@aiot-toolkit/emulator
Version:
vela emulator tool.
197 lines (186 loc) • 7.82 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _ColorConsole = _interopRequireDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
var _ILog = require("@aiot-toolkit/shared-utils/lib/interface/ILog");
var _adb = _interopRequireWildcard(require("@miwt/adb"));
var adbMiwt = _adb;
var _utils = require("../utils");
var _logcat = require("../vvd/logcat");
var _emulatorutil = require("../emulatorutil");
var _shared = require("../shared");
var _fs = _interopRequireDefault(require("fs"));
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
class CommonEmulatorInstance {
appDir = '/data/quickapp/app';
static emulatorStartedFlag = /quickapp_rpk_installer_init|rpk installer init done|booting completed|Boot completed/;
static appInstalledFlag = /InstallState_Finished|install finished/;
static appInstallFailedFlag = /uv_mq_read_cb: install prepare failed/;
static appUninstalledFlag = /uninstalled app/;
static appStartedFlag = /Start App loop/;
static isAppInstalled() {
const log = arguments.length <= 0 ? undefined : arguments[0];
return this.appInstalledFlag.test(log);
}
static isAppInstallFailed(log) {
return this.appInstallFailedFlag.test(log);
}
static isAppUninstalled(log, packageName) {
return new RegExp(this.appUninstalledFlag.source + ':\\s+' + packageName).test(log);
}
static isEmulatorStarted(log) {
return this.emulatorStartedFlag.test(log);
}
constructor(params) {
this.sn = `emulator-${params.serialPort}`;
this.vvdName = params.vvdName;
this.onStdout = params.onStdout || console.log;
this.onErrout = params.onErrout || console.error;
this.debugPort = params.debugPort || (0, _emulatorutil.getRunningVvdDebugPort)(this.vvdName);
if (params.customLogger) {
this.logger = msg => {
const prefix = _ColorConsole.default.createDefaultPrefix({
level: _ILog.Loglevel.INFO,
message: msg
});
params.customLogger(`${prefix[1]} ${msg?.trim()}`);
};
} else {
this.logger = _ColorConsole.default.info;
}
if (params.logcatProcess) {
this.logcatProcess = params.logcatProcess;
if (!params.stdoutReadline || !params.stderrReadline) {
const readlines = (0, _logcat.attachReadline)(params.logcatProcess, this.onStdout, this.onErrout);
params.stdoutReadline = readlines.stdoutReadline;
params.stderrReadline = readlines.stderrReadline;
params.dispose = readlines.dispose;
}
this.stdoutReadline = params.stdoutReadline;
this.stderrReadline = params.stderrReadline;
this.disposeReadlines = params.dispose;
} else {
const r = (0, _logcat.creatLogcat)(this.sn, this.onStdout, this.onErrout);
this.logcatProcess = r.logcatProcess;
this.stdoutReadline = r.stdoutReadline;
this.stderrReadline = r.stderrReadline;
this.disposeReadlines = r.dispose;
}
}
/** 安装应用,留给子类实现 */
/** 卸载应用,留给子类实现 */
/** 重启应用 */
/** 关闭应用 */
/** 启动应用,留给子类实现 */
/** 推送指定文件,返回推送结果 */
async push(sourcePath, targetPath) {
// 1. adb push应用的rpk
const pushCmd = `adb -s ${this.sn} push "${sourcePath}" ${targetPath}`;
this.logger(`Excuting: ${pushCmd}`);
const res = await adbMiwt.execAdbCmdAsync(pushCmd);
this.logger(`Push result: ${res}`);
return res;
}
async unzip(zipPath, targetPath) {
const unzipCmd = `adb -s ${this.sn} shell unzip -o ${zipPath} -d ${targetPath}`;
this.logger(`Excuting: ${unzipCmd}`);
const res = await adbMiwt.execAdbCmdAsync(unzipCmd);
this.logger(`Unzip result: ${res}`);
}
/** 推送指定 rpk */
async pushRpk(rpkPath, appPackageName) {
// 1. adb push应用的rpk
const targetPath = `${this.appDir}/${appPackageName}.rpk`;
await this.push(rpkPath, targetPath);
return targetPath;
}
/**
* 判断模拟器是否 ready
*/
async isConnected() {
return (0, _utils.tryRun)(async () => {
const devices = await adbMiwt.getAdbDevices();
this.logger(`adb devices: ${JSON.stringify(devices)}`);
const curDev = devices.find(t => t.sn === this.sn);
return curDev?.status === 'device';
}, 10, 500);
}
async pushAndInstall(rpkPath, appName) {
const targetPath = await this.pushRpk(rpkPath, appName);
try {
await this.install(targetPath, {
packageName: appName,
size: _fs.default.statSync(rpkPath).size
});
} catch (error) {
let timer;
if (error === _shared.RpkInstallFailedReason.Busy) {
this.logger('install process is busy, 3s later retry');
await new Promise((resolve, rejcet) => {
timer = setTimeout(() => {
this.pushAndInstall(rpkPath, appName).then(resolve).catch(rejcet);
}, 3000);
});
} else {
clearTimeout(timer);
throw error;
}
}
}
/** 关闭模拟器 */
poweroff() {
let timeout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10 * 1000;
return new Promise((resolve, reject) => {
const t = setTimeout(() => {
(0, _utils.killProcessByCmd)(this.vvdName).then(resolve).catch(e => {
reject(`poweroff ${this.vvdName} failed ${e}`);
});
}, timeout);
adbMiwt.execAdbCmdAsync(`adb -s ${this.sn} shell poweroff`).then(() => {
clearTimeout(t);
resolve();
}).catch(() => {
(0, _utils.killProcessByCmd)(this.vvdName).then(() => {
clearTimeout(t);
resolve();
}).catch(e => {
reject(`poweroff ${this.vvdName} failed ${e}`);
});
});
});
}
systemed() {
return adbMiwt.execAdbCmdAsync(`adb -s ${this.sn} shell systemd &`);
}
async getApplist() {
const cmd = `adb -s ${this.sn} shell ls ${this.appDir}`;
const dataStr = await (0, _adb.execAdbCmdAsync)(cmd);
if (dataStr) {
// 使用换行符分割字符串,得到数组
const appsArray = dataStr.replace(/\r\n/g, '\n').split('\n');
const cleanedAppsArray = appsArray.filter(item => item.endsWith('/')).map(item => item.trim().slice(0, -1));
return cleanedAppsArray;
}
return [];
}
/** 重启模拟器 */
async reboot() {
const rebootCmd = `adb -s ${this.sn} shell reboot`;
this.logger(`Excuting: ${rebootCmd}`);
await adbMiwt.execAdbCmdAsync(rebootCmd);
await this.isConnected();
if (this.logcatProcess.exitCode !== null) {
// 如果 logcat 进程被杀死,则重新创建
const r = (0, _logcat.creatLogcat)(this.sn, this.onStdout, this.onErrout);
this.logcatProcess = r.logcatProcess;
this.stdoutReadline = r.stdoutReadline;
this.stderrReadline = r.stderrReadline;
this.disposeReadlines = r.dispose;
}
}
}
var _default = exports.default = CommonEmulatorInstance;