490 lines
15 KiB
JavaScript
490 lines
15 KiB
JavaScript
|
'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
|