Skip to content

Commit 0dcca5c

Browse files
authored
feat(focus-mvp-android-device) Grant overlay permission (#4020)
* feat(focus-mvp-android-device) Grant overlay permission * Update AppiumAdbWrapper so that grantOverlayPermission takes the service package name as a parameter. This allows us to specify the package name in one place only.
1 parent 0f7d1ed commit 0dcca5c

22 files changed

+345
-4
lines changed

src/electron/platform/android/adb-wrapper.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export interface AdbWrapper {
3030
setTcpForwarding(deviceId: string, localPort: number, devicePort: number): Promise<number>;
3131
removeTcpForwarding(deviceId: string, devicePort: number): Promise<void>;
3232
sendKeyEvent(deviceId: string, keyEventCode: KeyEventCode): Promise<void>;
33+
grantOverlayPermission: (deviceId: string, packageName: string) => Promise<void>;
3334
}
3435

3536
export interface AdbWrapperFactory {

src/electron/platform/android/appium-adb-wrapper.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,18 @@ export class AppiumAdbWrapper implements AdbWrapper {
8888
this.adb.setDeviceId(deviceId);
8989
await this.adb.shell(['input', 'keyevent', keyEventCode]);
9090
};
91+
92+
public grantOverlayPermission = async (
93+
deviceId: string,
94+
packageName: string,
95+
): Promise<void> => {
96+
this.adb.setDeviceId(deviceId);
97+
await this.adb.shell(['cmd', 'appops', 'reset', packageName]);
98+
await this.adb.shell([
99+
'pm',
100+
'grant',
101+
packageName,
102+
'android.permission.SYSTEM_ALERT_WINDOW',
103+
]);
104+
};
91105
}

src/electron/platform/android/setup/android-service-configurator.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export interface ServiceConfigurator {
1515
hasRequiredServiceVersion(): Promise<boolean>;
1616
installRequiredServiceVersion(): Promise<void>;
1717
hasRequiredPermissions(): Promise<boolean>;
18+
grantOverlayPermission(): Promise<void>;
1819
setupTcpForwarding(): Promise<number>;
1920
removeTcpForwarding(hostPort: number): Promise<void>;
2021
}
@@ -83,6 +84,13 @@ export class AndroidServiceConfigurator implements ServiceConfigurator {
8384
return screenshotGranted;
8485
};
8586

87+
public grantOverlayPermission = async (): Promise<void> => {
88+
return await this.adbWrapper.grantOverlayPermission(
89+
this.selectedDeviceId,
90+
this.servicePackageName,
91+
);
92+
};
93+
8694
public setupTcpForwarding = async (): Promise<number> => {
8795
const hostPort = await this.portFinder({
8896
port: servicePortNumber,

src/electron/platform/android/setup/android-setup-deps.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export type AndroidSetupDeps = {
1212
hasExpectedServiceVersion: () => Promise<boolean>;
1313
installService: () => Promise<boolean>;
1414
hasExpectedPermissions: () => Promise<boolean>;
15+
grantOverlayPermission: () => Promise<void>;
1516
setupTcpForwarding: () => Promise<number>;
1617
removeTcpForwarding: (hostPort: number) => Promise<void>;
1718
fetchDeviceConfig: (port: number) => Promise<DeviceConfig>;

src/electron/platform/android/setup/android-setup-step-id.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export type AndroidSetupStepId =
1313
| 'prompt-install-failed'
1414
| 'detect-permissions'
1515
| 'prompt-grant-permissions'
16+
| 'grant-overlay-permission'
1617
| 'configuring-port-forwarding'
1718
| 'prompt-configuring-port-forwarding-failed'
1819
| 'prompt-connected-start-testing';

src/electron/platform/android/setup/android-setup-steps-configs.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { configuringPortForwarding } from 'electron/platform/android/setup/steps
99
import { detectDevices } from 'electron/platform/android/setup/steps/detect-devices';
1010
import { detectPermissions } from 'electron/platform/android/setup/steps/detect-permissions';
1111
import { detectService } from 'electron/platform/android/setup/steps/detect-service';
12+
import { grantOverlayPermission } from 'electron/platform/android/setup/steps/grant-overlay-permission';
1213
import { installingService } from 'electron/platform/android/setup/steps/installing-service';
1314
import { promptChooseDevice } from 'electron/platform/android/setup/steps/prompt-choose-device';
1415
import { promptConfiguringPortForwardingFailed } from 'electron/platform/android/setup/steps/prompt-configuring-port-forwarding-failed';
@@ -51,6 +52,7 @@ export const allAndroidSetupStepConfigs: AndroidSetupStepConfigs = {
5152
'prompt-install-failed': promptInstallService,
5253
'detect-permissions': detectPermissions,
5354
'prompt-grant-permissions': promptGrantPermissions,
55+
'grant-overlay-permission': grantOverlayPermission,
5456
'configuring-port-forwarding': configuringPortForwarding,
5557
'prompt-configuring-port-forwarding-failed': promptConfiguringPortForwardingFailed,
5658
'prompt-connected-start-testing': promptConnectedStartTesting,

src/electron/platform/android/setup/live-android-setup-deps.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ export class LiveAndroidSetupDeps implements AndroidSetupDeps {
7979
return false;
8080
};
8181

82+
public grantOverlayPermission = async (): Promise<void> => {
83+
try {
84+
return await this.serviceConfig.grantOverlayPermission();
85+
} catch (error) {
86+
this.logger.log(error);
87+
}
88+
};
89+
8290
public setupTcpForwarding = async (): Promise<number> => {
8391
return await this.serviceConfig.setupTcpForwarding();
8492
};

src/electron/platform/android/setup/port-cleaning-service-configurator.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ export class PortCleaningServiceConfigurator implements ServiceConfigurator {
3131
return this.innerObject.hasRequiredPermissions();
3232
};
3333

34+
public grantOverlayPermission = (): Promise<void> => {
35+
return this.innerObject.grantOverlayPermission();
36+
};
37+
3438
public setupTcpForwarding = async (): Promise<number> => {
3539
const assignedPort = await this.innerObject.setupTcpForwarding();
3640
this.portCleaner.addPort(assignedPort);

src/electron/platform/android/setup/steps/detect-permissions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ export const detectPermissions: AndroidSetupStepConfig = (stepTransition, deps)
77
actions: {},
88
onEnter: async () => {
99
const detected = await deps.hasExpectedPermissions();
10-
stepTransition(detected ? 'configuring-port-forwarding' : 'prompt-grant-permissions');
10+
stepTransition(detected ? 'grant-overlay-permission' : 'prompt-grant-permissions');
1111
},
1212
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
import { AndroidSetupStepConfig } from 'electron/platform/android/setup/android-setup-steps-configs';
5+
6+
export const grantOverlayPermission: AndroidSetupStepConfig = (stepTransition, deps) => ({
7+
actions: {},
8+
onEnter: async () => {
9+
await deps.grantOverlayPermission();
10+
stepTransition('configuring-port-forwarding');
11+
},
12+
});

0 commit comments

Comments
 (0)