UNPKG

nativescript

Version:

Command-line interface for building NativeScript projects

181 lines 8.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AndroidEmulatorServices = void 0; const constants_1 = require("../../constants"); const helpers_1 = require("../../helpers"); const os_1 = require("os"); const _ = require("lodash"); const constants_2 = require("../../../constants"); const yok_1 = require("../../yok"); const semver = require("semver"); class AndroidEmulatorServices { constructor($androidGenymotionService, $androidVirtualDeviceService, $adb, $childProcess, $emulatorHelper, $logger, $utils) { this.$androidGenymotionService = $androidGenymotionService; this.$androidVirtualDeviceService = $androidVirtualDeviceService; this.$adb = $adb; this.$childProcess = $childProcess; this.$emulatorHelper = $emulatorHelper; this.$logger = $logger; this.$utils = $utils; } async getEmulatorImages() { const adbDevicesOutput = await this.$adb.getDevicesSafe(); const avdAvailableEmulatorsOutput = await this.$androidVirtualDeviceService.getEmulatorImages(adbDevicesOutput); const genyAvailableDevicesOutput = await this.$androidGenymotionService.getEmulatorImages(adbDevicesOutput); const devices = _.concat(avdAvailableEmulatorsOutput.devices, genyAvailableDevicesOutput.devices).filter((item) => !!item); return { devices, errors: avdAvailableEmulatorsOutput.errors.concat(genyAvailableDevicesOutput.errors), }; } async getRunningEmulatorIds() { const adbDevicesOutput = await this.$adb.getDevicesSafe(); const avds = await this.$androidVirtualDeviceService.getRunningEmulatorIds(adbDevicesOutput); const genies = await this.$androidGenymotionService.getRunningEmulatorIds(adbDevicesOutput); return avds.concat(genies); } async getRunningEmulatorName(emulatorId) { let result = await this.$androidVirtualDeviceService.getRunningEmulatorName(emulatorId); if (!result) { result = await this.$androidGenymotionService.getRunningEmulatorName(emulatorId); } return result; } async getRunningEmulatorImageIdentifier(emulatorId) { let result = await this.$androidVirtualDeviceService.getRunningEmulatorImageIdentifier(emulatorId); if (!result) { result = await this.$androidGenymotionService.getRunningEmulatorImageIdentifier(emulatorId); } return result; } async startEmulator(options) { const output = await this.startEmulatorCore(options); let bootToCompleteOutput = null; if (output && output.runningEmulator) { bootToCompleteOutput = await this.waitForEmulatorBootToComplete(output.runningEmulator, output.endTimeEpoch, options.timeout); } return { errors: ((output && output.errors) || []).concat((bootToCompleteOutput && bootToCompleteOutput.errors) || []), }; } detach(deviceInfo) { this.$androidVirtualDeviceService.detach(deviceInfo); } async startEmulatorCore(options) { const timeout = options.timeout || constants_1.AndroidVirtualDevice.TIMEOUT_SECONDS; const endTimeEpoch = (0, helpers_1.getCurrentEpochTime)() + this.$utils.getMilliSecondsTimeout(timeout); const availableEmulators = (await this.getEmulatorImages()).devices; let emulator = this.$emulatorHelper.getEmulatorByStartEmulatorOptions(options, availableEmulators); if (!emulator && !options.emulatorIdOrName && !options.imageIdentifier && !options.emulator) { emulator = this.getBestFit(availableEmulators); } if (!emulator) { return { runningEmulator: null, errors: [ `No emulator image available for device identifier '${options.emulatorIdOrName || options.imageIdentifier}'.`, ], endTimeEpoch, }; } if (emulator.errorHelp) { return { runningEmulator: null, errors: [emulator.errorHelp], endTimeEpoch, }; } this.spawnEmulator(emulator); const isInfiniteWait = this.$utils.getMilliSecondsTimeout(timeout) === 0; let hasTimeLeft = (0, helpers_1.getCurrentEpochTime)() < endTimeEpoch; while (hasTimeLeft || isInfiniteWait) { const emulators = (await this.getEmulatorImages()).devices; const newEmulator = _.find(emulators, (e) => e.imageIdentifier === emulator.imageIdentifier); if (newEmulator && this.$emulatorHelper.isEmulatorRunning(newEmulator)) { return { runningEmulator: newEmulator, errors: [], endTimeEpoch, }; } await (0, helpers_1.sleep)(10000); // the emulator definitely takes its time to wake up hasTimeLeft = (0, helpers_1.getCurrentEpochTime)() < endTimeEpoch; } if (!hasTimeLeft && !isInfiniteWait) { return { runningEmulator: null, errors: [constants_1.AndroidVirtualDevice.UNABLE_TO_START_EMULATOR_MESSAGE], endTimeEpoch, }; } } spawnEmulator(emulator) { let pathToEmulatorExecutable = null; let startEmulatorArgs = null; if (emulator.vendor === constants_1.AndroidVirtualDevice.AVD_VENDOR_NAME) { pathToEmulatorExecutable = this.$androidVirtualDeviceService .pathToEmulatorExecutable; startEmulatorArgs = this.$androidVirtualDeviceService.startEmulatorArgs(emulator.imageIdentifier); } else if (emulator.vendor === constants_1.AndroidVirtualDevice.GENYMOTION_VENDOR_NAME) { pathToEmulatorExecutable = this.$androidGenymotionService .pathToEmulatorExecutable; startEmulatorArgs = this.$androidGenymotionService.startEmulatorArgs(emulator.imageIdentifier); } this.$logger.info(`Starting Android emulator with image ${emulator.imageIdentifier}`); const childProcess = this.$childProcess.spawn(pathToEmulatorExecutable, startEmulatorArgs, { stdio: "ignore", detached: true }); childProcess.unref(); childProcess.on("error", (err) => { this.$logger.trace(`Error when starting emulator. More info: ${err}`); }); } getBestFit(emulators) { let best = null; for (const emulator of emulators) { const currentVersion = emulator.version && semver.coerce(emulator.version); const currentBestVersion = best && best.version && semver.coerce(best.version); if (!best || (currentVersion && currentBestVersion && semver.gt(currentVersion, currentBestVersion))) { best = emulator; } } const minVersion = semver.coerce(constants_1.AndroidVirtualDevice.MIN_ANDROID_VERSION); const bestVersion = best && best.version && semver.coerce(best.version); return bestVersion && semver.gte(bestVersion, minVersion) ? best : null; } async waitForEmulatorBootToComplete(emulator, endTimeEpoch, timeout) { this.$logger.info("Waiting for emulator device initialization...", { [constants_2.LoggerConfigData.skipNewLine]: true, }); const isInfiniteWait = this.$utils.getMilliSecondsTimeout(timeout || constants_1.AndroidVirtualDevice.TIMEOUT_SECONDS) === 0; while ((0, helpers_1.getCurrentEpochTime)() < endTimeEpoch || isInfiniteWait) { const isEmulatorBootCompleted = await this.isEmulatorBootCompleted(emulator.identifier); if (isEmulatorBootCompleted) { this.$logger.info(os_1.EOL, { [constants_2.LoggerConfigData.skipNewLine]: true }); return { runningEmulator: emulator, errors: [], }; } this.$logger.info(".", { [constants_2.LoggerConfigData.skipNewLine]: true }); await (0, helpers_1.sleep)(10000); } return { runningEmulator: null, errors: [constants_1.AndroidVirtualDevice.UNABLE_TO_START_EMULATOR_MESSAGE], }; } async isEmulatorBootCompleted(emulatorId) { const output = await this.$adb.getPropertyValue(emulatorId, "dev.bootcomplete"); const matches = output.match("1"); return matches && matches.length > 0; } } exports.AndroidEmulatorServices = AndroidEmulatorServices; yok_1.injector.register("androidEmulatorServices", AndroidEmulatorServices); //# sourceMappingURL=android-emulator-services.js.map