'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.stopAdbReverseAsync = exports.startAdbReverseAsync = exports.openProjectAsync = exports.upgradeExpoAsync = undefined; let _getAdbOutputAsync = (() => { var _ref = _asyncToGenerator(function* (args) { yield (_Binaries || _load_Binaries()).addToPathAsync('adb'); try { let result = yield (0, (_spawnAsync || _load_spawnAsync()).default)('adb', args); return result.stdout; } catch (e) { let errorMessage = (_lodash || _load_lodash()).default.trim(e.stderr); if (errorMessage.startsWith(BEGINNING_OF_ADB_ERROR_MESSAGE)) { errorMessage = errorMessage.substring(BEGINNING_OF_ADB_ERROR_MESSAGE.length); } throw new Error(errorMessage); } }); return function _getAdbOutputAsync(_x) { return _ref.apply(this, arguments); }; })(); // Device attached let _isDeviceAttachedAsync = (() => { var _ref2 = _asyncToGenerator(function* () { let devices = yield _getAdbOutputAsync(['devices']); let lines = (_lodash || _load_lodash()).default.trim(devices).split(/\r?\n/); // First line is "List of devices". return lines.length > 1; }); return function _isDeviceAttachedAsync() { return _ref2.apply(this, arguments); }; })(); let _isDeviceAuthorizedAsync = (() => { var _ref3 = _asyncToGenerator(function* () { let devices = yield _getAdbOutputAsync(['devices']); let lines = (_lodash || _load_lodash()).default.trim(devices).split(/\r?\n/); lines.shift(); let listOfDevicesWithoutFirstLine = lines.join('\n'); // result looks like "072c4cf200e333c7 device" when authorized // and "072c4cf200e333c7 unauthorized" when not. return listOfDevicesWithoutFirstLine.includes('device'); }); return function _isDeviceAuthorizedAsync() { return _ref3.apply(this, arguments); }; })(); // Expo installed let _isExpoInstalledAsync = (() => { var _ref4 = _asyncToGenerator(function* () { let packages = yield _getAdbOutputAsync(['shell', 'pm', 'list', 'packages', '-f']); let lines = packages.split(/\r?\n/); for (let i = 0; i < lines.length; i++) { let line = lines[i]; if (line.includes('host.exp.exponent.test')) { continue; } if (line.includes('host.exp.exponent')) { return true; } } return false; }); return function _isExpoInstalledAsync() { return _ref4.apply(this, arguments); }; })(); let _expoVersionAsync = (() => { var _ref5 = _asyncToGenerator(function* () { let info = yield _getAdbOutputAsync(['shell', 'dumpsys', 'package', 'host.exp.exponent']); let regex = /versionName\=([0-9\.]+)/; let regexMatch = regex.exec(info); if (regexMatch.length < 2) { return null; } return regexMatch[1]; }); return function _expoVersionAsync() { return _ref5.apply(this, arguments); }; })(); let _checkExpoUpToDateAsync = (() => { var _ref6 = _asyncToGenerator(function* () { let versions = yield (_Api || _load_Api()).default.versionsAsync(); let installedVersion = yield _expoVersionAsync(); if (!installedVersion || (_semver || _load_semver()).default.lt(installedVersion, versions.androidVersion)) { (_Logger || _load_Logger()).default.notifications.warn({ code: (_NotificationCode || _load_NotificationCode()).default.OLD_ANDROID_APP_VERSION }, 'This version of the Expo app is out of date. Uninstall the app and run again to upgrade.'); } }); return function _checkExpoUpToDateAsync() { return _ref6.apply(this, arguments); }; })(); let _downloadApkAsync = (() => { var _ref7 = _asyncToGenerator(function* () { let versions = yield (_Api || _load_Api()).default.versionsAsync(); let apkPath = _path.default.join(_apkCacheDirectory(), `Exponent-${versions.androidVersion}.apk`); if (yield (0, (_existsAsync || _load_existsAsync()).default)(apkPath)) { return apkPath; } yield (_Api || _load_Api()).default.downloadAsync(versions.androidUrl, _path.default.join(_apkCacheDirectory(), `Exponent-${versions.androidVersion}.apk`)); return apkPath; }); return function _downloadApkAsync() { return _ref7.apply(this, arguments); }; })(); let _installExpoAsync = (() => { var _ref8 = _asyncToGenerator(function* () { (_Logger || _load_Logger()).default.global.info(`Downloading latest version of Expo`); (_Logger || _load_Logger()).default.notifications.info({ code: (_NotificationCode || _load_NotificationCode()).default.START_LOADING }); let path = yield _downloadApkAsync(); (_Logger || _load_Logger()).default.notifications.info({ code: (_NotificationCode || _load_NotificationCode()).default.STOP_LOADING }); (_Logger || _load_Logger()).default.global.info(`Installing Expo on device`); (_Logger || _load_Logger()).default.notifications.info({ code: (_NotificationCode || _load_NotificationCode()).default.START_LOADING }); let result = yield _getAdbOutputAsync(['install', path]); (_Logger || _load_Logger()).default.notifications.info({ code: (_NotificationCode || _load_NotificationCode()).default.STOP_LOADING }); return result; }); return function _installExpoAsync() { return _ref8.apply(this, arguments); }; })(); let _uninstallExpoAsync = (() => { var _ref9 = _asyncToGenerator(function* () { (_Logger || _load_Logger()).default.global.info('Uninstalling Expo from Android device.'); return yield _getAdbOutputAsync(['uninstall', 'host.exp.exponent']); }); return function _uninstallExpoAsync() { return _ref9.apply(this, arguments); }; })(); let upgradeExpoAsync = exports.upgradeExpoAsync = (() => { var _ref10 = _asyncToGenerator(function* () { try { yield _assertDeviceReadyAsync(); yield _uninstallExpoAsync(); let installResult = yield _installExpoAsync(); if (installResult.status !== 0) { return false; } if (_lastUrl) { (_Logger || _load_Logger()).default.global.info(`Opening ${_lastUrl} in Expo.`); yield _getAdbOutputAsync(['shell', 'am', 'start', '-a', 'android.intent.action.VIEW', '-d', _lastUrl]); _lastUrl = null; } return true; } catch (e) { (_Logger || _load_Logger()).default.global.error(e.message); return false; } }); return function upgradeExpoAsync() { return _ref10.apply(this, arguments); }; })(); // Open Url let _assertDeviceReadyAsync = (() => { var _ref11 = _asyncToGenerator(function* () { const genymotionMessage = `https://developer.android.com/studio/run/device.html#developer-device-options. If you are using Genymotion go to Settings -> ADB, select "Use custom Android SDK tools", and point it at your Android SDK directory.`; if (!(yield _isDeviceAttachedAsync())) { throw new Error(`No Android device found. Please connect a device and follow the instructions here to enable USB debugging:\n${genymotionMessage}`); } if (!(yield _isDeviceAuthorizedAsync())) { throw new Error(`This computer is not authorized to debug the device. Please follow the instructions here to enable USB debugging:\n${genymotionMessage}`); } }); return function _assertDeviceReadyAsync() { return _ref11.apply(this, arguments); }; })(); let _openUrlAsync = (() => { var _ref12 = _asyncToGenerator(function* (url) { let output = yield _getAdbOutputAsync(['shell', 'am', 'start', '-a', 'android.intent.action.VIEW', '-d', url]); if (output.includes(CANT_START_ACTIVITY_ERROR)) { throw new Error(output.substring(output.indexOf('Error: '))); } return output; }); return function _openUrlAsync(_x2) { return _ref12.apply(this, arguments); }; })(); let openUrlAsync = (() => { var _ref13 = _asyncToGenerator(function* (url, isDetached = false) { try { yield _assertDeviceReadyAsync(); let installedExpo = false; if (!isDetached && !(yield _isExpoInstalledAsync())) { yield _installExpoAsync(); installedExpo = true; } if (!isDetached) { _lastUrl = url; _checkExpoUpToDateAsync(); // let this run in background } (_Logger || _load_Logger()).default.global.info(`Opening on Android device`); try { yield _openUrlAsync(url); } catch (e) { if (isDetached) { e.message = `Error running app. Have you installed the app already using Android Studio? Since you are detached you must build manually. ${e.message}`; } else { e.message = `Error running app. ${e.message}`; } throw e; } (_Analytics || _load_Analytics()).logEvent('Open Url on Device', { platform: 'android', installedExpo }); } catch (e) { e.message = `Error running adb: ${e.message}`; throw e; } }); return function openUrlAsync(_x3) { return _ref13.apply(this, arguments); }; })(); let openProjectAsync = exports.openProjectAsync = (() => { var _ref14 = _asyncToGenerator(function* (projectRoot) { try { yield startAdbReverseAsync(projectRoot); let projectUrl = yield (_UrlUtils || _load_UrlUtils()).constructManifestUrlAsync(projectRoot); let { exp } = yield (_ProjectUtils || _load_ProjectUtils()).readConfigJsonAsync(projectRoot); yield openUrlAsync(projectUrl, !!exp.isDetached); return { success: true, error: null }; } catch (e) { (_Logger || _load_Logger()).default.global.error(`Couldn't start project on Android: ${e.message}`); return { success: false, error: e }; } }); return function openProjectAsync(_x4) { return _ref14.apply(this, arguments); }; })(); // Adb reverse let startAdbReverseAsync = exports.startAdbReverseAsync = (() => { var _ref15 = _asyncToGenerator(function* (projectRoot) { const packagerInfo = yield (_ProjectSettings || _load_ProjectSettings()).readPackagerInfoAsync(projectRoot); const expRc = yield (_ProjectUtils || _load_ProjectUtils()).readExpRcAsync(projectRoot); const userDefinedAdbReversePorts = expRc.extraAdbReversePorts || []; let adbReversePorts = [packagerInfo.packagerPort, packagerInfo.expoServerPort, ...userDefinedAdbReversePorts]; for (let port of adbReversePorts) { if (!(yield adbReverse(port))) { return false; } } return true; }); return function startAdbReverseAsync(_x5) { return _ref15.apply(this, arguments); }; })(); let stopAdbReverseAsync = exports.stopAdbReverseAsync = (() => { var _ref16 = _asyncToGenerator(function* (projectRoot) { const packagerInfo = yield (_ProjectSettings || _load_ProjectSettings()).readPackagerInfoAsync(projectRoot); const expRc = yield (_ProjectUtils || _load_ProjectUtils()).readExpRcAsync(projectRoot); const userDefinedAdbReversePorts = expRc.extraAdbReversePorts || []; let adbReversePorts = [packagerInfo.packagerPort, packagerInfo.expoServerPort, ...userDefinedAdbReversePorts]; for (let port of adbReversePorts) { yield adbReverseRemove(port); } }); return function stopAdbReverseAsync(_x6) { return _ref16.apply(this, arguments); }; })(); let adbReverse = (() => { var _ref17 = _asyncToGenerator(function* (port) { if (!(yield _isDeviceAuthorizedAsync())) { return false; } try { yield _getAdbOutputAsync(['reverse', `tcp:${port}`, `tcp:${port}`]); return true; } catch (e) { (_Logger || _load_Logger()).default.global.warn(`Couldn't adb reverse: ${e.message}`); return false; } }); return function adbReverse(_x7) { return _ref17.apply(this, arguments); }; })(); let adbReverseRemove = (() => { var _ref18 = _asyncToGenerator(function* (port) { if (!(yield _isDeviceAuthorizedAsync())) { return false; } try { yield _getAdbOutputAsync(['reverse', '--remove', `tcp:${port}`]); return true; } catch (e) { // Don't send this to warn because we call this preemptively sometimes (_Logger || _load_Logger()).default.global.debug(`Couldn't adb reverse remove: ${e.message}`); return false; } }); return function adbReverseRemove(_x8) { return _ref18.apply(this, arguments); }; })(); exports.isPlatformSupported = isPlatformSupported; var _lodash; function _load_lodash() { return _lodash = _interopRequireDefault(require('lodash')); } var _spawnAsync; function _load_spawnAsync() { return _spawnAsync = _interopRequireDefault(require('@expo/spawn-async')); } var _existsAsync; function _load_existsAsync() { return _existsAsync = _interopRequireDefault(require('exists-async')); } var _mkdirp; function _load_mkdirp() { return _mkdirp = _interopRequireDefault(require('mkdirp')); } var _path = _interopRequireDefault(require('path')); var _semver; function _load_semver() { return _semver = _interopRequireDefault(require('semver')); } var _Analytics; function _load_Analytics() { return _Analytics = _interopRequireWildcard(require('./Analytics')); } var _Binaries; function _load_Binaries() { return _Binaries = _interopRequireWildcard(require('./Binaries')); } var _Api; function _load_Api() { return _Api = _interopRequireDefault(require('./Api')); } var _Logger; function _load_Logger() { return _Logger = _interopRequireDefault(require('./Logger')); } var _NotificationCode; function _load_NotificationCode() { return _NotificationCode = _interopRequireDefault(require('./NotificationCode')); } var _ProjectUtils; function _load_ProjectUtils() { return _ProjectUtils = _interopRequireWildcard(require('./project/ProjectUtils')); } var _ProjectSettings; function _load_ProjectSettings() { return _ProjectSettings = _interopRequireWildcard(require('./ProjectSettings')); } var _UserSettings; function _load_UserSettings() { return _UserSettings = _interopRequireDefault(require('./UserSettings')); } var _UrlUtils; function _load_UrlUtils() { return _UrlUtils = _interopRequireWildcard(require('./UrlUtils')); } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } let _lastUrl = null; const BEGINNING_OF_ADB_ERROR_MESSAGE = 'error: '; const CANT_START_ACTIVITY_ERROR = 'Activity not started, unable to resolve Intent'; function isPlatformSupported() { return process.platform === 'darwin' || process.platform === 'win32' || process.platform === 'linux'; } function _apkCacheDirectory() { let dotExpoHomeDirectory = (_UserSettings || _load_UserSettings()).default.dotExpoHomeDirectory(); let dir = _path.default.join(dotExpoHomeDirectory, 'android-apk-cache'); (_mkdirp || _load_mkdirp()).default.sync(dir); return dir; } //# sourceMappingURL=__sourcemaps__/Android.js.map