nativescript
Version:
Command-line interface for building NativeScript projects
189 lines • 9.23 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AndroidGenymotionService = void 0;
const constants_1 = require("../../../constants");
const helpers_1 = require("../../../helpers");
const os_1 = require("os");
const path = require("path");
const _ = require("lodash");
const os_2 = require("os");
const decorators_1 = require("../../../decorators");
const constants_2 = require("../../../../constants");
const yok_1 = require("../../../yok");
class AndroidGenymotionService {
constructor($adb, $childProcess, $devicePlatformsConstants, $emulatorHelper, $fs, $logger, $virtualBoxService) {
this.$adb = $adb;
this.$childProcess = $childProcess;
this.$devicePlatformsConstants = $devicePlatformsConstants;
this.$emulatorHelper = $emulatorHelper;
this.$fs = $fs;
this.$logger = $logger;
this.$virtualBoxService = $virtualBoxService;
}
async getEmulatorImages(adbDevicesOutput) {
const availableEmulatorsOutput = await this.getEmulatorImagesCore();
const runningEmulatorIds = await this.getRunningEmulatorIds(adbDevicesOutput);
const runningEmulators = await (0, helpers_1.settlePromises)(_.map(runningEmulatorIds, (emulatorId) => this.getRunningEmulatorData(emulatorId, availableEmulatorsOutput.devices)));
const devices = availableEmulatorsOutput.devices.map((emulator) => this.$emulatorHelper.getEmulatorByImageIdentifier(emulator.imageIdentifier, runningEmulators) || emulator);
return {
devices,
errors: availableEmulatorsOutput.errors,
};
}
async getRunningEmulatorIds(adbDevicesOutput) {
const results = await Promise.all(_(adbDevicesOutput)
.filter((r) => !r.match(constants_1.AndroidVirtualDevice.RUNNING_AVD_EMULATOR_REGEX))
.map(async (row) => {
const match = row.match(/^(.+?)\s+device$/);
if (match && match[1]) {
// possible genymotion emulator
const emulatorId = match[1];
const result = (await this.isGenymotionEmulator(emulatorId))
? emulatorId
: undefined;
return Promise.resolve(result);
}
return Promise.resolve(undefined);
})
.value());
return _(results)
.filter((r) => !!r)
.map((r) => r.toString())
.value();
}
get pathToEmulatorExecutable() {
const searchPaths = this.playerSearchPaths[process.platform];
const searchPath = _.find(searchPaths, (sPath) => this.$fs.exists(sPath));
return searchPath || "player";
}
startEmulatorArgs(imageIdentifier) {
return ["--vm-name", imageIdentifier];
}
async getEmulatorImagesCore() {
const output = await this.$virtualBoxService.listVms();
if (output.error) {
return { devices: [], errors: output.error ? [output.error] : [] };
}
const devices = await this.parseListVmsOutput(output.vms);
return { devices, errors: [] };
}
async getRunningEmulatorName(emulatorId) {
const output = await this.$adb.getPropertyValue(emulatorId, "ro.product.model");
this.$logger.trace(output);
return _.first(output.split(os_1.EOL)).trim();
}
async getRunningEmulatorImageIdentifier(emulatorId) {
const adbDevices = await this.$adb.getDevicesSafe();
const emulatorImages = (await this.getEmulatorImages(adbDevices)).devices;
const emulator = await this.getRunningEmulatorData(emulatorId, emulatorImages);
return emulator ? emulator.imageIdentifier : null;
}
async getRunningEmulatorData(runningEmulatorId, availableEmulators) {
const emulatorName = await this.getRunningEmulatorName(runningEmulatorId);
const runningEmulator = this.$emulatorHelper.getEmulatorByIdOrName(emulatorName, availableEmulators);
if (!runningEmulator) {
return null;
}
this.$emulatorHelper.setRunningAndroidEmulatorProperties(runningEmulatorId, runningEmulator);
return runningEmulator;
}
// https://wiki.appcelerator.org/display/guides2/Installing+Genymotion
get playerSearchPaths() {
return {
darwin: [
"/Applications/Genymotion.app/Contents/MacOS/player.app/Contents/MacOS/player",
"/Applications/Genymotion.app/Contents/MacOS/player",
],
linux: [path.join((0, os_2.homedir)(), "genymotion", "player")],
win32: [
`${process.env["PROGRAMFILES"]}\\Genymobile\\Genymotion\\player.exe`,
`${process.env["PROGRAMFILES(X86)"]}\\Genymobile\\Genymotion\\player.exe`,
],
};
}
async parseListVmsOutput(vms) {
const configurationError = await this.getConfigurationError();
const devices = [];
for (const vm of vms) {
try {
const output = await this.$virtualBoxService.enumerateGuestProperties(vm.id);
if (output &&
output.properties &&
output.properties.indexOf("genymotion") !== -1) {
devices.push(this.convertToDeviceInfo(output.properties, vm.id, vm.name, output.error, configurationError));
}
}
catch (err) {
this.$logger.trace(`Error while parsing vm ${vm.id}`);
}
}
return devices;
}
convertToDeviceInfo(output, id, name, error, configurationError) {
return {
identifier: null,
imageIdentifier: id,
displayName: name,
model: name,
version: this.getSdkVersion(output),
vendor: constants_1.AndroidVirtualDevice.GENYMOTION_VENDOR_NAME,
status: constants_1.NOT_RUNNING_EMULATOR_STATUS,
errorHelp: [configurationError, error].filter((item) => !!item).join(os_1.EOL) || null,
isTablet: false, //TODO: Consider how to populate this correctly when the device is not running
type: constants_1.DeviceTypes.Emulator,
connectionTypes: [constants_2.DeviceConnectionType.Local],
platform: this.$devicePlatformsConstants.Android,
};
}
getSdkVersion(output) {
// Example -> Name: android_version, value: 6.0.0, timestamp: 1530090506102029000, flags:
const androidApiLevelRow = output
.split("\n")
.filter((row) => !!row)
.find((row) => row.indexOf("Name: android_version") !== -1);
return androidApiLevelRow.split(", ")[1].split("value: ")[1];
}
async isGenymotionEmulator(emulatorId) {
const manufacturer = await this.$adb.getPropertyValue(emulatorId, "ro.product.manufacturer");
if (manufacturer && manufacturer.match(/^Genymotion/i)) {
return true;
}
const buildProduct = await this.$adb.getPropertyValue(emulatorId, "ro.build.product");
if (buildProduct && _.includes(buildProduct.toLowerCase(), "vbox")) {
return true;
}
return false;
}
getConfigurationPlatformSpecficErrorMessage() {
const searchPaths = this.playerSearchPaths[process.platform];
return `Unable to find the Genymotion player in the following location${searchPaths.length > 1 ? "s" : ""}:
${searchPaths.join(os_1.EOL)}
In case you have installed Genymotion in a different location, please add the path to player executable to your PATH environment variable.`;
}
async getConfigurationError() {
const result = await this.$childProcess.trySpawnFromCloseEvent(this.pathToEmulatorExecutable, [], {}, { throwError: false });
// When player is spawned, it always prints message on stderr.
if (result &&
result.stderr &&
result.stderr.indexOf(constants_1.AndroidVirtualDevice.GENYMOTION_DEFAULT_STDERR_STRING) === -1) {
this.$logger.trace("Configuration error for Genymotion", result);
return this.getConfigurationPlatformSpecficErrorMessage();
}
return null;
}
}
exports.AndroidGenymotionService = AndroidGenymotionService;
__decorate([
(0, decorators_1.cache)()
], AndroidGenymotionService.prototype, "getConfigurationPlatformSpecficErrorMessage", null);
__decorate([
(0, decorators_1.cache)()
], AndroidGenymotionService.prototype, "getConfigurationError", null);
yok_1.injector.register("androidGenymotionService", AndroidGenymotionService);
//# sourceMappingURL=genymotion-service.js.map