nativescript
Version:
Command-line interface for building NativeScript projects
149 lines • 7.08 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.AndroidDevice = void 0;
const device_android_debug_bridge_1 = require("./device-android-debug-bridge");
const applicationManagerPath = require("./android-application-manager");
const fileSystemPath = require("./android-device-file-system");
const constants = require("../../constants");
const _ = require("lodash");
const decorators_1 = require("../../decorators");
const constants_1 = require("../../../constants");
class AndroidDevice {
constructor(identifier, status, $androidEmulatorServices, $logger, $devicePlatformsConstants, $logcatHelper, $injector) {
this.identifier = identifier;
this.status = status;
this.$androidEmulatorServices = $androidEmulatorServices;
this.$logger = $logger;
this.$devicePlatformsConstants = $devicePlatformsConstants;
this.$logcatHelper = $logcatHelper;
this.$injector = $injector;
}
async init() {
this.adb = this.$injector.resolve(device_android_debug_bridge_1.DeviceAndroidDebugBridge, {
identifier: this.identifier,
});
this.applicationManager = this.$injector.resolve(applicationManagerPath.AndroidApplicationManager, { adb: this.adb, identifier: this.identifier });
this.fileSystem = this.$injector.resolve(fileSystemPath.AndroidDeviceFileSystem, { adb: this.adb });
let details = await this.getDeviceDetails(["getprop"]);
if (!details || !details.name) {
// In older CLI versions we are calling cat /system/build.prop to get details.
// Keep this logic for compatibility and possibly for devices for which getprop is not working
details = await this.getDeviceDetails(["cat", "/system/build.prop"]);
}
this.$logger.trace(details);
const adbStatusInfo = AndroidDevice.ADB_DEVICE_STATUS_INFO[this.status];
const type = await this.getType();
let version = details.release;
if (version && version.toLowerCase() === "q") {
version = "10.0.0";
}
this.deviceInfo = {
identifier: this.identifier,
displayName: details.name,
model: details.model,
version,
vendor: details.brand,
platform: this.$devicePlatformsConstants.Android,
status: adbStatusInfo ? adbStatusInfo.deviceStatus : this.status,
errorHelp: adbStatusInfo ? adbStatusInfo.errorHelp : "Unknown status",
isTablet: this.getIsTablet(details),
type,
connectionTypes: [constants_1.DeviceConnectionType.Local],
};
this.deviceInfo.connectionTypes = this.isEmulator
? [constants_1.DeviceConnectionType.Local]
: [constants_1.DeviceConnectionType.USB];
if (this.isEmulator) {
this.deviceInfo.displayName = await this.$androidEmulatorServices.getRunningEmulatorName(this.identifier);
this.deviceInfo.imageIdentifier = await this.$androidEmulatorServices.getRunningEmulatorImageIdentifier(this.identifier);
}
this.$logger.trace(this.deviceInfo);
}
get isEmulator() {
return this.deviceInfo.type === constants.DeviceTypes.Emulator;
}
get isOnlyWiFiConnected() {
return false;
}
async openDeviceLogStream() {
if (this.deviceInfo.status === constants.CONNECTED_STATUS) {
await this.$logcatHelper.start({
deviceIdentifier: this.identifier,
keepSingleProcess: true,
});
}
}
detach() {
if (this.isEmulator) {
this.$androidEmulatorServices.detach(this.deviceInfo);
}
}
async getDeviceDetails(shellCommandArgs) {
const parsedDetails = {};
this.$logger.trace(`Trying to get information for Android device. Command is: ${shellCommandArgs}`);
try {
const details = await this.adb.executeShellCommand(shellCommandArgs);
details.split(/\r?\n|\r/).forEach((value) => {
// sample line is "ro.build.version.release=4.4" in /system/build.prop
// sample line from getprop is: [ro.build.version.release]: [6.0]
// NOTE: some props do not have value: [ro.build.version.base_os]: []
const match = /(?:\[?ro\.build\.version|ro\.product|ro\.build)\.(.+?)]?(?:\:|=)(?:\s*?\[)?(.*?)]?$/.exec(value);
if (match) {
parsedDetails[match[1]] = match[2];
}
});
}
catch (err) {
this.$logger.trace(`Error while getting details from Android device. Command is: ${shellCommandArgs}. Error is: ${err}`);
}
this.$logger.trace(parsedDetails);
return parsedDetails;
}
getIsTablet(details) {
//version 3.x.x (also known as Honeycomb) is a tablet only version
return (details &&
(_.startsWith(details.release, "3.") ||
_.includes((details.characteristics || "").toLowerCase(), "tablet")));
}
async getType() {
const runningEmulatorIds = await this.$androidEmulatorServices.getRunningEmulatorIds();
if (_.find(runningEmulatorIds, (emulatorId) => emulatorId === this.identifier)) {
return constants.DeviceTypes.Emulator;
}
return constants.DeviceTypes.Device;
}
}
exports.AndroidDevice = AndroidDevice;
// http://stackoverflow.com/questions/31178195/what-does-adb-device-status-mean
AndroidDevice.ADB_DEVICE_STATUS_INFO = {
device: {
errorHelp: null,
deviceStatus: constants.CONNECTED_STATUS,
},
offline: {
errorHelp: "The device instance is not connected to adb or is not responding.",
deviceStatus: constants.UNREACHABLE_STATUS,
},
unauthorized: {
errorHelp: "Allow USB Debugging on your device.",
deviceStatus: constants.UNREACHABLE_STATUS,
},
recovery: {
errorHelp: "Your device is in recovery mode. This mode is used to recover your phone when it is broken or to install custom roms.",
deviceStatus: constants.UNREACHABLE_STATUS,
},
"no permissions": {
errorHelp: "Insufficient permissions to communicate with the device.",
deviceStatus: constants.UNREACHABLE_STATUS,
},
};
__decorate([
(0, decorators_1.cache)()
], AndroidDevice.prototype, "init", null);
//# sourceMappingURL=android-device.js.map