UNPKG

appium-adb

Version:

Android Debug Bridge interface

1,284 lines (1,005 loc) 78.2 kB
'use strict'; var _regeneratorRuntime = require('babel-runtime/regenerator')['default']; var _getIterator = require('babel-runtime/core-js/get-iterator')['default']; var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default']; Object.defineProperty(exports, '__esModule', { value: true }); var _path = require('path'); var _path2 = _interopRequireDefault(_path); var _loggerJs = require('../logger.js'); var _loggerJs2 = _interopRequireDefault(_loggerJs); var _bluebird = require('bluebird'); var _bluebird2 = _interopRequireDefault(_bluebird); var _appiumSupport = require('appium-support'); var _helpers = require('../helpers'); var _teen_process = require('teen_process'); var _asyncbox = require('asyncbox'); var systemCallMethods = {}; var DEFAULT_ADB_EXEC_TIMEOUT = 20000; // in milliseconds systemCallMethods.getSdkBinaryPath = function callee$0$0(binaryName) { return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: _loggerJs2['default'].info('Checking whether ' + binaryName + ' is present'); if (!this.sdkRoot) { context$1$0.next = 5; break; } return context$1$0.abrupt('return', this.getBinaryFromSdkRoot(binaryName)); case 5: _loggerJs2['default'].warn('The ANDROID_HOME environment variable is not set to the Android SDK ' + 'root directory path. ANDROID_HOME is required for compatibility ' + ('with SDK 23+. Checking along PATH for ' + binaryName + '.')); context$1$0.next = 8; return _regeneratorRuntime.awrap(this.getBinaryFromPath(binaryName)); case 8: return context$1$0.abrupt('return', context$1$0.sent); case 9: case 'end': return context$1$0.stop(); } }, null, this); }; systemCallMethods.getCommandForOS = function () { var cmd = "which"; if (_appiumSupport.system.isWindows()) { cmd = "where"; } return cmd; }; systemCallMethods.getBinaryNameForOS = function (binaryName) { if (_appiumSupport.system.isWindows()) { if (binaryName === "android") { binaryName += ".bat"; } else { if (binaryName.indexOf(".exe", binaryName.length - 4) === -1) { binaryName += ".exe"; } } } return binaryName; }; systemCallMethods.getBinaryFromSdkRoot = function callee$0$0(binaryName) { var binaryLoc, binaryLocs, buildToolDirs, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, versionDir, _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, loc, flag; return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: binaryLoc = null; binaryName = this.getBinaryNameForOS(binaryName); binaryLocs = [_path2['default'].resolve(this.sdkRoot, "platform-tools", binaryName), _path2['default'].resolve(this.sdkRoot, "tools", binaryName)]; buildToolDirs = []; context$1$0.next = 6; return _regeneratorRuntime.awrap((0, _helpers.getDirectories)(_path2['default'].resolve(this.sdkRoot, "build-tools"))); case 6: buildToolDirs = context$1$0.sent; _iteratorNormalCompletion = true; _didIteratorError = false; _iteratorError = undefined; context$1$0.prev = 10; for (_iterator = _getIterator(buildToolDirs); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { versionDir = _step.value; binaryLocs.push(_path2['default'].resolve(this.sdkRoot, "build-tools", versionDir, binaryName)); } context$1$0.next = 18; break; case 14: context$1$0.prev = 14; context$1$0.t0 = context$1$0['catch'](10); _didIteratorError = true; _iteratorError = context$1$0.t0; case 18: context$1$0.prev = 18; context$1$0.prev = 19; if (!_iteratorNormalCompletion && _iterator['return']) { _iterator['return'](); } case 21: context$1$0.prev = 21; if (!_didIteratorError) { context$1$0.next = 24; break; } throw _iteratorError; case 24: return context$1$0.finish(21); case 25: return context$1$0.finish(18); case 26: _iteratorNormalCompletion2 = true; _didIteratorError2 = false; _iteratorError2 = undefined; context$1$0.prev = 29; _iterator2 = _getIterator(binaryLocs); case 31: if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) { context$1$0.next = 40; break; } loc = _step2.value; context$1$0.next = 35; return _regeneratorRuntime.awrap(_appiumSupport.fs.exists(loc)); case 35: flag = context$1$0.sent; if (flag) { binaryLoc = loc; } case 37: _iteratorNormalCompletion2 = true; context$1$0.next = 31; break; case 40: context$1$0.next = 46; break; case 42: context$1$0.prev = 42; context$1$0.t1 = context$1$0['catch'](29); _didIteratorError2 = true; _iteratorError2 = context$1$0.t1; case 46: context$1$0.prev = 46; context$1$0.prev = 47; if (!_iteratorNormalCompletion2 && _iterator2['return']) { _iterator2['return'](); } case 49: context$1$0.prev = 49; if (!_didIteratorError2) { context$1$0.next = 52; break; } throw _iteratorError2; case 52: return context$1$0.finish(49); case 53: return context$1$0.finish(46); case 54: if (!(binaryLoc === null)) { context$1$0.next = 56; break; } throw new Error('Could not find ' + binaryName + ' in tools, platform-tools, ' + ('or supported build-tools under ' + this.sdkRoot + ' ') + 'do you have the Android SDK installed at this location?'); case 56: binaryLoc = binaryLoc.trim(); _loggerJs2['default'].info('Using ' + binaryName + ' from ' + binaryLoc); return context$1$0.abrupt('return', binaryLoc); case 59: case 'end': return context$1$0.stop(); } }, null, this, [[10, 14, 18, 26], [19,, 21, 25], [29, 42, 46, 54], [47,, 49, 53]]); }; systemCallMethods.getBinaryFromPath = function callee$0$0(binaryName) { var binaryLoc, cmd, _ref, stdout; return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: binaryLoc = null; cmd = this.getCommandForOS(); context$1$0.prev = 2; context$1$0.next = 5; return _regeneratorRuntime.awrap((0, _teen_process.exec)(cmd, [binaryName])); case 5: _ref = context$1$0.sent; stdout = _ref.stdout; _loggerJs2['default'].info('Using ' + binaryName + ' from ' + stdout); // TODO write a test for binaries with spaces. binaryLoc = stdout.trim(); return context$1$0.abrupt('return', binaryLoc); case 12: context$1$0.prev = 12; context$1$0.t0 = context$1$0['catch'](2); _loggerJs2['default'].errorAndThrow('Could not find ' + binaryName + ' Please set the ANDROID_HOME ' + 'environment variable with the Android SDK root directory path.'); case 15: case 'end': return context$1$0.stop(); } }, null, this, [[2, 12]]); }; systemCallMethods.getConnectedDevices = function callee$0$0() { var _ref2, stdout, startingIndex, devices, _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, line, lineInfo; return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: _loggerJs2['default'].debug("Getting connected devices..."); context$1$0.prev = 1; context$1$0.next = 4; return _regeneratorRuntime.awrap((0, _teen_process.exec)(this.executable.path, ['devices'])); case 4: _ref2 = context$1$0.sent; stdout = _ref2.stdout; startingIndex = stdout.indexOf("List of devices"); if (!(startingIndex === -1)) { context$1$0.next = 11; break; } throw new Error('Unexpected output while trying to get devices. output was: ' + stdout); case 11: // slicing ouput we care about. stdout = stdout.slice(startingIndex); devices = []; _iteratorNormalCompletion3 = true; _didIteratorError3 = false; _iteratorError3 = undefined; context$1$0.prev = 16; for (_iterator3 = _getIterator(stdout.split("\n")); !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { line = _step3.value; if (line.trim() !== "" && line.indexOf("List of devices") === -1 && line.indexOf("* daemon") === -1 && line.indexOf("offline") === -1) { lineInfo = line.split("\t"); // state is either "device" or "offline", afaict devices.push({ udid: lineInfo[0], state: lineInfo[1] }); } } context$1$0.next = 24; break; case 20: context$1$0.prev = 20; context$1$0.t0 = context$1$0['catch'](16); _didIteratorError3 = true; _iteratorError3 = context$1$0.t0; case 24: context$1$0.prev = 24; context$1$0.prev = 25; if (!_iteratorNormalCompletion3 && _iterator3['return']) { _iterator3['return'](); } case 27: context$1$0.prev = 27; if (!_didIteratorError3) { context$1$0.next = 30; break; } throw _iteratorError3; case 30: return context$1$0.finish(27); case 31: return context$1$0.finish(24); case 32: _loggerJs2['default'].debug(devices.length + ' device(s) connected'); return context$1$0.abrupt('return', devices); case 34: context$1$0.next = 39; break; case 36: context$1$0.prev = 36; context$1$0.t1 = context$1$0['catch'](1); _loggerJs2['default'].errorAndThrow('Error while getting connected devices. Original error: ' + context$1$0.t1.message); case 39: case 'end': return context$1$0.stop(); } }, null, this, [[1, 36], [16, 20, 24, 32], [25,, 27, 31]]); }; systemCallMethods.getDevicesWithRetry = function callee$0$0() { var timeoutMs = arguments.length <= 0 || arguments[0] === undefined ? 20000 : arguments[0]; var start, getDevices; return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { var _this = this; while (1) switch (context$1$0.prev = context$1$0.next) { case 0: start = Date.now(); _loggerJs2['default'].debug("Trying to find a connected android device"); getDevices = function getDevices() { var devices; return _regeneratorRuntime.async(function getDevices$(context$2$0) { while (1) switch (context$2$0.prev = context$2$0.next) { case 0: if (!(Date.now() - start > timeoutMs)) { context$2$0.next = 2; break; } throw new Error("Could not find a connected Android device."); case 2: context$2$0.prev = 2; context$2$0.next = 5; return _regeneratorRuntime.awrap(this.getConnectedDevices()); case 5: devices = context$2$0.sent; if (!(devices.length < 1)) { context$2$0.next = 15; break; } _loggerJs2['default'].debug("Could not find devices, restarting adb server..."); context$2$0.next = 10; return _regeneratorRuntime.awrap(this.restartAdb()); case 10: context$2$0.next = 12; return _regeneratorRuntime.awrap((0, _asyncbox.sleep)(200)); case 12: context$2$0.next = 14; return _regeneratorRuntime.awrap(getDevices()); case 14: return context$2$0.abrupt('return', context$2$0.sent); case 15: return context$2$0.abrupt('return', devices); case 18: context$2$0.prev = 18; context$2$0.t0 = context$2$0['catch'](2); _loggerJs2['default'].debug("Could not find devices, restarting adb server..."); context$2$0.next = 23; return _regeneratorRuntime.awrap(this.restartAdb()); case 23: context$2$0.next = 25; return _regeneratorRuntime.awrap((0, _asyncbox.sleep)(200)); case 25: context$2$0.next = 27; return _regeneratorRuntime.awrap(getDevices()); case 27: return context$2$0.abrupt('return', context$2$0.sent); case 28: case 'end': return context$2$0.stop(); } }, null, _this, [[2, 18]]); }; context$1$0.next = 5; return _regeneratorRuntime.awrap(getDevices()); case 5: return context$1$0.abrupt('return', context$1$0.sent); case 6: case 'end': return context$1$0.stop(); } }, null, this); }; systemCallMethods.restartAdb = function callee$0$0() { return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: if (this.suppressKillServer) { context$1$0.next = 10; break; } _loggerJs2['default'].debug('Restarting adb'); context$1$0.prev = 2; context$1$0.next = 5; return _regeneratorRuntime.awrap((0, _teen_process.exec)(this.executable.path, ['kill-server'])); case 5: context$1$0.next = 10; break; case 7: context$1$0.prev = 7; context$1$0.t0 = context$1$0['catch'](2); _loggerJs2['default'].error("Error killing ADB server, going to see if it's online anyway"); case 10: case 'end': return context$1$0.stop(); } }, null, this, [[2, 7]]); }; systemCallMethods.adbExec = function callee$0$0(cmd) { var opts = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; var execFunc; return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { var _this2 = this; while (1) switch (context$1$0.prev = context$1$0.next) { case 0: if (cmd) { context$1$0.next = 2; break; } throw new Error("You need to pass in a command to adbExec()"); case 2: // setting default timeout for each command to prevent infinite wait. opts.timeout = opts.timeout || DEFAULT_ADB_EXEC_TIMEOUT; execFunc = function execFunc() { var args, _ref3, stdout, linkerWarningRe, protocolFaultError, deviceNotFoundError; return _regeneratorRuntime.async(function execFunc$(context$2$0) { while (1) switch (context$2$0.prev = context$2$0.next) { case 0: context$2$0.prev = 0; if (!(cmd instanceof Array)) { cmd = [cmd]; } args = this.executable.defaultArgs.concat(cmd); _loggerJs2['default'].debug('Running ' + this.executable.path + ' with args: ' + ('' + JSON.stringify(args))); context$2$0.next = 6; return _regeneratorRuntime.awrap((0, _teen_process.exec)(this.executable.path, args, opts)); case 6: _ref3 = context$2$0.sent; stdout = _ref3.stdout; linkerWarningRe = /^WARNING: linker.+$/m; stdout = stdout.replace(linkerWarningRe, '').trim(); return context$2$0.abrupt('return', stdout); case 13: context$2$0.prev = 13; context$2$0.t0 = context$2$0['catch'](0); protocolFaultError = new RegExp("protocol fault \\(no status\\)", "i").test(context$2$0.t0); deviceNotFoundError = new RegExp("error: device ('.+' )?not found", "i").test(context$2$0.t0); if (!(protocolFaultError || deviceNotFoundError)) { context$2$0.next = 23; break; } _loggerJs2['default'].info('error sending command, reconnecting device and retrying: ' + cmd); context$2$0.next = 21; return _regeneratorRuntime.awrap((0, _asyncbox.sleep)(1000)); case 21: context$2$0.next = 23; return _regeneratorRuntime.awrap(this.getDevicesWithRetry()); case 23: throw new Error('Error executing adbExec. Original error: ' + context$2$0.t0.message + JSON.stringify(context$2$0.t0)); case 24: case 'end': return context$2$0.stop(); } }, null, _this2, [[0, 13]]); }; context$1$0.next = 6; return _regeneratorRuntime.awrap((0, _asyncbox.retry)(2, execFunc)); case 6: return context$1$0.abrupt('return', context$1$0.sent); case 7: case 'end': return context$1$0.stop(); } }, null, this); }; systemCallMethods.shell = function callee$0$0(cmd) { var opts = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; var execCmd; return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: context$1$0.next = 2; return _regeneratorRuntime.awrap(this.isDeviceConnected()); case 2: if (context$1$0.sent) { context$1$0.next = 4; break; } throw new Error('No device connected, cannot run adb shell command "' + cmd.join(' ') + '"'); case 4: execCmd = ['shell']; if (cmd instanceof Array) { execCmd = execCmd.concat(cmd); } else { execCmd.push(cmd); } context$1$0.next = 8; return _regeneratorRuntime.awrap(this.adbExec(execCmd, opts)); case 8: return context$1$0.abrupt('return', context$1$0.sent); case 9: case 'end': return context$1$0.stop(); } }, null, this); }; systemCallMethods.createSubProcess = function () { var args = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; // add the default arguments args = this.executable.defaultArgs.concat(args); _loggerJs2['default'].debug('Creating ADB subprocess with args: ' + args.join(', ')); return new _teen_process.SubProcess(this.getAdbPath(), args); }; // TODO can probably deprecate this now that the logic is just to read // this.adbPort systemCallMethods.getAdbServerPort = function () { return this.adbPort; }; systemCallMethods.getEmulatorPort = function callee$0$0() { var devices, port; return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: _loggerJs2['default'].debug("Getting running emulator port"); if (!(this.emulatorPort !== null)) { context$1$0.next = 3; break; } return context$1$0.abrupt('return', this.emulatorPort); case 3: context$1$0.prev = 3; context$1$0.next = 6; return _regeneratorRuntime.awrap(this.getConnectedDevices()); case 6: devices = context$1$0.sent; port = this.getPortFromEmulatorString(devices[0].udid); if (!port) { context$1$0.next = 12; break; } return context$1$0.abrupt('return', port); case 12: throw new Error('Emulator port not found'); case 13: context$1$0.next = 18; break; case 15: context$1$0.prev = 15; context$1$0.t0 = context$1$0['catch'](3); _loggerJs2['default'].errorAndThrow('No devices connected. Original error: ' + context$1$0.t0.message); case 18: case 'end': return context$1$0.stop(); } }, null, this, [[3, 15]]); }; systemCallMethods.getPortFromEmulatorString = function (emStr) { var portPattern = /emulator-(\d+)/; if (portPattern.test(emStr)) { return parseInt(portPattern.exec(emStr)[1], 10); } return false; }; systemCallMethods.getConnectedEmulators = function callee$0$0() { var devices, emulators, _iteratorNormalCompletion4, _didIteratorError4, _iteratorError4, _iterator4, _step4, device, port; return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: context$1$0.prev = 0; _loggerJs2['default'].debug("Getting connected emulators"); context$1$0.next = 4; return _regeneratorRuntime.awrap(this.getConnectedDevices()); case 4: devices = context$1$0.sent; emulators = []; _iteratorNormalCompletion4 = true; _didIteratorError4 = false; _iteratorError4 = undefined; context$1$0.prev = 9; for (_iterator4 = _getIterator(devices); !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { device = _step4.value; port = this.getPortFromEmulatorString(device.udid); if (port) { device.port = port; emulators.push(device); } } context$1$0.next = 17; break; case 13: context$1$0.prev = 13; context$1$0.t0 = context$1$0['catch'](9); _didIteratorError4 = true; _iteratorError4 = context$1$0.t0; case 17: context$1$0.prev = 17; context$1$0.prev = 18; if (!_iteratorNormalCompletion4 && _iterator4['return']) { _iterator4['return'](); } case 20: context$1$0.prev = 20; if (!_didIteratorError4) { context$1$0.next = 23; break; } throw _iteratorError4; case 23: return context$1$0.finish(20); case 24: return context$1$0.finish(17); case 25: _loggerJs2['default'].debug(emulators.length + ' emulator(s) connected'); return context$1$0.abrupt('return', emulators); case 29: context$1$0.prev = 29; context$1$0.t1 = context$1$0['catch'](0); _loggerJs2['default'].errorAndThrow('Error getting emulators. Original error: ' + context$1$0.t1.message); case 32: case 'end': return context$1$0.stop(); } }, null, this, [[0, 29], [9, 13, 17, 25], [18,, 20, 24]]); }; systemCallMethods.setEmulatorPort = function (emPort) { this.emulatorPort = emPort; }; systemCallMethods.setDeviceId = function (deviceId) { _loggerJs2['default'].debug('Setting device id to ' + deviceId); this.curDeviceId = deviceId; var argsHasDevice = this.executable.defaultArgs.indexOf('-s'); if (argsHasDevice !== -1) { // remove the old device id from the arguments this.executable.defaultArgs.splice(argsHasDevice, 2); } this.executable.defaultArgs.push('-s', deviceId); }; systemCallMethods.setDevice = function (deviceObj) { var deviceId = deviceObj.udid; var emPort = this.getPortFromEmulatorString(deviceId); this.setEmulatorPort(emPort); this.setDeviceId(deviceId); }; systemCallMethods.getRunningAVD = function callee$0$0(avdName) { var emulators, _iteratorNormalCompletion5, _didIteratorError5, _iteratorError5, _iterator5, _step5, emulator, runningAVDName; return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: context$1$0.prev = 0; _loggerJs2['default'].debug('Trying to find ' + avdName + ' emulator'); context$1$0.next = 4; return _regeneratorRuntime.awrap(this.getConnectedEmulators()); case 4: emulators = context$1$0.sent; _iteratorNormalCompletion5 = true; _didIteratorError5 = false; _iteratorError5 = undefined; context$1$0.prev = 8; _iterator5 = _getIterator(emulators); case 10: if (_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done) { context$1$0.next = 23; break; } emulator = _step5.value; this.setEmulatorPort(emulator.port); context$1$0.next = 15; return _regeneratorRuntime.awrap(this.sendTelnetCommand("avd name")); case 15: runningAVDName = context$1$0.sent; if (!(avdName === runningAVDName)) { context$1$0.next = 20; break; } _loggerJs2['default'].debug('Found emulator ' + avdName + ' in port ' + emulator.port); this.setDeviceId(emulator.udid); return context$1$0.abrupt('return', emulator); case 20: _iteratorNormalCompletion5 = true; context$1$0.next = 10; break; case 23: context$1$0.next = 29; break; case 25: context$1$0.prev = 25; context$1$0.t0 = context$1$0['catch'](8); _didIteratorError5 = true; _iteratorError5 = context$1$0.t0; case 29: context$1$0.prev = 29; context$1$0.prev = 30; if (!_iteratorNormalCompletion5 && _iterator5['return']) { _iterator5['return'](); } case 32: context$1$0.prev = 32; if (!_didIteratorError5) { context$1$0.next = 35; break; } throw _iteratorError5; case 35: return context$1$0.finish(32); case 36: return context$1$0.finish(29); case 37: _loggerJs2['default'].debug('Emulator ' + avdName + ' not running'); return context$1$0.abrupt('return', null); case 41: context$1$0.prev = 41; context$1$0.t1 = context$1$0['catch'](0); _loggerJs2['default'].errorAndThrow('Error getting AVD. Original error: ' + context$1$0.t1.message); case 44: case 'end': return context$1$0.stop(); } }, null, this, [[0, 41], [8, 25, 29, 37], [30,, 32, 36]]); }; systemCallMethods.getRunningAVDWithRetry = function callee$0$0(avdName) { var timeoutMs = arguments.length <= 1 || arguments[1] === undefined ? 20000 : arguments[1]; var start, runningAVD; return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: context$1$0.prev = 0; start = Date.now(); case 2: if (!(Date.now() - start < timeoutMs)) { context$1$0.next = 18; break; } context$1$0.prev = 3; context$1$0.next = 6; return _regeneratorRuntime.awrap(this.getRunningAVD(avdName.replace('@', ''))); case 6: runningAVD = context$1$0.sent; if (!runningAVD) { context$1$0.next = 9; break; } return context$1$0.abrupt('return', runningAVD); case 9: context$1$0.next = 14; break; case 11: context$1$0.prev = 11; context$1$0.t0 = context$1$0['catch'](3); // Do nothing. _loggerJs2['default'].info('Couldn\'t get running AVD, will retry. Error was: ' + context$1$0.t0.message); case 14: context$1$0.next = 16; return _regeneratorRuntime.awrap((0, _asyncbox.sleep)(200)); case 16: context$1$0.next = 2; break; case 18: _loggerJs2['default'].errorAndThrow('Could not find ' + avdName + ' emulator.'); context$1$0.next = 24; break; case 21: context$1$0.prev = 21; context$1$0.t1 = context$1$0['catch'](0); _loggerJs2['default'].errorAndThrow('Error getting AVD with retry. Original error: ' + context$1$0.t1.message); case 24: case 'end': return context$1$0.stop(); } }, null, this, [[0, 21], [3, 11]]); }; systemCallMethods.killAllEmulators = function callee$0$0() { var cmd, args; return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: cmd = undefined, args = undefined; if (_appiumSupport.system.isWindows()) { cmd = 'TASKKILL'; args = ['TASKKILL', '/IM', 'emulator.exe']; } else { cmd = '/usr/bin/killall'; args = ['-m', 'emulator*']; } context$1$0.prev = 2; context$1$0.next = 5; return _regeneratorRuntime.awrap((0, _teen_process.exec)(cmd, args)); case 5: context$1$0.next = 10; break; case 7: context$1$0.prev = 7; context$1$0.t0 = context$1$0['catch'](2); _loggerJs2['default'].errorAndThrow('Error killing emulators. Original error: ' + context$1$0.t0.message); case 10: case 'end': return context$1$0.stop(); } }, null, this, [[2, 7]]); }; systemCallMethods.launchAVD = function callee$0$0(avdName, avdArgs, language, country) { var avdLaunchTimeout = arguments.length <= 4 || arguments[4] === undefined ? 60000 : arguments[4]; var avdReadyTimeout = arguments.length <= 5 || arguments[5] === undefined ? 60000 : arguments[5]; var retryTimes = arguments.length <= 6 || arguments[6] === undefined ? 1 : arguments[6]; var emulatorBinaryPath, launchArgs, locale, proc; return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: _loggerJs2['default'].debug('Launching Emulator with AVD ' + avdName + ', launchTimeout' + (avdLaunchTimeout + ' ms and readyTimeout ' + avdReadyTimeout + ' ms')); context$1$0.next = 3; return _regeneratorRuntime.awrap(this.getSdkBinaryPath("emulator")); case 3: emulatorBinaryPath = context$1$0.sent; if (avdName[0] === "@") { avdName = avdName.substr(1); } launchArgs = ["-avd", avdName]; if (typeof language === "string") { _loggerJs2['default'].debug('Setting Android Device Language to ' + language); launchArgs.push("-prop", 'persist.sys.language=' + language.toLowerCase()); } if (typeof country === "string") { _loggerJs2['default'].debug('Setting Android Device Country to ' + country); launchArgs.push("-prop", 'persist.sys.country=' + country.toUpperCase()); } locale = undefined; if (typeof language === "string" && typeof country === "string") { locale = language.toLowerCase() + "-" + country.toUpperCase(); } else if (typeof language === "string") { locale = language.toLowerCase(); } else if (typeof country === "string") { locale = country; } if (typeof locale === "string") { _loggerJs2['default'].debug('Setting Android Device Locale to ' + locale); launchArgs.push("-prop", 'persist.sys.locale=' + locale); } if (typeof avdArgs === "string") { avdArgs = avdArgs.split(" "); launchArgs = launchArgs.concat(avdArgs); } proc = new _teen_process.SubProcess(emulatorBinaryPath, launchArgs); context$1$0.next = 15; return _regeneratorRuntime.awrap(proc.start(0)); case 15: proc.on('output', function (stdout, stderr) { _loggerJs2['default'].info('[AVD OUTPUT] ' + (stdout || stderr)); }); context$1$0.next = 18; return _regeneratorRuntime.awrap((0, _asyncbox.retry)(retryTimes, this.getRunningAVDWithRetry.bind(this), avdName, avdLaunchTimeout)); case 18: context$1$0.next = 20; return _regeneratorRuntime.awrap(this.waitForEmulatorReady(avdReadyTimeout)); case 20: return context$1$0.abrupt('return', proc); case 21: case 'end': return context$1$0.stop(); } }, null, this); }; systemCallMethods.waitForEmulatorReady = function callee$0$0() { var timeoutMs = arguments.length <= 0 || arguments[0] === undefined ? 20000 : arguments[0]; var start, stdout; return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: start = Date.now(); _loggerJs2['default'].debug("Waiting until emulator is ready"); case 2: if (!(Date.now() - start < timeoutMs)) { context$1$0.next = 17; break; } context$1$0.prev = 3; context$1$0.next = 6; return _regeneratorRuntime.awrap(this.shell(["getprop", "init.svc.bootanim"])); case 6: stdout = context$1$0.sent; if (!(stdout.indexOf('stopped') > -1)) { context$1$0.next = 9; break; } return context$1$0.abrupt('return'); case 9: context$1$0.next = 13; break; case 11: context$1$0.prev = 11; context$1$0.t0 = context$1$0['catch'](3); case 13: context$1$0.next = 15; return _regeneratorRuntime.awrap((0, _asyncbox.sleep)(3000)); case 15: context$1$0.next = 2; break; case 17: _loggerJs2['default'].errorAndThrow('Emulator not ready'); case 18: case 'end': return context$1$0.stop(); } }, null, this, [[3, 11]]); }; systemCallMethods.waitForDevice = function callee$0$0() { var appDeviceReadyTimeout = arguments.length <= 0 || arguments[0] === undefined ? 30 : arguments[0]; var retries, timeout; return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { var _this3 = this; while (1) switch (context$1$0.prev = context$1$0.next) { case 0: this.appDeviceReadyTimeout = appDeviceReadyTimeout; retries = 3; timeout = parseInt(this.appDeviceReadyTimeout, 10) / retries * 1000; context$1$0.next = 5; return _regeneratorRuntime.awrap((0, _asyncbox.retry)(retries, function callee$1$0() { return _regeneratorRuntime.async(function callee$1$0$(context$2$0) { while (1) switch (context$2$0.prev = context$2$0.next) { case 0: context$2$0.prev = 0; context$2$0.next = 3; return _regeneratorRuntime.awrap(this.adbExec('wait-for-device', { timeout: timeout })); case 3: context$2$0.next = 5; return _regeneratorRuntime.awrap(this.ping()); case 5: context$2$0.next = 14; break; case 7: context$2$0.prev = 7; context$2$0.t0 = context$2$0['catch'](0); context$2$0.next = 11; return _regeneratorRuntime.awrap(this.restartAdb()); case 11: context$2$0.next = 13; return _regeneratorRuntime.awrap(this.getConnectedDevices()); case 13: _loggerJs2['default'].errorAndThrow('Error in waiting for device. Original error: \'' + context$2$0.t0.message + '\'. ' + 'Retrying by restarting ADB'); case 14: case 'end': return context$2$0.stop(); } }, null, _this3, [[0, 7]]); })); case 5: case 'end': return context$1$0.stop(); } }, null, this); }; systemCallMethods.reboot = function callee$0$0() { return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { var _this4 = this; while (1) switch (context$1$0.prev = context$1$0.next) { case 0: context$1$0.next = 2; return _regeneratorRuntime.awrap(this.shell(['stop'])); case 2: context$1$0.next = 4; return _regeneratorRuntime.awrap(_bluebird2['default'].delay(2000)); case 4: context$1$0.next = 6; return _regeneratorRuntime.awrap(this.setDeviceProperty('sys.boot_completed', 0)); case 6: context$1$0.next = 8; return _regeneratorRuntime.awrap(this.shell(['start'])); case 8: context$1$0.next = 10; return _regeneratorRuntime.awrap((0, _asyncbox.retryInterval)(90, 1000, function callee$1$0() { var booted; return _regeneratorRuntime.async(function callee$1$0$(context$2$0) { while (1) switch (context$2$0.prev = context$2$0.next) { case 0: context$2$0.next = 2; return _regeneratorRuntime.awrap(this.getDeviceProperty('sys.boot_completed')); case 2: booted = context$2$0.sent; if (!(booted === '1')) { context$2$0.next = 7; break; } return context$2$0.abrupt('return'); case 7: _loggerJs2['default'].errorAndthrow('Waiting for reboot this takes time'); case 8: case 'end': return context$2$0.stop(); } }, null, _this4); })); case 10: case 'end': return context$1$0.stop(); } }, null, this); }; systemCallMethods.fileExists = function callee$0$0(remotePath) { var files; return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: context$1$0.next = 2; return _regeneratorRuntime.awrap(this.ls(remotePath)); case 2: files = context$1$0.sent; return context$1$0.abrupt('return', files.length > 0); case 4: case 'end': return context$1$0.stop(); } }, null, this); }; systemCallMethods.ls = function callee$0$0(remotePath) { var stdout, lines; return _regeneratorRuntime.async(function callee$0$0$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: context$1$0.next = 2; return _regeneratorRuntime.awrap(this.shell(['ls', remotePath])); case 2: stdout = context$1$0.sent; lines = stdout.split("\n"); return context$1$0.abrupt('return', lines.map(function (l) { return l.trim(); }).filter(Boolean).filter(function (l) { return l.indexOf("No such file") === -1; })); case 5: case 'end': return context$1$0.stop(); } }, null, this); }; exports['default'] = systemCallMethods; module.exports = exports['default']; // get subpaths for currently installed build tool directories // expecting adb devices to return output as // List of devices attached // emulator-5554 device // cool down // cool down // sometimes ADB prints out stupid stdout warnings that we don't want // to include in any of the response data, so let's strip it out // cool down // do nothing // let the emu finish stopping; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi90b29scy9zeXN0ZW0tY2FsbHMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O29CQUFpQixNQUFNOzs7O3dCQUNQLGNBQWM7Ozs7d0JBQ2hCLFVBQVU7Ozs7NkJBQ0csZ0JBQWdCOzt1QkFDWixZQUFZOzs0QkFDdEIsY0FBYzs7d0JBQ1MsVUFBVTs7QUFHdEQsSUFBSSxpQkFBaUIsR0FBRyxFQUFFLENBQUM7O0FBRTNCLElBQU0sd0JBQXdCLEdBQUcsS0FBSyxDQUFDOztBQUV2QyxpQkFBaUIsQ0FBQyxnQkFBZ0IsR0FBRyxvQkFBZ0IsVUFBVTs7OztBQUM3RCw4QkFBSSxJQUFJLHVCQUFxQixVQUFVLGlCQUFjLENBQUM7O2FBQ2xELElBQUksQ0FBQyxPQUFPOzs7Ozs0Q0FDUCxJQUFJLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDOzs7QUFFNUMsOEJBQUksSUFBSSxDQUFDLDJJQUNrRSwrQ0FDekIsVUFBVSxPQUFHLENBQUMsQ0FBQzs7eUNBQ3BELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLENBQUM7Ozs7Ozs7Ozs7Q0FHbEQsQ0FBQzs7QUFFRixpQkFBaUIsQ0FBQyxlQUFlLEdBQUcsWUFBWTtBQUM5QyxNQUFJLEdBQUcsR0FBRyxPQUFPLENBQUM7QUFDbEIsTUFBSSxzQkFBTyxTQUFTLEVBQUUsRUFBRTtBQUN0QixPQUFHLEdBQUcsT0FBTyxDQUFDO0dBQ2Y7QUFDRCxTQUFPLEdBQUcsQ0FBQztDQUNaLENBQUM7O0FBRUYsaUJBQWlCLENBQUMsa0JBQWtCLEdBQUcsVUFBVSxVQUFVLEVBQUU7QUFDM0QsTUFBSSxzQkFBTyxTQUFTLEVBQUUsRUFBRTtBQUN0QixRQUFJLFVBQVUsS0FBSyxTQUFTLEVBQUU7QUFDNUIsZ0JBQVUsSUFBSSxNQUFNLENBQUM7S0FDdEIsTUFBTTtBQUNMLFVBQUksVUFBVSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFD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