eas-cli
Version:
EAS command line tool
118 lines (117 loc) • 5.07 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.waitForEmulatorToBeBootedAsync = exports.isEmulatorBootedAsync = exports.getFirstRunningEmulatorAsync = exports.getRunningEmulatorsAsync = exports.getAdbNameForDeviceIdAsync = exports.sanitizeAdbDeviceName = exports.getAdbExecutableAsync = exports.adbAsync = void 0;
const tslib_1 = require("tslib");
const spawn_async_1 = tslib_1.__importDefault(require("@expo/spawn-async"));
const os_1 = tslib_1.__importDefault(require("os"));
const path_1 = tslib_1.__importDefault(require("path"));
const sdk_1 = require("./sdk");
const log_1 = tslib_1.__importDefault(require("../../log"));
const filter_1 = require("../../utils/expodash/filter");
const promise_1 = require("../../utils/promise");
const BEGINNING_OF_ADB_ERROR_MESSAGE = 'error: ';
async function adbAsync(...args) {
const adbExecutable = await getAdbExecutableAsync();
try {
return await (0, spawn_async_1.default)(adbExecutable, args);
}
catch (error) {
let errorMessage = (error.stderr || error.stdout || error.message).trim();
if (errorMessage.startsWith(BEGINNING_OF_ADB_ERROR_MESSAGE)) {
errorMessage = errorMessage.substring(BEGINNING_OF_ADB_ERROR_MESSAGE.length);
}
error.message = errorMessage;
throw error;
}
}
exports.adbAsync = adbAsync;
async function getAdbExecutableAsync() {
const sdkRoot = await (0, sdk_1.getAndroidSdkRootAsync)();
if (!sdkRoot) {
log_1.default.debug('Failed to resolve the Android SDK path, falling back to global adb executable');
return 'adb';
}
return path_1.default.join(sdkRoot, 'platform-tools/adb');
}
exports.getAdbExecutableAsync = getAdbExecutableAsync;
function sanitizeAdbDeviceName(deviceName) {
return deviceName.trim().split(/[\r\n]+/)[0];
}
exports.sanitizeAdbDeviceName = sanitizeAdbDeviceName;
/**
* Return the Emulator name for an emulator ID, this can be used to determine if an emulator is booted.
*
* @param devicePid a value like `emulator-5554` from `abd devices`
*/
async function getAdbNameForDeviceIdAsync(emulatorPid) {
const { stdout } = await adbAsync('-s', emulatorPid, 'emu', 'avd', 'name');
if (stdout.match(/could not connect to TCP port .*: Connection refused/)) {
// Can also occur when the emulator does not exist.
throw new Error(`Emulator not found: ${stdout}`);
}
return sanitizeAdbDeviceName(stdout) ?? null;
}
exports.getAdbNameForDeviceIdAsync = getAdbNameForDeviceIdAsync;
// TODO: This is very expensive for some operations.
async function getRunningEmulatorsAsync() {
const { stdout } = await adbAsync('devices', '-l');
const splitItems = stdout.trim().split(os_1.default.EOL);
const attachedDevices = splitItems
// First line is `"List of devices attached"`, remove it
.slice(1, splitItems.length)
.map(line => {
// unauthorized: ['FA8251A00719', 'unauthorized', 'usb:338690048X', 'transport_id:5']
// authorized: ['FA8251A00719', 'device', 'usb:336592896X', 'product:walleye', 'model:Pixel_2', 'device:walleye', 'transport_id:4']
// emulator: ['emulator-5554', 'offline', 'transport_id:1']
const [pid] = line.split(' ').filter(filter_1.truthy);
const type = line.includes('emulator') ? 'emulator' : 'device';
return { pid, type };
})
.filter(({ pid, type }) => !!pid && type === 'emulator');
const devicePromises = attachedDevices.map(async ({ pid }) => {
const name = (await getAdbNameForDeviceIdAsync(pid)) ?? '';
return {
pid,
name,
};
});
return await Promise.all(devicePromises);
}
exports.getRunningEmulatorsAsync = getRunningEmulatorsAsync;
async function getFirstRunningEmulatorAsync() {
const emulators = await getRunningEmulatorsAsync();
return emulators[0] ?? null;
}
exports.getFirstRunningEmulatorAsync = getFirstRunningEmulatorAsync;
/**
* Returns true if emulator is booted
*
* @param emulatorPid
*/
async function isEmulatorBootedAsync(emulatorPid) {
try {
const { stdout } = await adbAsync('-s', emulatorPid, 'shell', 'getprop', 'sys.boot_completed');
if (stdout.trim() === '1') {
return true;
}
return false;
}
catch {
return false;
}
}
exports.isEmulatorBootedAsync = isEmulatorBootedAsync;
async function waitForEmulatorToBeBootedAsync(maxWaitTimeMs, intervalMs) {
log_1.default.newLine();
log_1.default.log('Waiting for the Android emulator to start...');
const startTime = Date.now();
while (Date.now() - startTime < maxWaitTimeMs) {
const emulator = await getFirstRunningEmulatorAsync();
if (emulator?.pid && (await isEmulatorBootedAsync(emulator.pid))) {
return emulator;
}
await (0, promise_1.sleepAsync)(intervalMs);
}
throw new Error('Timed out waiting for the Android emulator to start.');
}
exports.waitForEmulatorToBeBootedAsync = waitForEmulatorToBeBootedAsync;
;