Skip to content

Commit 9f829a3

Browse files
author
Vasil Chimev
authored
feat(android): add "Don't keep activities" functionality (#5)
* feat(android): add "Don't keep activities" abilities This allows you to turn on/off "Don't keep activities" setting in the Developer options for Android. * refactor(android-controller): setDontKeepActivities method * refactor(android-controller): getAlwaysFinishActivitiesGlobalSettingsValue method * refactor(android-controller): add executeAdbShellCommand method * refactor(android-controller): rebase on origin/master * refactor(android-controller): getTokenPrefix method
1 parent 0e2082f commit 9f829a3

File tree

2 files changed

+38
-15
lines changed

2 files changed

+38
-15
lines changed

lib/android-controller.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ export declare class AndroidController {
5757
private static sendKeyCommand;
5858
private static checkAndroid();
5959
private static executeAdbCommand(device, command);
60+
private static executeAdbShellCommand(device, command);
6061
private static getTokenPrefix(device);
62+
private static getAlwaysFinishActivitiesGlobalSettingValue(device);
63+
static setDontKeepActivities(value: boolean, device: IDevice): void;
6164
}
6265
export declare class AndroidDevice extends Device {
6366
constructor(name: string, apiLevel: any, type: DeviceType, token?: string, status?: Status, pid?: number);

lib/android-controller.ts

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export class AndroidController {
3636
}
3737

3838
public static getPhysicalDensity(device: IDevice) {
39-
return parseInt(AndroidController.executeAdbCommand(device, "shell wm density").split(":")[1]) * 0.01;
39+
return parseInt(AndroidController.executeAdbShellCommand(device, "wm density").split(":")[1]) * 0.01;
4040
}
4141

4242
public static getPixelsOffset(device: IDevice) {
@@ -147,7 +147,7 @@ export class AndroidController {
147147
}
148148

149149
public isAppRunning(device: IDevice, appId: string) {
150-
const result = AndroidController.executeAdbCommand(device, "shell ps");
150+
const result = AndroidController.executeAdbShellCommand(device, "ps");
151151
if (result.includes(appId)) {
152152
return true;
153153
} else {
@@ -157,12 +157,12 @@ export class AndroidController {
157157

158158
public static startApplication(device: IDevice, fullAppName: string) {
159159
const appId = AndroidController.installApp(device, fullAppName);
160-
let command = "shell monkey -p " + appId + " 1";
161-
Promise.resolve(AndroidController.executeAdbCommand(device, command));
160+
const commandToExecute = "monkey -p " + appId + " 1";
161+
Promise.resolve(AndroidController.executeAdbShellCommand(device, commandToExecute));
162162
}
163163

164164
public static getInstalledApps(device) {
165-
const list = AndroidController.executeAdbCommand(device, `shell pm list packages -3`).split("\n");
165+
const list = AndroidController.executeAdbShellCommand(device, `pm list packages -3`).split("\n");
166166
return list;
167167
}
168168

@@ -208,13 +208,13 @@ export class AndroidController {
208208
}
209209

210210
public static stopApp(device: IDevice, appId) {
211-
AndroidController.executeAdbCommand(device, `shell am force-stop ${appId}`);
211+
AndroidController.executeAdbShellCommand(device, `am force-stop ${appId}`);
212212
}
213213

214214
public static async getScreenshot(device: IDevice, dir, fileName) {
215215
fileName = fileName.endsWith(".pne") ? fileName : `${fileName}.png`;
216216
const pathToScreenshotPng = `/sdcard/${fileName}`;
217-
AndroidController.executeAdbCommand(device, `shell screencap ${pathToScreenshotPng}`);
217+
AndroidController.executeAdbShellCommand(device, `screencap ${pathToScreenshotPng}`);
218218
const fullFileName = resolve(dir, fileName);
219219
AndroidController.pullFile(device, pathToScreenshotPng, fullFileName);
220220
return fullFileName;
@@ -240,7 +240,6 @@ export class AndroidController {
240240
const devicePath = `/sdcard/${videoFileName}`;
241241
const prefix = AndroidController.getTokenPrefix(device);
242242
const videoRecoringProcess = spawn(AndroidController.ADB, ['-s', `${prefix}${device.token}`, 'shell', 'screenrecord', `${devicePath}`]);
243-
244243
return { pathToVideo: pathToVideo, devicePath: devicePath, videoRecoringProcess: videoRecoringProcess };
245244
}
246245

@@ -252,7 +251,7 @@ export class AndroidController {
252251
const destinationFolder = dirname(destinationFile);
253252
// Verify remotePath
254253
const remoteBasePath = remotePath.substring(0, remotePath.lastIndexOf("/"));
255-
const sdcardFiles = AndroidController.executeAdbCommand(device, " shell ls -la " + remoteBasePath);
254+
const sdcardFiles = AndroidController.executeAdbShellCommand(device, "ls -la " + remoteBasePath);
256255
if (sdcardFiles.includes("No such file or directory")) {
257256
const error = remoteBasePath + " does not exist.";
258257
console.log(error);
@@ -282,11 +281,11 @@ export class AndroidController {
282281

283282
public static pushFile(device: IDevice, fileName, deviceParh) {
284283

285-
let output = AndroidController.executeAdbCommand(device, "shell mount -o rw,remount -t rootfs /");
284+
let output = AndroidController.executeAdbShellCommand(device, "mount -o rw,remount -t rootfs /");
286285

287286
// Verify remotePath
288287
const remoteBasePath = deviceParh.substring(0, deviceParh.lastIndexOf("/"));
289-
const sdcardFiles = AndroidController.executeAdbCommand(device, "shell ls -la " + remoteBasePath);
288+
const sdcardFiles = AndroidController.executeAdbShellCommand(device, "ls -la " + remoteBasePath);
290289
if (sdcardFiles.includes("No such file or directory")) {
291290
const error = remoteBasePath + " does not exist.";
292291
console.log(error);
@@ -577,14 +576,35 @@ export class AndroidController {
577576

578577
private static executeAdbCommand(device: IDevice, command: string) {
579578
const prefix = AndroidController.getTokenPrefix(device);
580-
return executeCommand(`${AndroidController.ADB} -s ${prefix}${device.token} ${command}`);
579+
const commandToExecute = `${AndroidController.ADB} -s ${prefix}${device.token} ${command}`;
580+
const result = executeCommand(commandToExecute);
581+
return result;
582+
}
583+
584+
private static executeAdbShellCommand(device: IDevice, command: string) {
585+
const commandToExecute = `shell ${command}`;
586+
const result = AndroidController.executeAdbCommand(device, commandToExecute);
587+
return result;
581588
}
582589

583590
private static getTokenPrefix(device: IDevice) {
584-
if (device.type === DeviceType.EMULATOR && !device.token.startsWith("emulator")) {
585-
return "emulator-";
591+
const result = device.type === DeviceType.EMULATOR && !device.token.startsWith("emulator") ? "emulator-" : "";
592+
return result;
593+
}
594+
595+
private static getAlwaysFinishActivitiesGlobalSettingValue(device: IDevice): boolean {
596+
const commandToExecute = `settings get global always_finish_activities`;
597+
const result = AndroidController.executeAdbShellCommand(device, commandToExecute).trim() === "1";
598+
return result;
599+
}
600+
601+
public static setDontKeepActivities(value: boolean, device: IDevice) {
602+
const status = value ? 1 : 0;
603+
const commandToExecute = `service call activity 43 i32 ${status}`;
604+
AndroidController.executeAdbShellCommand(device, commandToExecute);
605+
if (AndroidController.getAlwaysFinishActivitiesGlobalSettingValue(device) !== value) {
606+
throw new Error(`Failed to set "Don't keep activities" to ${value}!`);
586607
}
587-
return "";
588608
}
589609
}
590610

0 commit comments

Comments
 (0)