appium-adb 14.3.1 → 14.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/build/lib/adb.d.ts +9 -9
- package/build/lib/adb.d.ts.map +1 -1
- package/build/lib/adb.js +61 -61
- package/build/lib/adb.js.map +1 -1
- package/build/lib/helpers.d.ts +2 -2
- package/build/lib/helpers.d.ts.map +1 -1
- package/build/lib/helpers.js +5 -5
- package/build/lib/helpers.js.map +1 -1
- package/build/lib/index.d.ts +8 -0
- package/build/lib/index.d.ts.map +1 -0
- package/build/{index.js → lib/index.js} +4 -4
- package/build/lib/index.js.map +1 -0
- package/build/lib/logcat.d.ts.map +1 -1
- package/build/lib/logcat.js +1 -1
- package/build/lib/logcat.js.map +1 -1
- package/build/lib/tools/aab-utils.d.ts +2 -2
- package/build/lib/tools/aab-utils.d.ts.map +1 -1
- package/build/lib/tools/aab-utils.js +10 -10
- package/build/lib/tools/aab-utils.js.map +1 -1
- package/build/lib/tools/android-manifest.d.ts +2 -2
- package/build/lib/tools/android-manifest.d.ts.map +1 -1
- package/build/lib/tools/android-manifest.js +27 -27
- package/build/lib/tools/android-manifest.js.map +1 -1
- package/build/lib/tools/apk-signing.d.ts +2 -2
- package/build/lib/tools/apk-signing.d.ts.map +1 -1
- package/build/lib/tools/apk-signing.js +34 -34
- package/build/lib/tools/apk-signing.js.map +1 -1
- package/build/lib/tools/apk-utils.d.ts +2 -2
- package/build/lib/tools/apk-utils.d.ts.map +1 -1
- package/build/lib/tools/apk-utils.js +76 -76
- package/build/lib/tools/apk-utils.js.map +1 -1
- package/build/lib/tools/apks-utils.d.ts +2 -2
- package/build/lib/tools/apks-utils.d.ts.map +1 -1
- package/build/lib/tools/apks-utils.js +58 -58
- package/build/lib/tools/apks-utils.js.map +1 -1
- package/build/lib/tools/app-commands.d.ts +13 -13
- package/build/lib/tools/app-commands.d.ts.map +1 -1
- package/build/lib/tools/app-commands.js +36 -38
- package/build/lib/tools/app-commands.js.map +1 -1
- package/build/lib/tools/device-settings.d.ts +2 -2
- package/build/lib/tools/device-settings.d.ts.map +1 -1
- package/build/lib/tools/device-settings.js +27 -27
- package/build/lib/tools/device-settings.js.map +1 -1
- package/build/lib/tools/emulator-commands.d.ts +2 -2
- package/build/lib/tools/emulator-commands.d.ts.map +1 -1
- package/build/lib/tools/emulator-commands.js +47 -47
- package/build/lib/tools/emulator-commands.js.map +1 -1
- package/build/lib/tools/fs-commands.d.ts +1 -1
- package/build/lib/tools/fs-commands.d.ts.map +1 -1
- package/build/lib/tools/fs-commands.js +3 -3
- package/build/lib/tools/fs-commands.js.map +1 -1
- package/build/lib/tools/general-commands.d.ts +2 -2
- package/build/lib/tools/general-commands.d.ts.map +1 -1
- package/build/lib/tools/general-commands.js +7 -7
- package/build/lib/tools/general-commands.js.map +1 -1
- package/build/lib/tools/keyboard-commands.d.ts +2 -2
- package/build/lib/tools/keyboard-commands.d.ts.map +1 -1
- package/build/lib/tools/keyboard-commands.js +3 -3
- package/build/lib/tools/keyboard-commands.js.map +1 -1
- package/build/lib/tools/lockmgmt.d.ts +1 -1
- package/build/lib/tools/lockmgmt.d.ts.map +1 -1
- package/build/lib/tools/lockmgmt.js +78 -78
- package/build/lib/tools/lockmgmt.js.map +1 -1
- package/build/lib/tools/logcat-commands.d.ts +2 -2
- package/build/lib/tools/logcat-commands.d.ts.map +1 -1
- package/build/lib/tools/network-commands.d.ts +2 -2
- package/build/lib/tools/network-commands.d.ts.map +1 -1
- package/build/lib/tools/network-commands.js +10 -10
- package/build/lib/tools/network-commands.js.map +1 -1
- package/build/lib/tools/process-commands.d.ts +1 -1
- package/build/lib/tools/process-commands.d.ts.map +1 -1
- package/build/lib/tools/process-commands.js +10 -10
- package/build/lib/tools/process-commands.js.map +1 -1
- package/build/lib/tools/system-calls.d.ts +8 -8
- package/build/lib/tools/system-calls.d.ts.map +1 -1
- package/build/lib/tools/system-calls.js +81 -83
- package/build/lib/tools/system-calls.js.map +1 -1
- package/lib/adb.ts +69 -69
- package/lib/helpers.ts +3 -3
- package/lib/index.ts +8 -0
- package/lib/logcat.ts +4 -6
- package/lib/tools/aab-utils.ts +4 -4
- package/lib/tools/android-manifest.ts +4 -4
- package/lib/tools/apk-signing.ts +4 -4
- package/lib/tools/apk-utils.ts +41 -41
- package/lib/tools/apks-utils.ts +53 -53
- package/lib/tools/app-commands.ts +15 -19
- package/lib/tools/device-settings.ts +16 -16
- package/lib/tools/emulator-commands.ts +53 -53
- package/lib/tools/fs-commands.ts +5 -5
- package/lib/tools/general-commands.ts +3 -3
- package/lib/tools/keyboard-commands.ts +3 -3
- package/lib/tools/lockmgmt.ts +84 -84
- package/lib/tools/logcat-commands.ts +2 -2
- package/lib/tools/network-commands.ts +3 -3
- package/lib/tools/process-commands.ts +2 -2
- package/lib/tools/system-calls.ts +13 -17
- package/package.json +4 -6
- package/build/index.d.ts +0 -8
- package/build/index.d.ts.map +0 -1
- package/build/index.js.map +0 -1
- package/index.ts +0 -8
|
@@ -74,10 +74,10 @@ exports.isMitmCertificateInstalled = isMitmCertificateInstalled;
|
|
|
74
74
|
exports.shellChunks = shellChunks;
|
|
75
75
|
exports.toAvdLocaleArgs = toAvdLocaleArgs;
|
|
76
76
|
const node_path_1 = __importDefault(require("node:path"));
|
|
77
|
-
const
|
|
77
|
+
const logger_1 = require("../logger");
|
|
78
78
|
const bluebird_1 = __importDefault(require("bluebird"));
|
|
79
79
|
const support_1 = require("@appium/support");
|
|
80
|
-
const
|
|
80
|
+
const helpers_1 = require("../helpers");
|
|
81
81
|
const teen_process_1 = require("teen_process");
|
|
82
82
|
const asyncbox_1 = require("asyncbox");
|
|
83
83
|
const lodash_1 = __importDefault(require("lodash"));
|
|
@@ -103,7 +103,15 @@ const SDK_BINARY_ROOTS = [
|
|
|
103
103
|
const MIN_DELAY_ADB_API_LEVEL = 28;
|
|
104
104
|
const REQUIRED_SERVICES = ['activity', 'package', 'window'];
|
|
105
105
|
const MAX_SHELL_BUFFER_LENGTH = 1000;
|
|
106
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Retrieve full path to the given binary.
|
|
108
|
+
*
|
|
109
|
+
* @param binaryName - The name of the binary
|
|
110
|
+
* @returns The full path to the binary
|
|
111
|
+
*/
|
|
112
|
+
async function getSdkBinaryPath(binaryName) {
|
|
113
|
+
return await this.getBinaryFromSdkRoot(binaryName);
|
|
114
|
+
}
|
|
107
115
|
/**
|
|
108
116
|
* Retrieve full binary name for the current operating system.
|
|
109
117
|
*
|
|
@@ -147,16 +155,6 @@ async function getOpenSslForOs() {
|
|
|
147
155
|
throw new Error('The openssl tool must be installed on the system and available on the path');
|
|
148
156
|
}
|
|
149
157
|
}
|
|
150
|
-
// Public methods
|
|
151
|
-
/**
|
|
152
|
-
* Retrieve full path to the given binary.
|
|
153
|
-
*
|
|
154
|
-
* @param binaryName - The name of the binary
|
|
155
|
-
* @returns The full path to the binary
|
|
156
|
-
*/
|
|
157
|
-
async function getSdkBinaryPath(binaryName) {
|
|
158
|
-
return await this.getBinaryFromSdkRoot(binaryName);
|
|
159
|
-
}
|
|
160
158
|
exports.getBinaryNameForOS = lodash_1.default.memoize(_getBinaryNameForOS);
|
|
161
159
|
/**
|
|
162
160
|
* Retrieve full path to the given binary and caches it into `binaries`
|
|
@@ -180,10 +178,10 @@ async function getBinaryFromSdkRoot(binaryName) {
|
|
|
180
178
|
if (this.buildToolsVersion) {
|
|
181
179
|
buildToolsDirs = buildToolsDirs.filter((x) => node_path_1.default.basename(x) === this.buildToolsVersion);
|
|
182
180
|
if (lodash_1.default.isEmpty(buildToolsDirs)) {
|
|
183
|
-
|
|
181
|
+
logger_1.log.info(`Found no build tools whose version matches to '${this.buildToolsVersion}'`);
|
|
184
182
|
}
|
|
185
183
|
else {
|
|
186
|
-
|
|
184
|
+
logger_1.log.info(`Using build tools at '${buildToolsDirs}'`);
|
|
187
185
|
}
|
|
188
186
|
}
|
|
189
187
|
binaryLocs.push(...lodash_1.default.flatten(buildToolsDirs.map((dir) => [
|
|
@@ -202,7 +200,7 @@ async function getBinaryFromSdkRoot(binaryName) {
|
|
|
202
200
|
`Do you have Android Build Tools ${this.buildToolsVersion ? `v ${this.buildToolsVersion} ` : ''}` +
|
|
203
201
|
`installed at '${this.sdkRoot}'?`);
|
|
204
202
|
}
|
|
205
|
-
|
|
203
|
+
logger_1.log.info(`Using '${fullBinaryName}' from '${binaryLoc}'`);
|
|
206
204
|
if (!this.binaries) {
|
|
207
205
|
this.binaries = {};
|
|
208
206
|
}
|
|
@@ -219,7 +217,7 @@ async function getBinaryFromSdkRoot(binaryName) {
|
|
|
219
217
|
*/
|
|
220
218
|
async function getAndroidBinaryPath(binaryName) {
|
|
221
219
|
const fullBinaryName = (0, exports.getBinaryNameForOS)(binaryName);
|
|
222
|
-
const sdkRoot = (0,
|
|
220
|
+
const sdkRoot = (0, helpers_1.getSdkRootFromEnv)();
|
|
223
221
|
const binaryLocs = getSdkBinaryLocationCandidates(sdkRoot ?? '', fullBinaryName);
|
|
224
222
|
for (const loc of binaryLocs) {
|
|
225
223
|
if (await support_1.fs.exists(loc)) {
|
|
@@ -243,7 +241,7 @@ async function getBinaryFromPath(binaryName) {
|
|
|
243
241
|
const fullBinaryName = this.getBinaryNameForOS(binaryName);
|
|
244
242
|
try {
|
|
245
243
|
const binaryLoc = await support_1.fs.which(fullBinaryName);
|
|
246
|
-
|
|
244
|
+
logger_1.log.info(`Using '${fullBinaryName}' from '${binaryLoc}'`);
|
|
247
245
|
if (!this.binaries) {
|
|
248
246
|
this.binaries = {};
|
|
249
247
|
}
|
|
@@ -263,7 +261,7 @@ async function getBinaryFromPath(binaryName) {
|
|
|
263
261
|
* @throws {Error} If adb devices command fails or returns unexpected output
|
|
264
262
|
*/
|
|
265
263
|
async function getConnectedDevices(opts = {}) {
|
|
266
|
-
|
|
264
|
+
logger_1.log.debug('Getting connected devices');
|
|
267
265
|
const args = [...this.executable.defaultArgs, 'devices'];
|
|
268
266
|
if (opts.verbose) {
|
|
269
267
|
args.push('-l');
|
|
@@ -310,10 +308,10 @@ async function getConnectedDevices(opts = {}) {
|
|
|
310
308
|
return device;
|
|
311
309
|
});
|
|
312
310
|
if (lodash_1.default.isEmpty(devices)) {
|
|
313
|
-
|
|
311
|
+
logger_1.log.debug('No connected devices have been detected');
|
|
314
312
|
}
|
|
315
313
|
else {
|
|
316
|
-
|
|
314
|
+
logger_1.log.debug(`Connected devices: ${JSON.stringify(devices)}`);
|
|
317
315
|
}
|
|
318
316
|
return devices;
|
|
319
317
|
}
|
|
@@ -325,7 +323,7 @@ async function getConnectedDevices(opts = {}) {
|
|
|
325
323
|
* @throws {Error} If no devices are found within the timeout period
|
|
326
324
|
*/
|
|
327
325
|
async function getDevicesWithRetry(timeoutMs = 20000) {
|
|
328
|
-
|
|
326
|
+
logger_1.log.debug('Trying to find connected Android devices');
|
|
329
327
|
try {
|
|
330
328
|
let devices = [];
|
|
331
329
|
await (0, asyncbox_1.waitForCondition)(async () => {
|
|
@@ -334,12 +332,12 @@ async function getDevicesWithRetry(timeoutMs = 20000) {
|
|
|
334
332
|
if (devices.length) {
|
|
335
333
|
return true;
|
|
336
334
|
}
|
|
337
|
-
|
|
335
|
+
logger_1.log.debug('Could not find online devices');
|
|
338
336
|
}
|
|
339
337
|
catch (err) {
|
|
340
338
|
const error = err;
|
|
341
|
-
|
|
342
|
-
|
|
339
|
+
logger_1.log.debug(error.stack);
|
|
340
|
+
logger_1.log.warn(`Got an unexpected error while fetching connected devices list: ${error.message}`);
|
|
343
341
|
}
|
|
344
342
|
try {
|
|
345
343
|
await this.reconnect();
|
|
@@ -371,7 +369,7 @@ async function getDevicesWithRetry(timeoutMs = 20000) {
|
|
|
371
369
|
* @throws {Error} If reconnect command fails
|
|
372
370
|
*/
|
|
373
371
|
async function reconnect(target = 'offline') {
|
|
374
|
-
|
|
372
|
+
logger_1.log.debug(`Reconnecting adb (target ${target})`);
|
|
375
373
|
const args = ['reconnect'];
|
|
376
374
|
if (target) {
|
|
377
375
|
args.push(target);
|
|
@@ -389,23 +387,23 @@ async function reconnect(target = 'offline') {
|
|
|
389
387
|
*/
|
|
390
388
|
async function restartAdb() {
|
|
391
389
|
if (this.suppressKillServer) {
|
|
392
|
-
|
|
390
|
+
logger_1.log.debug(`Not restarting abd since 'suppressKillServer' is on`);
|
|
393
391
|
return;
|
|
394
392
|
}
|
|
395
|
-
|
|
393
|
+
logger_1.log.debug('Restarting adb');
|
|
396
394
|
try {
|
|
397
395
|
await this.killServer();
|
|
398
396
|
await this.adbExec(['start-server']);
|
|
399
397
|
}
|
|
400
398
|
catch {
|
|
401
|
-
|
|
399
|
+
logger_1.log.error(`Error killing ADB server, going to see if it's online anyway`);
|
|
402
400
|
}
|
|
403
401
|
}
|
|
404
402
|
/**
|
|
405
403
|
* Kill adb server.
|
|
406
404
|
*/
|
|
407
405
|
async function killServer() {
|
|
408
|
-
|
|
406
|
+
logger_1.log.debug(`Killing adb server on port '${this.adbPort}'`);
|
|
409
407
|
await this.adbExec(['kill-server'], {
|
|
410
408
|
exclusive: true,
|
|
411
409
|
});
|
|
@@ -421,17 +419,17 @@ exports.resetTelnetAuthToken = lodash_1.default.memoize(async function resetTeln
|
|
|
421
419
|
//
|
|
422
420
|
const homeFolderPath = process.env[process.platform === 'win32' ? 'USERPROFILE' : 'HOME'];
|
|
423
421
|
if (!homeFolderPath) {
|
|
424
|
-
|
|
422
|
+
logger_1.log.warn(`Cannot find the path to user home folder. Ignoring resetting of emulator's telnet authentication token`);
|
|
425
423
|
return false;
|
|
426
424
|
}
|
|
427
425
|
const dstPath = node_path_1.default.resolve(homeFolderPath, '.emulator_console_auth_token');
|
|
428
|
-
|
|
426
|
+
logger_1.log.debug(`Overriding ${dstPath} with an empty string to avoid telnet authentication for emulator commands`);
|
|
429
427
|
try {
|
|
430
428
|
await support_1.fs.writeFile(dstPath, '');
|
|
431
429
|
}
|
|
432
430
|
catch (e) {
|
|
433
431
|
const error = e;
|
|
434
|
-
|
|
432
|
+
logger_1.log.warn(`Error ${error.message} while resetting the content of ${dstPath}. Ignoring resetting of emulator's telnet authentication token`);
|
|
435
433
|
return false;
|
|
436
434
|
}
|
|
437
435
|
return true;
|
|
@@ -466,7 +464,7 @@ async function adbExec(cmd, opts) {
|
|
|
466
464
|
}
|
|
467
465
|
const optsCopy = lodash_1.default.cloneDeep(opts ?? {});
|
|
468
466
|
// setting default timeout for each command to prevent infinite wait.
|
|
469
|
-
optsCopy.timeout = optsCopy.timeout || this.adbExecTimeout ||
|
|
467
|
+
optsCopy.timeout = optsCopy.timeout || this.adbExecTimeout || helpers_1.DEFAULT_ADB_EXEC_TIMEOUT;
|
|
470
468
|
optsCopy.timeoutCapName = optsCopy.timeoutCapName || 'adbExecTimeout'; // For error message
|
|
471
469
|
const { outputFormat = this.EXEC_OUTPUT_FORMAT.STDOUT } = optsCopy;
|
|
472
470
|
cmd = lodash_1.default.isArray(cmd) ? cmd : [cmd];
|
|
@@ -474,7 +472,7 @@ async function adbExec(cmd, opts) {
|
|
|
474
472
|
const execFunc = async () => {
|
|
475
473
|
try {
|
|
476
474
|
const args = [...this.executable.defaultArgs, ...cmd];
|
|
477
|
-
|
|
475
|
+
logger_1.log.debug(`Running '${this.executable.path} ` +
|
|
478
476
|
(args.find((arg) => /\s+/.test(arg)) ? support_1.util.quote(args) : args.join(' ')) +
|
|
479
477
|
`'`);
|
|
480
478
|
const { stdout: rawStdout, stderr } = (await (0, teen_process_1.exec)(this.executable.path, args, optsCopy));
|
|
@@ -487,7 +485,7 @@ async function adbExec(cmd, opts) {
|
|
|
487
485
|
const error = e;
|
|
488
486
|
const errText = `${error.message}, ${error.stdout}, ${error.stderr}`;
|
|
489
487
|
if (ADB_RETRY_ERROR_PATTERNS.some((p) => p.test(errText))) {
|
|
490
|
-
|
|
488
|
+
logger_1.log.info(`Error sending command, reconnecting device and retrying: ${cmd}`);
|
|
491
489
|
await this.getDevicesWithRetry();
|
|
492
490
|
// try again one time
|
|
493
491
|
if (!adbRetried) {
|
|
@@ -513,12 +511,12 @@ async function adbExec(cmd, opts) {
|
|
|
513
511
|
}
|
|
514
512
|
};
|
|
515
513
|
if (isExecLocked) {
|
|
516
|
-
|
|
514
|
+
logger_1.log.debug('Waiting until the other exclusive ADB command is completed');
|
|
517
515
|
await (0, asyncbox_1.waitForCondition)(() => !isExecLocked, {
|
|
518
516
|
waitMs: Number.MAX_SAFE_INTEGER,
|
|
519
517
|
intervalMs: 10,
|
|
520
518
|
});
|
|
521
|
-
|
|
519
|
+
logger_1.log.debug('Continuing with the current ADB command');
|
|
522
520
|
}
|
|
523
521
|
if (optsCopy.exclusive) {
|
|
524
522
|
isExecLocked = true;
|
|
@@ -545,9 +543,9 @@ async function shell(cmd, opts) {
|
|
|
545
543
|
const cmdArr = lodash_1.default.isArray(cmd) ? cmd : [cmd];
|
|
546
544
|
const fullCmd = ['shell'];
|
|
547
545
|
if (privileged) {
|
|
548
|
-
|
|
546
|
+
logger_1.log.info(`'adb shell ${support_1.util.quote(cmdArr)}' requires root access`);
|
|
549
547
|
if (await this.isRoot()) {
|
|
550
|
-
|
|
548
|
+
logger_1.log.info('The device already had root access');
|
|
551
549
|
fullCmd.push(...cmdArr);
|
|
552
550
|
}
|
|
553
551
|
else {
|
|
@@ -568,7 +566,7 @@ async function shell(cmd, opts) {
|
|
|
568
566
|
function createSubProcess(args = []) {
|
|
569
567
|
// add the default arguments
|
|
570
568
|
const finalArgs = [...this.executable.defaultArgs, ...args];
|
|
571
|
-
|
|
569
|
+
logger_1.log.debug(`Creating ADB subprocess with args: ${JSON.stringify(finalArgs)}`);
|
|
572
570
|
return new teen_process_1.SubProcess(this.getAdbPath(), finalArgs);
|
|
573
571
|
}
|
|
574
572
|
/**
|
|
@@ -588,7 +586,7 @@ function getAdbServerPort() {
|
|
|
588
586
|
* @throws {Error} If no devices are connected or emulator port cannot be found
|
|
589
587
|
*/
|
|
590
588
|
async function getEmulatorPort() {
|
|
591
|
-
|
|
589
|
+
logger_1.log.debug('Getting running emulator port');
|
|
592
590
|
if (!lodash_1.default.isNil(this.emulatorPort)) {
|
|
593
591
|
return this.emulatorPort;
|
|
594
592
|
}
|
|
@@ -626,7 +624,7 @@ function getPortFromEmulatorString(emStr) {
|
|
|
626
624
|
* @throws {Error} If error occurs while getting emulators
|
|
627
625
|
*/
|
|
628
626
|
async function getConnectedEmulators(opts = {}) {
|
|
629
|
-
|
|
627
|
+
logger_1.log.debug('Getting connected emulators');
|
|
630
628
|
try {
|
|
631
629
|
const devices = await this.getConnectedDevices(opts);
|
|
632
630
|
const emulators = [];
|
|
@@ -637,7 +635,7 @@ async function getConnectedEmulators(opts = {}) {
|
|
|
637
635
|
emulators.push(device);
|
|
638
636
|
}
|
|
639
637
|
}
|
|
640
|
-
|
|
638
|
+
logger_1.log.debug(`${support_1.util.pluralize('emulator', emulators.length, true)} connected`);
|
|
641
639
|
return emulators;
|
|
642
640
|
}
|
|
643
641
|
catch (e) {
|
|
@@ -659,7 +657,7 @@ function setEmulatorPort(emPort) {
|
|
|
659
657
|
* @param deviceId - The device identifier
|
|
660
658
|
*/
|
|
661
659
|
function setDeviceId(deviceId) {
|
|
662
|
-
|
|
660
|
+
logger_1.log.debug(`Setting device id to ${deviceId}`);
|
|
663
661
|
this.curDeviceId = deviceId;
|
|
664
662
|
const argsHasDevice = this.executable.defaultArgs.indexOf('-s');
|
|
665
663
|
if (argsHasDevice !== -1) {
|
|
@@ -692,7 +690,7 @@ function setDevice(deviceObj) {
|
|
|
692
690
|
* @throws {Error} If error occurs while getting AVD
|
|
693
691
|
*/
|
|
694
692
|
async function getRunningAVD(avdName) {
|
|
695
|
-
|
|
693
|
+
logger_1.log.debug(`Trying to find '${avdName}' emulator`);
|
|
696
694
|
try {
|
|
697
695
|
const emulators = await this.getConnectedEmulators();
|
|
698
696
|
for (const emulator of emulators) {
|
|
@@ -705,12 +703,12 @@ async function getRunningAVD(avdName) {
|
|
|
705
703
|
connTimeout: 1000,
|
|
706
704
|
});
|
|
707
705
|
if (lodash_1.default.toLower(avdName) === lodash_1.default.toLower(runningAVDName.trim())) {
|
|
708
|
-
|
|
706
|
+
logger_1.log.debug(`Found emulator '${avdName}' on port ${emulator.port}`);
|
|
709
707
|
this.setDeviceId(emulator.udid);
|
|
710
708
|
return emulator;
|
|
711
709
|
}
|
|
712
710
|
}
|
|
713
|
-
|
|
711
|
+
logger_1.log.debug(`Emulator '${avdName}' not running`);
|
|
714
712
|
return null;
|
|
715
713
|
}
|
|
716
714
|
catch (e) {
|
|
@@ -734,7 +732,7 @@ async function getRunningAVDWithRetry(avdName, timeoutMs = 20000) {
|
|
|
734
732
|
}
|
|
735
733
|
catch (e) {
|
|
736
734
|
const error = e;
|
|
737
|
-
|
|
735
|
+
logger_1.log.debug(error.message);
|
|
738
736
|
return false;
|
|
739
737
|
}
|
|
740
738
|
}, {
|
|
@@ -782,23 +780,23 @@ async function killAllEmulators() {
|
|
|
782
780
|
*/
|
|
783
781
|
async function killEmulator(avdName = null, timeout = 60000) {
|
|
784
782
|
if (support_1.util.hasValue(avdName)) {
|
|
785
|
-
|
|
783
|
+
logger_1.log.debug(`Killing avd '${avdName}'`);
|
|
786
784
|
const device = await this.getRunningAVD(avdName);
|
|
787
785
|
if (!device) {
|
|
788
|
-
|
|
786
|
+
logger_1.log.info(`No avd with name '${avdName}' running. Skipping kill step.`);
|
|
789
787
|
return false;
|
|
790
788
|
}
|
|
791
789
|
}
|
|
792
790
|
else {
|
|
793
791
|
// killing the current avd
|
|
794
|
-
|
|
792
|
+
logger_1.log.debug(`Killing avd with id '${this.curDeviceId}'`);
|
|
795
793
|
if (!(await this.isEmulatorConnected())) {
|
|
796
|
-
|
|
794
|
+
logger_1.log.debug(`Emulator with id '${this.curDeviceId}' not connected. Skipping kill step`);
|
|
797
795
|
return false;
|
|
798
796
|
}
|
|
799
797
|
}
|
|
800
798
|
await this.adbExec(['emu', 'kill']);
|
|
801
|
-
|
|
799
|
+
logger_1.log.debug(`Waiting up to ${timeout}ms until the emulator '${avdName ? avdName : this.curDeviceId}' is killed`);
|
|
802
800
|
try {
|
|
803
801
|
await (0, asyncbox_1.waitForCondition)(async () => {
|
|
804
802
|
try {
|
|
@@ -817,7 +815,7 @@ async function killEmulator(avdName = null, timeout = 60000) {
|
|
|
817
815
|
catch {
|
|
818
816
|
throw new Error(`The emulator '${avdName ? avdName : this.curDeviceId}' is still running after being killed ${timeout}ms ago`);
|
|
819
817
|
}
|
|
820
|
-
|
|
818
|
+
logger_1.log.info(`Successfully killed the '${avdName ? avdName : this.curDeviceId}' emulator`);
|
|
821
819
|
return true;
|
|
822
820
|
}
|
|
823
821
|
/**
|
|
@@ -830,7 +828,7 @@ async function killEmulator(avdName = null, timeout = 60000) {
|
|
|
830
828
|
*/
|
|
831
829
|
async function launchAVD(avdName, opts = {}) {
|
|
832
830
|
const { args = [], env = {}, language, country, launchTimeout = 60000, readyTimeout = 60000, retryTimes = 1, } = opts;
|
|
833
|
-
|
|
831
|
+
logger_1.log.debug(`Launching Emulator with AVD ${avdName}, launchTimeout ` +
|
|
834
832
|
`${launchTimeout}ms and readyTimeout ${readyTimeout}ms`);
|
|
835
833
|
const emulatorBinaryPath = await this.getSdkBinaryPath('emulator');
|
|
836
834
|
let processedAvdName = avdName;
|
|
@@ -859,30 +857,30 @@ async function launchAVD(avdName, opts = {}) {
|
|
|
859
857
|
}
|
|
860
858
|
catch (e) {
|
|
861
859
|
const error = e;
|
|
862
|
-
|
|
860
|
+
logger_1.log.info(`The -delay-adb emulator startup detection feature will not be enabled. ` +
|
|
863
861
|
`Original error: ${error.message}`);
|
|
864
862
|
}
|
|
865
863
|
}
|
|
866
864
|
}
|
|
867
865
|
else {
|
|
868
|
-
|
|
866
|
+
logger_1.log.info('The -delay-adb emulator startup detection feature has been explicitly disabled');
|
|
869
867
|
}
|
|
870
868
|
if (!lodash_1.default.isEmpty(args)) {
|
|
871
869
|
launchArgs.push(...(lodash_1.default.isArray(args) ? args : support_1.util.shellParse(`${args}`)));
|
|
872
870
|
}
|
|
873
|
-
|
|
871
|
+
logger_1.log.debug(`Running '${emulatorBinaryPath}' with args: ${support_1.util.quote(launchArgs)}`);
|
|
874
872
|
if (!lodash_1.default.isEmpty(env)) {
|
|
875
|
-
|
|
873
|
+
logger_1.log.debug(`Customized emulator environment: ${JSON.stringify(env)}`);
|
|
876
874
|
}
|
|
877
875
|
const proc = new teen_process_1.SubProcess(emulatorBinaryPath, launchArgs, {
|
|
878
876
|
env: { ...process.env, ...env },
|
|
879
877
|
});
|
|
880
878
|
await proc.start(0);
|
|
881
879
|
for (const streamName of ['stderr', 'stdout']) {
|
|
882
|
-
proc.on(`line-${streamName}`, (line) =>
|
|
880
|
+
proc.on(`line-${streamName}`, (line) => logger_1.log.debug(`[AVD OUTPUT] ${line}`));
|
|
883
881
|
}
|
|
884
882
|
proc.on('die', (code, signal) => {
|
|
885
|
-
|
|
883
|
+
logger_1.log.warn(`Emulator avd ${processedAvdName} exited with code ${code}${signal ? `, signal ${signal}` : ''}`);
|
|
886
884
|
});
|
|
887
885
|
await (0, asyncbox_1.retry)(retryTimes, async () => await this.getRunningAVDWithRetry(processedAvdName, launchTimeout));
|
|
888
886
|
// At this point we have deviceId already assigned
|
|
@@ -937,7 +935,7 @@ exports.getVersion = lodash_1.default.memoize(async function getVersion() {
|
|
|
937
935
|
* @throws {Error} If emulator is not ready within the timeout period
|
|
938
936
|
*/
|
|
939
937
|
async function waitForEmulatorReady(timeoutMs = 20000) {
|
|
940
|
-
|
|
938
|
+
logger_1.log.debug(`Waiting up to ${timeoutMs}ms for the emulator to be ready`);
|
|
941
939
|
const requiredServicesRe = REQUIRED_SERVICES.map((name) => new RegExp(`\\b${name}:`));
|
|
942
940
|
let services;
|
|
943
941
|
const timer = new support_1.timing.Timer().start();
|
|
@@ -949,7 +947,7 @@ async function waitForEmulatorReady(timeoutMs = 20000) {
|
|
|
949
947
|
isFirstCheck = false;
|
|
950
948
|
}
|
|
951
949
|
else {
|
|
952
|
-
|
|
950
|
+
logger_1.log.debug(`${timer.getDuration().asMilliSeconds.toFixed(0)}ms elapsed since ` +
|
|
953
951
|
`emulator readiness check has started`);
|
|
954
952
|
}
|
|
955
953
|
try {
|
|
@@ -959,7 +957,7 @@ async function waitForEmulatorReady(timeoutMs = 20000) {
|
|
|
959
957
|
this.shell(['getprop', 'init.svc.bootanim']),
|
|
960
958
|
]);
|
|
961
959
|
if (bootCompleted.trim() !== '1' || !['stopped', ''].includes(bootAnimState.trim())) {
|
|
962
|
-
|
|
960
|
+
logger_1.log.debug(`Current status: sys.boot_completed=${bootCompleted.trim()}, ` +
|
|
963
961
|
`init.svc.bootanim=${bootAnimState.trim()}`);
|
|
964
962
|
return false;
|
|
965
963
|
}
|
|
@@ -969,14 +967,14 @@ async function waitForEmulatorReady(timeoutMs = 20000) {
|
|
|
969
967
|
services = servicesOutput;
|
|
970
968
|
if (!servicesOutput ||
|
|
971
969
|
!requiredServicesRe.every((pattern) => pattern.test(servicesOutput))) {
|
|
972
|
-
|
|
970
|
+
logger_1.log.debug(`Running services: ${servicesOutput}`);
|
|
973
971
|
return false;
|
|
974
972
|
}
|
|
975
973
|
return true;
|
|
976
974
|
}
|
|
977
975
|
catch (err) {
|
|
978
976
|
const error = err;
|
|
979
|
-
|
|
977
|
+
logger_1.log.debug(`Intermediate error: ${error.message}`);
|
|
980
978
|
return false;
|
|
981
979
|
}
|
|
982
980
|
}, {
|
|
@@ -998,7 +996,7 @@ async function waitForEmulatorReady(timeoutMs = 20000) {
|
|
|
998
996
|
const elapsedMs = timer.getDuration().asMilliSeconds;
|
|
999
997
|
// Only log if the wait took a noticeable amount of time
|
|
1000
998
|
if (elapsedMs > 100) {
|
|
1001
|
-
|
|
999
|
+
logger_1.log.info(`Emulator is ready after ${elapsedMs}ms`);
|
|
1002
1000
|
}
|
|
1003
1001
|
}
|
|
1004
1002
|
/**
|
|
@@ -1088,7 +1086,7 @@ async function reboot(retries = DEFAULT_ADB_REBOOT_RETRIES) {
|
|
|
1088
1086
|
}
|
|
1089
1087
|
const msg = `Reboot is not completed after ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`;
|
|
1090
1088
|
// we don't want the stack trace
|
|
1091
|
-
|
|
1089
|
+
logger_1.log.debug(msg);
|
|
1092
1090
|
throw new Error(msg);
|
|
1093
1091
|
});
|
|
1094
1092
|
}
|
|
@@ -1109,7 +1107,7 @@ async function changeUserPrivileges(isElevated) {
|
|
|
1109
1107
|
// Check the output of the stdErr to see if there's any clues that show that the device went offline
|
|
1110
1108
|
// and if it did go offline, restart ADB
|
|
1111
1109
|
if (['closed', 'device offline', 'timeout expired'].some((x) => (error.stderr || '').toLowerCase().includes(x))) {
|
|
1112
|
-
|
|
1110
|
+
logger_1.log.warn(`Attempt to ${cmd} caused ADB to think the device went offline`);
|
|
1113
1111
|
try {
|
|
1114
1112
|
await this.reconnect();
|
|
1115
1113
|
}
|
|
@@ -1131,7 +1129,7 @@ async function changeUserPrivileges(isElevated) {
|
|
|
1131
1129
|
let wasAlreadyRooted = isRoot;
|
|
1132
1130
|
try {
|
|
1133
1131
|
const { stdout } = await retryIfOffline(async () => await this.adbExec([cmd]));
|
|
1134
|
-
|
|
1132
|
+
logger_1.log.debug(stdout);
|
|
1135
1133
|
// on real devices in some situations we get an error in the stdout
|
|
1136
1134
|
if (stdout) {
|
|
1137
1135
|
if (stdout.includes('adbd cannot run as root')) {
|
|
@@ -1147,7 +1145,7 @@ async function changeUserPrivileges(isElevated) {
|
|
|
1147
1145
|
catch (err) {
|
|
1148
1146
|
const error = err;
|
|
1149
1147
|
const { stderr = '', message } = error;
|
|
1150
|
-
|
|
1148
|
+
logger_1.log.warn(`Unable to ${cmd} adb daemon. Original error: '${message}'. Stderr: '${stderr}'. Continuing.`);
|
|
1151
1149
|
return { isSuccessful: false, wasAlreadyRooted };
|
|
1152
1150
|
}
|
|
1153
1151
|
}
|
|
@@ -1195,19 +1193,19 @@ async function installMitmCertificate(cert) {
|
|
|
1195
1193
|
await support_1.fs.writeFile(srcCert, Buffer.isBuffer(cert) ? cert : Buffer.from(cert, 'base64'));
|
|
1196
1194
|
const { stdout } = await (0, teen_process_1.exec)(openSsl, ['x509', '-noout', '-hash', '-in', srcCert]);
|
|
1197
1195
|
const certHash = stdout.trim();
|
|
1198
|
-
|
|
1199
|
-
|
|
1196
|
+
logger_1.log.debug(`Got certificate hash: ${certHash}`);
|
|
1197
|
+
logger_1.log.debug('Preparing certificate content');
|
|
1200
1198
|
const { stdout: stdoutBuff1 } = await (0, teen_process_1.exec)(openSsl, ['x509', '-in', srcCert], { isBuffer: true });
|
|
1201
1199
|
const { stdout: stdoutBuff2 } = await (0, teen_process_1.exec)(openSsl, ['x509', '-in', srcCert, '-text', '-fingerprint', '-noout'], { isBuffer: true });
|
|
1202
1200
|
const dstCertContent = Buffer.concat([stdoutBuff1, stdoutBuff2]);
|
|
1203
1201
|
const dstCert = node_path_1.default.resolve(tmpRoot, `${certHash}.0`);
|
|
1204
1202
|
await support_1.fs.writeFile(dstCert, dstCertContent);
|
|
1205
|
-
|
|
1203
|
+
logger_1.log.debug('Remounting /system in rw mode');
|
|
1206
1204
|
// Sometimes emulator reboot is still not fully finished on this stage, so retry
|
|
1207
1205
|
await (0, asyncbox_1.retryInterval)(5, 2000, async () => await this.adbExec(['remount']));
|
|
1208
|
-
|
|
1206
|
+
logger_1.log.debug(`Uploading the generated certificate from '${dstCert}' to '${CERTS_ROOT}'`);
|
|
1209
1207
|
await this.push(dstCert, CERTS_ROOT);
|
|
1210
|
-
|
|
1208
|
+
logger_1.log.debug('Remounting /system to confirm changes');
|
|
1211
1209
|
await this.adbExec(['remount']);
|
|
1212
1210
|
}
|
|
1213
1211
|
catch (err) {
|
|
@@ -1248,7 +1246,7 @@ async function isMitmCertificateInstalled(cert) {
|
|
|
1248
1246
|
await support_1.fs.rimraf(tmpRoot);
|
|
1249
1247
|
}
|
|
1250
1248
|
const dstPath = node_path_1.default.posix.resolve(CERTS_ROOT, `${certHash}.0`);
|
|
1251
|
-
|
|
1249
|
+
logger_1.log.debug(`Checking if the certificate is already installed at '${dstPath}'`);
|
|
1252
1250
|
return await this.fileExists(dstPath);
|
|
1253
1251
|
}
|
|
1254
1252
|
/**
|
|
@@ -1281,7 +1279,7 @@ async function shellChunks(argTransformer, args) {
|
|
|
1281
1279
|
if (!lodash_1.default.isEmpty(cmdChunk)) {
|
|
1282
1280
|
commands.push(cmdChunk);
|
|
1283
1281
|
}
|
|
1284
|
-
|
|
1282
|
+
logger_1.log.debug(`Got the following command chunks to execute: ${JSON.stringify(commands)}`);
|
|
1285
1283
|
let lastError = null;
|
|
1286
1284
|
for (const cmd of commands) {
|
|
1287
1285
|
try {
|
|
@@ -1346,15 +1344,15 @@ exports.getBuildToolsDirs = lodash_1.default.memoize(async function getBuildTool
|
|
|
1346
1344
|
}
|
|
1347
1345
|
catch (err) {
|
|
1348
1346
|
const error = err;
|
|
1349
|
-
|
|
1347
|
+
logger_1.log.warn(`Cannot sort build-tools folders ${JSON.stringify(buildToolsDirs.map((dir) => node_path_1.default.basename(dir)))} ` +
|
|
1350
1348
|
`by semantic version names.`);
|
|
1351
|
-
|
|
1349
|
+
logger_1.log.warn(`Falling back to sorting by modification date. Original error: ${error.message}`);
|
|
1352
1350
|
const pairs = await bluebird_1.default.map(buildToolsDirs, async (dir) => [(await support_1.fs.stat(dir)).mtime.valueOf(), dir]);
|
|
1353
1351
|
buildToolsDirs = pairs.sort((a, b) => (a[0] < b[0] ? 1 : -1)).map((pair) => pair[1]);
|
|
1354
1352
|
}
|
|
1355
|
-
|
|
1353
|
+
logger_1.log.info(`Found ${buildToolsDirs.length} 'build-tools' folders under '${sdkRoot}' (newest first):`);
|
|
1356
1354
|
for (const dir of buildToolsDirs) {
|
|
1357
|
-
|
|
1355
|
+
logger_1.log.info(` ${dir}`);
|
|
1358
1356
|
}
|
|
1359
1357
|
return buildToolsDirs;
|
|
1360
1358
|
});
|