@aiot-toolkit/emulator 2.0.2-beta.13 → 2.0.2-beta.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/avd/index.js +3 -3
- package/lib/emulatorutil/EmulatorCmd.d.ts +9 -0
- package/lib/emulatorutil/EmulatorCmd.js +226 -0
- package/lib/emulatorutil/EmulatorLog.d.ts +11 -0
- package/lib/emulatorutil/EmulatorLog.js +21 -0
- package/lib/{static → emulatorutil}/constants.js +2 -2
- package/lib/emulatorutil/index.d.ts +3 -0
- package/lib/emulatorutil/index.js +10 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/instance/common.js +17 -15
- package/lib/instance/dev.d.ts +10 -3
- package/lib/instance/dev.js +62 -128
- package/lib/instance/index.js +2 -2
- package/lib/instance/miwear.d.ts +10 -9
- package/lib/instance/miwear.js +60 -142
- package/lib/instance/pre.d.ts +4 -1
- package/lib/instance/pre.js +82 -1
- package/lib/instance/preDev.d.ts +4 -0
- package/lib/instance/preDev.js +39 -74
- package/lib/typing/Instance.d.ts +5 -1
- package/lib/typing/Instance.js +6 -0
- package/lib/utils/index.d.ts +1 -1
- package/lib/utils/index.js +7 -7
- package/package.json +9 -5
- /package/lib/{static → emulatorutil}/constants.d.ts +0 -0
package/lib/instance/miwear.js
CHANGED
|
@@ -35,16 +35,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
35
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
36
|
};
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
const
|
|
38
|
+
const ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
|
|
39
39
|
const adbMiwt = __importStar(require("@miwt/adb"));
|
|
40
40
|
const child_process_1 = require("child_process");
|
|
41
|
+
const readline_1 = __importDefault(require("readline"));
|
|
41
42
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
42
43
|
const os_1 = __importDefault(require("os"));
|
|
43
44
|
const path_1 = __importDefault(require("path"));
|
|
44
45
|
const ws_1 = __importStar(require("ws"));
|
|
46
|
+
const Instance_1 = require("../typing/Instance");
|
|
45
47
|
const utils_1 = require("../utils");
|
|
48
|
+
const emulatorutil_1 = require("../emulatorutil");
|
|
46
49
|
const common_1 = __importDefault(require("./common"));
|
|
47
|
-
const dayjs_1 = __importDefault(require("dayjs"));
|
|
48
50
|
const MAX_RECONNECT_COUNT = 8;
|
|
49
51
|
/**
|
|
50
52
|
* MiwearInstance
|
|
@@ -54,11 +56,8 @@ class MiwearInstance extends common_1.default {
|
|
|
54
56
|
constructor(params) {
|
|
55
57
|
super(params);
|
|
56
58
|
this.params = params;
|
|
57
|
-
this.
|
|
58
|
-
this.appPathInEmulator = '/data/quickapp/app';
|
|
59
|
+
this.appDir = '/data/quickapp/app';
|
|
59
60
|
this.reconnectCount = 0;
|
|
60
|
-
this.emulatorStartedFlag = /quickapp_rpk_installer_init|rpk installer init done/;
|
|
61
|
-
this.installBol = false;
|
|
62
61
|
}
|
|
63
62
|
/**
|
|
64
63
|
* 1. 启动模拟器
|
|
@@ -74,7 +73,7 @@ class MiwearInstance extends common_1.default {
|
|
|
74
73
|
// adb连接模拟器
|
|
75
74
|
const connected = yield this.isConnected();
|
|
76
75
|
if (connected) {
|
|
77
|
-
|
|
76
|
+
ColorConsole_1.default.info('### Emulator ### Goldfish emulator connected successfully');
|
|
78
77
|
// 如果是首次启动,创建server端监听事件
|
|
79
78
|
if (this.isFirstStart && this.startOptions.serverPort) {
|
|
80
79
|
yield this.createWebsockeServer();
|
|
@@ -85,7 +84,7 @@ class MiwearInstance extends common_1.default {
|
|
|
85
84
|
}
|
|
86
85
|
else {
|
|
87
86
|
const msg = '### Emulator ### Failed to connect emulator, please check whether the adb is normal';
|
|
88
|
-
|
|
87
|
+
ColorConsole_1.default.throw(msg);
|
|
89
88
|
throw new Error(msg);
|
|
90
89
|
}
|
|
91
90
|
});
|
|
@@ -101,120 +100,58 @@ class MiwearInstance extends common_1.default {
|
|
|
101
100
|
* @returns
|
|
102
101
|
*/
|
|
103
102
|
startGoldfish(options) {
|
|
104
|
-
var _a;
|
|
105
103
|
return __awaiter(this, void 0, void 0, function* () {
|
|
106
|
-
const {
|
|
107
|
-
// 获取emulator bin的绝对路径
|
|
108
|
-
const emulatorBin = this.getEmulatorBinPath();
|
|
109
|
-
shared_utils_1.ColorConsole.log(`### Emulator ### emulator path: ${emulatorBin}`);
|
|
110
|
-
// 获取vela镜像的绝对路径
|
|
111
|
-
const avdInfo = this.velaAvdCls.getVelaAvdInfo(avdName);
|
|
112
|
-
const { avdArch, avdImagePath, customImagePath } = avdInfo;
|
|
113
|
-
shared_utils_1.ColorConsole.log(`### Emulator ### adb port: ${options.adbPort}`);
|
|
114
|
-
if (!avdImagePath) {
|
|
115
|
-
return shared_utils_1.ColorConsole.throw(`### Emulator ### Unable to find vela image via avd`);
|
|
116
|
-
}
|
|
117
|
-
const nuttxBinPath = path_1.default.resolve(customImagePath || avdImagePath, 'nuttx');
|
|
118
|
-
shared_utils_1.ColorConsole.log(`### Emulator ### nuttx path: ${nuttxBinPath}`);
|
|
119
|
-
// 端口映射
|
|
120
|
-
let portMappingStr = ``;
|
|
121
|
-
if (devtool) {
|
|
122
|
-
portMappingStr += `-network-user-mode-options hostfwd=tcp:127.0.0.1:${options.debugPort}-10.0.2.15:101`;
|
|
123
|
-
}
|
|
124
|
-
// 设备挂载节点
|
|
125
|
-
const systemImageBin = path_1.default.resolve(avdImagePath, 'vela_resource.bin'); // 只读
|
|
126
|
-
const dataImageBin = path_1.default.resolve(avdImagePath, 'vela_data.bin'); // 可读可写
|
|
127
|
-
const coreBin = path_1.default.resolve(avdImagePath, 'coredump.core'); // 只读
|
|
128
|
-
// 复制可写文件到AVD目录下(多模拟器实例时需要)
|
|
129
|
-
const dataImageBinInAvd = path_1.default.join(this.avdHome, `${avdName}.avd`, 'vela_data.bin');
|
|
130
|
-
if (!fs_extra_1.default.existsSync(dataImageBinInAvd)) {
|
|
131
|
-
// vela_data.bin不存在时直接copy
|
|
132
|
-
fs_extra_1.default.copyFileSync(dataImageBin, dataImageBinInAvd);
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
// vela_data.bin存在时,如果.export里的时间晚于avd里的时候,说明更新了镜像,需要重新copy
|
|
136
|
-
const statsInAvd = fs_extra_1.default.statSync(dataImageBinInAvd);
|
|
137
|
-
const stats = fs_extra_1.default.statSync(dataImageBin);
|
|
138
|
-
if ((0, dayjs_1.default)(stats.mtime).isAfter(statsInAvd.mtime)) {
|
|
139
|
-
fs_extra_1.default.copyFileSync(dataImageBin, dataImageBinInAvd);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
// 挂载节点配置,只读文件加入read-only标识
|
|
143
|
-
const imageMountStr = `-drive index=0,id=system,if=none,format=raw,file=${systemImageBin},read-only \
|
|
144
|
-
-device virtio-blk-device,bus=virtio-mmio-bus.0,drive=system \
|
|
145
|
-
-drive index=1,id=userdata,if=none,format=raw,file=${dataImageBinInAvd} \
|
|
146
|
-
-device virtio-blk-device,bus=virtio-mmio-bus.1,drive=userdata \
|
|
147
|
-
-drive index=2,id=vendor,if=none,format=raw,file=${coreBin},read-only \
|
|
148
|
-
-device virtio-blk-device,bus=virtio-mmio-bus.4,drive=vendor \
|
|
149
|
-
-device virtio-snd,bus=virtio-mmio-bus.2 -allow-host-audio -semihosting`;
|
|
150
|
-
// grpc配置
|
|
151
|
-
let windowStr = '';
|
|
152
|
-
let grpcStr = '';
|
|
153
|
-
if ((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.grpcPort) {
|
|
154
|
-
windowStr = '-qt-hide-window';
|
|
155
|
-
grpcStr = ` -idle-grpc-timeout 300 -grpc ${this.startOptions.grpcPort}`;
|
|
156
|
-
}
|
|
104
|
+
const { origin = Instance_1.IStartOrigin.Terminal } = options;
|
|
157
105
|
// 启动模拟器的命令和参数
|
|
158
|
-
const cmd =
|
|
106
|
+
const cmd = emulatorutil_1.EmulatorCmd.createMiwerCmd(options, this.sdkHome, this.avdHome);
|
|
107
|
+
if (!cmd)
|
|
108
|
+
return;
|
|
159
109
|
const spawnArgs = cmd.split(' ');
|
|
160
110
|
const spawnBin = spawnArgs.shift();
|
|
161
|
-
|
|
111
|
+
ColorConsole_1.default.log(`### Emulator ### Start CMD miwear: ${cmd}`);
|
|
112
|
+
const func = this instanceof MiwearInstance ? emulatorutil_1.EmulatorLog.rpkIsStart : emulatorutil_1.EmulatorLog.devIsStart;
|
|
162
113
|
return new Promise((resolve) => {
|
|
163
|
-
var _a, _b
|
|
114
|
+
var _a, _b;
|
|
164
115
|
this.goldfishProcess = (0, child_process_1.spawn)(spawnBin, spawnArgs, {
|
|
165
116
|
stdio: 'pipe',
|
|
166
117
|
shell: true,
|
|
167
118
|
cwd: this.sdkHome
|
|
168
119
|
});
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
process.stdout.pipe(this.goldfishProcess.stdin);
|
|
172
|
-
//setTimeout是为了解决window环境报错
|
|
173
|
-
const stdoutPipe = () => {
|
|
174
|
-
var _a, _b, _c, _d;
|
|
175
|
-
(_b = (_a = this.goldfishProcess) === null || _a === void 0 ? void 0 : _a.stdout) === null || _b === void 0 ? void 0 : _b.pipe(process.stdout);
|
|
176
|
-
(_d = (_c = this.goldfishProcess) === null || _c === void 0 ? void 0 : _c.stderr) === null || _d === void 0 ? void 0 : _d.pipe(process.stderr);
|
|
177
|
-
};
|
|
178
|
-
if (this.goldfishProcess.connected) {
|
|
179
|
-
stdoutPipe();
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
setTimeout(stdoutPipe, 0);
|
|
183
|
-
}
|
|
184
|
-
//setTimeout加一层保险防止app无法拉起
|
|
185
|
-
setTimeout(() => {
|
|
186
|
-
this.pmInstallApp && this.pmInstallApp(10);
|
|
187
|
-
}, 10000);
|
|
120
|
+
if (origin === Instance_1.IStartOrigin.Terminal) {
|
|
121
|
+
process.stdin.pipe(this.goldfishProcess.stdin);
|
|
188
122
|
}
|
|
123
|
+
// 利用 readline 接口可解决子进程日志换行的问题
|
|
124
|
+
this.stdoutReadline = readline_1.default.createInterface({
|
|
125
|
+
input: this.goldfishProcess.stdout
|
|
126
|
+
});
|
|
127
|
+
this.stderrReadline = readline_1.default.createInterface({
|
|
128
|
+
input: this.goldfishProcess.stderr
|
|
129
|
+
});
|
|
189
130
|
// 监听模拟器的退出事件
|
|
190
131
|
this.goldfishProcess.on('exit', (code) => {
|
|
191
|
-
|
|
132
|
+
ColorConsole_1.default.error(`### Emulator ### Goldfish emulator exited with code ${code}`);
|
|
192
133
|
if (options.exitCallback) {
|
|
193
134
|
options.exitCallback(code);
|
|
194
135
|
}
|
|
195
136
|
});
|
|
196
137
|
// 监听错误流
|
|
197
|
-
(_a = this.
|
|
138
|
+
(_a = this.stderrReadline) === null || _a === void 0 ? void 0 : _a.on('line', (data) => {
|
|
198
139
|
const stderrCb = options.stderrCallback || console.log;
|
|
199
140
|
stderrCb(data.toString());
|
|
200
141
|
});
|
|
201
142
|
// 监听输出流
|
|
202
|
-
(
|
|
143
|
+
(_b = this.stdoutReadline) === null || _b === void 0 ? void 0 : _b.on('line', (data) => {
|
|
203
144
|
const msg = data.toString();
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
stdoutCb(msg);
|
|
207
|
-
}
|
|
145
|
+
const stdoutCb = options.stdoutCallback || console.log;
|
|
146
|
+
stdoutCb(msg);
|
|
208
147
|
// 应用安装成功,则启动它
|
|
209
|
-
if (
|
|
210
|
-
|
|
211
|
-
this.installBol = true;
|
|
212
|
-
shared_utils_1.ColorConsole.info(`### Emulator ### Install quickapp successfully`);
|
|
148
|
+
if (emulatorutil_1.EmulatorLog.inStallIsFinshe(msg)) {
|
|
149
|
+
ColorConsole_1.default.info(`### Emulator ### Install quickapp successfully`);
|
|
213
150
|
this.launchQuickapp();
|
|
214
151
|
}
|
|
215
152
|
// 匹配到,则认为模拟器启动成功
|
|
216
|
-
if (msg
|
|
217
|
-
|
|
153
|
+
if (func(msg)) {
|
|
154
|
+
ColorConsole_1.default.info(`### Emulator ### Goldfish emulator starts successfully`);
|
|
218
155
|
resolve();
|
|
219
156
|
}
|
|
220
157
|
});
|
|
@@ -241,7 +178,7 @@ class MiwearInstance extends common_1.default {
|
|
|
241
178
|
.readdirSync(releaseDir)
|
|
242
179
|
.filter((item) => item.includes(appPackageName) && item.endsWith('.rpk'));
|
|
243
180
|
if (files.length === 0) {
|
|
244
|
-
|
|
181
|
+
ColorConsole_1.default.error(`### Emulator the rpk does not exist`);
|
|
245
182
|
}
|
|
246
183
|
const rpkPath = path_1.default.resolve(releaseDir, files[0]);
|
|
247
184
|
// 调试模式需要push一个文件至miwear中
|
|
@@ -252,7 +189,7 @@ class MiwearInstance extends common_1.default {
|
|
|
252
189
|
else {
|
|
253
190
|
yield adbMiwt.execAdbCmdAsync(`adb -s ${this.sn} shell rm /data/debugger_ip.cfg`);
|
|
254
191
|
}
|
|
255
|
-
this.
|
|
192
|
+
this.pushAndInstall(rpkPath, this.appDir);
|
|
256
193
|
});
|
|
257
194
|
}
|
|
258
195
|
/**
|
|
@@ -262,16 +199,16 @@ class MiwearInstance extends common_1.default {
|
|
|
262
199
|
* @param rpkPath rpk的绝对目录
|
|
263
200
|
* @param targetDir 要将rpk放到模拟器的哪个目录下
|
|
264
201
|
*/
|
|
265
|
-
|
|
202
|
+
pushAndInstall(rpkPath, targetDir) {
|
|
266
203
|
return __awaiter(this, void 0, void 0, function* () {
|
|
267
204
|
const { package: packageName } = this.projectInfo;
|
|
268
205
|
// 1. adb push应用的rpk
|
|
269
206
|
const targetPath = `${targetDir}/${packageName}.rpk`;
|
|
270
207
|
const pushCmd = `adb -s ${this.sn} push "${rpkPath}" ${targetPath}`;
|
|
271
|
-
|
|
208
|
+
ColorConsole_1.default.info(`### Emulator ### Excuting cmd: ${pushCmd}`);
|
|
272
209
|
yield adbMiwt.execAdbCmdAsync(pushCmd);
|
|
273
210
|
const installCmd = `adb -s ${this.sn} shell pm install ${targetPath}`;
|
|
274
|
-
|
|
211
|
+
ColorConsole_1.default.info(`### Emulator ### Excuting cmd: ${installCmd}`);
|
|
275
212
|
yield adbMiwt.execAdbCmdAsync(installCmd);
|
|
276
213
|
});
|
|
277
214
|
}
|
|
@@ -280,37 +217,10 @@ class MiwearInstance extends common_1.default {
|
|
|
280
217
|
return __awaiter(this, void 0, void 0, function* () {
|
|
281
218
|
const { package: packageName } = this.projectInfo;
|
|
282
219
|
const startCmd = `adb -s ${this.sn} shell am start ${packageName}`;
|
|
283
|
-
|
|
220
|
+
ColorConsole_1.default.info(`### Emulator ### Excuting cmd: ${startCmd}`);
|
|
284
221
|
adbMiwt.execAdbCmdAsync(startCmd);
|
|
285
222
|
});
|
|
286
223
|
}
|
|
287
|
-
/** 命令行模式下添加重复调用防止app无法拉起
|
|
288
|
-
* 主要用将子进程的流输出到主进程后,由于流写入的过多可能会影响事件循环
|
|
289
|
-
*/
|
|
290
|
-
pmInstallApp(maxRepeats, count = 0) {
|
|
291
|
-
var _a;
|
|
292
|
-
const releaseDir = this.isRpk
|
|
293
|
-
? path_1.default.resolve(this.projectPath, '../')
|
|
294
|
-
: path_1.default.resolve(this.projectPath, ((_a = this.params.compilerOption) === null || _a === void 0 ? void 0 : _a.releasePath) || 'dist');
|
|
295
|
-
const { package: packageName } = this.projectInfo;
|
|
296
|
-
const files = fs_extra_1.default
|
|
297
|
-
.readdirSync(releaseDir)
|
|
298
|
-
.filter((item) => item.includes(packageName) && item.endsWith('.rpk'));
|
|
299
|
-
const targetDir = path_1.default.resolve(releaseDir, files[0]);
|
|
300
|
-
const targetPath = `${targetDir}/${packageName}.rpk`;
|
|
301
|
-
const installCmd = `adb -s ${this.sn} shell pm install ${targetPath}`;
|
|
302
|
-
if (count < maxRepeats - 1 && !this.installBol) {
|
|
303
|
-
count++;
|
|
304
|
-
shared_utils_1.ColorConsole.info(`### Emulator ### Excuting cmd: terminalr ${installCmd}`);
|
|
305
|
-
adbMiwt.execAdbCmdAsync(installCmd);
|
|
306
|
-
setTimeout(() => {
|
|
307
|
-
this.pmInstallApp(maxRepeats, count);
|
|
308
|
-
}, 6000);
|
|
309
|
-
}
|
|
310
|
-
else {
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
224
|
/** 连接模拟器中的调试服务,创建debugSocket
|
|
315
225
|
* 主要用于热更新时,通过debugSocket通知调试服务更新页面
|
|
316
226
|
* 设置了重连机制,会重复连接8次
|
|
@@ -323,7 +233,7 @@ class MiwearInstance extends common_1.default {
|
|
|
323
233
|
}
|
|
324
234
|
this.debugSocket = new ws_1.default(`ws://localhost:${(_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.debugPort}`);
|
|
325
235
|
this.debugSocket.onopen = () => {
|
|
326
|
-
|
|
236
|
+
ColorConsole_1.default.info(`### Emulator debugSocket connect success`);
|
|
327
237
|
return resolve();
|
|
328
238
|
};
|
|
329
239
|
this.debugSocket.onerror = (errorEvent) => {
|
|
@@ -331,7 +241,7 @@ class MiwearInstance extends common_1.default {
|
|
|
331
241
|
// 重连机制
|
|
332
242
|
(_a = this.debugSocket) === null || _a === void 0 ? void 0 : _a.terminate();
|
|
333
243
|
if (this.reconnectCount < MAX_RECONNECT_COUNT) {
|
|
334
|
-
|
|
244
|
+
ColorConsole_1.default.info(`### Emulator the ${this.reconnectCount + 1}th time to reconnect debug server`);
|
|
335
245
|
this.reconnectCount++;
|
|
336
246
|
setTimeout(() => this.initDebugSocket(), 2000);
|
|
337
247
|
}
|
|
@@ -344,7 +254,7 @@ class MiwearInstance extends common_1.default {
|
|
|
344
254
|
this.debugSocket.onclose = (closeEvent) => {
|
|
345
255
|
this.debugSocket = undefined;
|
|
346
256
|
this.reconnectCount = 0;
|
|
347
|
-
|
|
257
|
+
ColorConsole_1.default.log(`### Emulator debugSocket connect close: ${closeEvent.reason}`);
|
|
348
258
|
};
|
|
349
259
|
});
|
|
350
260
|
}
|
|
@@ -367,7 +277,7 @@ class MiwearInstance extends common_1.default {
|
|
|
367
277
|
}
|
|
368
278
|
}
|
|
369
279
|
catch (e) {
|
|
370
|
-
|
|
280
|
+
ColorConsole_1.default.error(`${e}`);
|
|
371
281
|
}
|
|
372
282
|
});
|
|
373
283
|
}
|
|
@@ -378,17 +288,25 @@ class MiwearInstance extends common_1.default {
|
|
|
378
288
|
// windows平台adb push时无法使用通配符,需另外处理;
|
|
379
289
|
// 项目路径包含空格时,无法通过加引号来使用 * 通配符
|
|
380
290
|
if (os_1.default.platform() === 'win32' || this.projectPath.indexOf(' ') > 0) {
|
|
381
|
-
const rmCmd = `adb -s ${this.sn} shell rm -r ${this.
|
|
291
|
+
const rmCmd = `adb -s ${this.sn} shell rm -r ${this.appDir}/${appPackageName}`;
|
|
382
292
|
yield adbMiwt.execAdbCmdAsync(rmCmd);
|
|
383
293
|
const sourcePath = path_1.default.resolve(this.projectPath, './build');
|
|
384
|
-
const pushCmd = `adb -s ${this.sn} push "${sourcePath}" ${this.
|
|
294
|
+
const pushCmd = `adb -s ${this.sn} push "${sourcePath}" ${this.appDir}/${appPackageName}`;
|
|
385
295
|
yield adbMiwt.execAdbCmdAsync(pushCmd);
|
|
386
296
|
}
|
|
387
297
|
else {
|
|
388
298
|
const sourcePath = path_1.default.resolve(this.projectPath, './build/*');
|
|
389
|
-
yield adbMiwt.execAdbCmdAsync(`adb -s ${this.sn} push ${sourcePath} ${this.
|
|
299
|
+
yield adbMiwt.execAdbCmdAsync(`adb -s ${this.sn} push ${sourcePath} ${this.appDir}/${appPackageName}`);
|
|
390
300
|
}
|
|
391
|
-
|
|
301
|
+
ColorConsole_1.default.info(`### Emulator push to ${this.appDir}/${appPackageName} successfully`);
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
/** 通过命令行启动时,在watich模式下监听websocket消息,
|
|
305
|
+
* 在文件发生变动时,重新启动应用
|
|
306
|
+
*/
|
|
307
|
+
restart() {
|
|
308
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
309
|
+
this.pushAndReloadApp();
|
|
392
310
|
});
|
|
393
311
|
}
|
|
394
312
|
/** 在模拟器中重启快应用(基于am命令,需要保证镜像中已经有am功能)
|
|
@@ -410,15 +328,15 @@ class MiwearInstance extends common_1.default {
|
|
|
410
328
|
// 2. 执行am stop和am start命令
|
|
411
329
|
const stopCmd = `adb -s ${this.sn} shell am stop ${appPackageName}`;
|
|
412
330
|
yield adbMiwt.execAdbCmdAsync(stopCmd);
|
|
413
|
-
|
|
331
|
+
ColorConsole_1.default.info(`### Emulator stop ${appPackageName} successfully`);
|
|
414
332
|
// 这里是为了等am stop命令清除资源等
|
|
415
333
|
yield (0, utils_1.sleep)(500);
|
|
416
334
|
const startCmd = `adb -s ${this.sn} shell am start ${appPackageName}`;
|
|
417
335
|
yield adbMiwt.execAdbCmdAsync(startCmd);
|
|
418
|
-
|
|
336
|
+
ColorConsole_1.default.info(`### Emulator start ${appPackageName} successfully`);
|
|
419
337
|
}
|
|
420
338
|
catch (e) {
|
|
421
|
-
|
|
339
|
+
ColorConsole_1.default.error(`${e}`);
|
|
422
340
|
}
|
|
423
341
|
});
|
|
424
342
|
}
|
|
@@ -432,15 +350,15 @@ class MiwearInstance extends common_1.default {
|
|
|
432
350
|
port: (_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.serverPort
|
|
433
351
|
});
|
|
434
352
|
wsServer.on('connection', (socket) => {
|
|
435
|
-
|
|
353
|
+
ColorConsole_1.default.success(`### App Socket server ### Websocket connects to websocket server`);
|
|
436
354
|
socket.on('error', (err) => {
|
|
437
|
-
|
|
355
|
+
ColorConsole_1.default.error(`### App Socket server ### Websocket server error: ${err.message}`);
|
|
438
356
|
});
|
|
439
357
|
// data的格式:{ type: string, data: any }
|
|
440
358
|
socket.on('message', (data) => __awaiter(this, void 0, void 0, function* () {
|
|
441
359
|
var _a;
|
|
442
360
|
const message = JSON.parse(data.toString());
|
|
443
|
-
|
|
361
|
+
ColorConsole_1.default.log(`### App Socket server ### Websocket server get data: ${data}`);
|
|
444
362
|
if (message.type === 'restart') {
|
|
445
363
|
// 非调试模式下无法热更新
|
|
446
364
|
if (!((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.devtool)) {
|
package/lib/instance/pre.d.ts
CHANGED
|
@@ -3,6 +3,9 @@ import GoldfishInstance from './dev';
|
|
|
3
3
|
* 不带 miwear 的 4.0 镜像
|
|
4
4
|
*/
|
|
5
5
|
declare class PreInstance extends GoldfishInstance {
|
|
6
|
-
|
|
6
|
+
appDir: string;
|
|
7
|
+
pushRpk(rpkPath?: string): Promise<string>;
|
|
8
|
+
installApp(rpkPath?: string): Promise<void>;
|
|
9
|
+
pushAndInstall(rpkPath?: string): Promise<void>;
|
|
7
10
|
}
|
|
8
11
|
export default PreInstance;
|
package/lib/instance/pre.js
CHANGED
|
@@ -1,17 +1,98 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
2
34
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
36
|
};
|
|
5
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
const path_1 = __importDefault(require("path"));
|
|
39
|
+
const fs_1 = __importDefault(require("fs"));
|
|
6
40
|
const dev_1 = __importDefault(require("./dev"));
|
|
7
41
|
const miwear_1 = __importDefault(require("./miwear"));
|
|
42
|
+
const ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
|
|
43
|
+
const adbMiwt = __importStar(require("@miwt/adb"));
|
|
8
44
|
/**
|
|
9
45
|
* 不带 miwear 的 4.0 镜像
|
|
10
46
|
*/
|
|
11
47
|
class PreInstance extends dev_1.default {
|
|
12
48
|
constructor() {
|
|
13
49
|
super(...arguments);
|
|
14
|
-
this.
|
|
50
|
+
this.appDir = '/data/quickapp/app';
|
|
51
|
+
}
|
|
52
|
+
pushRpk(rpkPath) {
|
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
const { package: appPackageName } = this.projectInfo;
|
|
55
|
+
const releaseDir = this.isRpk
|
|
56
|
+
? path_1.default.resolve(this.projectPath, '../')
|
|
57
|
+
: path_1.default.resolve(this.projectPath, 'dist');
|
|
58
|
+
let srouceRpk = rpkPath;
|
|
59
|
+
if (!srouceRpk) {
|
|
60
|
+
const files = fs_1.default
|
|
61
|
+
.readdirSync(releaseDir)
|
|
62
|
+
.filter((item) => item.includes(appPackageName) && item.endsWith('.rpk'));
|
|
63
|
+
if (files.length === 0) {
|
|
64
|
+
ColorConsole_1.default.error(`### Emulator the rpk does not exist`);
|
|
65
|
+
}
|
|
66
|
+
srouceRpk = path_1.default.resolve(releaseDir, files[0]);
|
|
67
|
+
}
|
|
68
|
+
// 1. adb push应用的rpk
|
|
69
|
+
const targetPath = `${this.appDir}/${appPackageName}.rpk`;
|
|
70
|
+
const pushCmd = `adb -s ${this.sn} push "${srouceRpk}" ${targetPath}`;
|
|
71
|
+
ColorConsole_1.default.info(`### Emulator ### Excuting cmd: ${pushCmd}`);
|
|
72
|
+
yield adbMiwt.execAdbCmdAsync(pushCmd);
|
|
73
|
+
ColorConsole_1.default.info(`### Emulator push to ${this.appDir}/${appPackageName} successfully`);
|
|
74
|
+
return targetPath;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
installApp(rpkPath) {
|
|
78
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
const { package: appPackageName } = this.projectInfo;
|
|
80
|
+
// 基于 vapp 启动的应用只需要将 rpk 解压到指定的目录下
|
|
81
|
+
rpkPath = rpkPath || `${this.appDir}/${appPackageName}.rpk`;
|
|
82
|
+
const targetPath = `${this.appDir}/${appPackageName}`;
|
|
83
|
+
const mkdirCmd = `adb -s ${this.sn} shell mkdir ${targetPath}`;
|
|
84
|
+
ColorConsole_1.default.info(`### Emulator mkdir cmd ${mkdirCmd}`);
|
|
85
|
+
yield adbMiwt.execAdbCmdAsync(mkdirCmd);
|
|
86
|
+
const unzipCmd = `adb -s ${this.sn} shell unzip -o ${rpkPath} -d ${targetPath}`;
|
|
87
|
+
ColorConsole_1.default.info(`### Emulator unzip cmd ${unzipCmd}`);
|
|
88
|
+
yield adbMiwt.execAdbCmdAsync(unzipCmd);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
pushAndInstall(rpkPath) {
|
|
92
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
93
|
+
const target = yield this.pushRpk(rpkPath);
|
|
94
|
+
yield this.installApp(target);
|
|
95
|
+
});
|
|
15
96
|
}
|
|
16
97
|
}
|
|
17
98
|
// pre 镜像的 启动 方式与 MiwearInstance 一致
|
package/lib/instance/preDev.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
2
3
|
import { ChildProcess } from 'child_process';
|
|
4
|
+
import readline from 'readline';
|
|
3
5
|
import { INewGoldfishInstanceParams, IStartOptions } from '../typing/Instance';
|
|
4
6
|
import CommonInstance from './common';
|
|
5
7
|
/**
|
|
@@ -9,6 +11,8 @@ import CommonInstance from './common';
|
|
|
9
11
|
declare class OldGoldfishInstance extends CommonInstance {
|
|
10
12
|
private host9pPort;
|
|
11
13
|
v9fsProcess: ChildProcess | undefined;
|
|
14
|
+
stdoutReadline: readline.Interface;
|
|
15
|
+
stderrReadline: readline.Interface;
|
|
12
16
|
constructor(params: INewGoldfishInstanceParams);
|
|
13
17
|
/**
|
|
14
18
|
* 1. 启动9p server
|