@aiot-toolkit/emulator 2.0.2-beta.12 → 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.
@@ -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 shared_utils_1 = require("@aiot-toolkit/shared-utils");
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,10 +56,8 @@ class MiwearInstance extends common_1.default {
54
56
  constructor(params) {
55
57
  super(params);
56
58
  this.params = params;
57
- this.quickappStartedFlag = /quickapp_rpk_installer_init|rpk installer init done/;
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
61
  }
62
62
  /**
63
63
  * 1. 启动模拟器
@@ -73,7 +73,7 @@ class MiwearInstance extends common_1.default {
73
73
  // adb连接模拟器
74
74
  const connected = yield this.isConnected();
75
75
  if (connected) {
76
- shared_utils_1.ColorConsole.info('### Emulator ### Goldfish emulator connected successfully');
76
+ ColorConsole_1.default.info('### Emulator ### Goldfish emulator connected successfully');
77
77
  // 如果是首次启动,创建server端监听事件
78
78
  if (this.isFirstStart && this.startOptions.serverPort) {
79
79
  yield this.createWebsockeServer();
@@ -84,7 +84,7 @@ class MiwearInstance extends common_1.default {
84
84
  }
85
85
  else {
86
86
  const msg = '### Emulator ### Failed to connect emulator, please check whether the adb is normal';
87
- shared_utils_1.ColorConsole.throw(msg);
87
+ ColorConsole_1.default.throw(msg);
88
88
  throw new Error(msg);
89
89
  }
90
90
  });
@@ -100,96 +100,58 @@ class MiwearInstance extends common_1.default {
100
100
  * @returns
101
101
  */
102
102
  startGoldfish(options) {
103
- var _a;
104
103
  return __awaiter(this, void 0, void 0, function* () {
105
- const { avdName, devtool, origin = 'terminal' } = options;
106
- // 获取emulator bin的绝对路径
107
- const emulatorBin = this.getEmulatorBinPath();
108
- shared_utils_1.ColorConsole.log(`### Emulator ### emulator path: ${emulatorBin}`);
109
- // 获取vela镜像的绝对路径
110
- const avdInfo = this.velaAvdCls.getVelaAvdInfo(avdName);
111
- const { avdArch, avdImagePath, customImagePath } = avdInfo;
112
- shared_utils_1.ColorConsole.log(`### Emulator ### adb port: ${options.adbPort}`);
113
- if (!avdImagePath) {
114
- return shared_utils_1.ColorConsole.throw(`### Emulator ### Unable to find vela image via avd`);
115
- }
116
- const nuttxBinPath = path_1.default.resolve(customImagePath || avdImagePath, 'nuttx');
117
- shared_utils_1.ColorConsole.log(`### Emulator ### nuttx path: ${nuttxBinPath}`);
118
- // 端口映射
119
- let portMappingStr = ``;
120
- if (devtool) {
121
- portMappingStr += `-network-user-mode-options hostfwd=tcp:127.0.0.1:${options.debugPort}-10.0.2.15:101`;
122
- }
123
- // 设备挂载节点
124
- const systemImageBin = path_1.default.resolve(avdImagePath, 'vela_resource.bin'); // 只读
125
- const dataImageBin = path_1.default.resolve(avdImagePath, 'vela_data.bin'); // 可读可写
126
- const coreBin = path_1.default.resolve(avdImagePath, 'coredump.core'); // 只读
127
- // 复制可写文件到AVD目录下(多模拟器实例时需要)
128
- const dataImageBinInAvd = path_1.default.join(this.avdHome, `${avdName}.avd`, 'vela_data.bin');
129
- if (!fs_extra_1.default.existsSync(dataImageBinInAvd)) {
130
- // vela_data.bin不存在时直接copy
131
- fs_extra_1.default.copyFileSync(dataImageBin, dataImageBinInAvd);
132
- }
133
- else {
134
- // vela_data.bin存在时,如果.export里的时间晚于avd里的时候,说明更新了镜像,需要重新copy
135
- const statsInAvd = fs_extra_1.default.statSync(dataImageBinInAvd);
136
- const stats = fs_extra_1.default.statSync(dataImageBin);
137
- if ((0, dayjs_1.default)(stats.mtime).isAfter(statsInAvd.mtime)) {
138
- fs_extra_1.default.copyFileSync(dataImageBin, dataImageBinInAvd);
139
- }
140
- }
141
- // 挂载节点配置,只读文件加入read-only标识
142
- const imageMountStr = `-drive index=0,id=system,if=none,format=raw,file=${systemImageBin},read-only \
143
- -device virtio-blk-device,bus=virtio-mmio-bus.0,drive=system \
144
- -drive index=1,id=userdata,if=none,format=raw,file=${dataImageBinInAvd} \
145
- -device virtio-blk-device,bus=virtio-mmio-bus.1,drive=userdata \
146
- -drive index=2,id=vendor,if=none,format=raw,file=${coreBin},read-only \
147
- -device virtio-blk-device,bus=virtio-mmio-bus.4,drive=vendor \
148
- -device virtio-snd,bus=virtio-mmio-bus.2 -allow-host-audio -semihosting`;
149
- // grpc配置
150
- let windowStr = '';
151
- let grpcStr = '';
152
- if ((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.grpcPort) {
153
- windowStr = '-qt-hide-window';
154
- grpcStr = ` -idle-grpc-timeout 300 -grpc ${this.startOptions.grpcPort}`;
155
- }
104
+ const { origin = Instance_1.IStartOrigin.Terminal } = options;
156
105
  // 启动模拟器的命令和参数
157
- const cmd = `${emulatorBin} -nuttx -avd ${avdName} -port ${options.adbPort} -avd-arch ${avdArch} -show-kernel -kernel ${nuttxBinPath} ${portMappingStr} ${windowStr} ${grpcStr} -qemu ${imageMountStr}`;
106
+ const cmd = emulatorutil_1.EmulatorCmd.createMiwerCmd(options, this.sdkHome, this.avdHome);
107
+ if (!cmd)
108
+ return;
158
109
  const spawnArgs = cmd.split(' ');
159
110
  const spawnBin = spawnArgs.shift();
160
- shared_utils_1.ColorConsole.log(`### Emulator ### Start CMD: ${cmd}`);
111
+ ColorConsole_1.default.log(`### Emulator ### Start CMD miwear: ${cmd}`);
112
+ const func = this instanceof MiwearInstance ? emulatorutil_1.EmulatorLog.rpkIsStart : emulatorutil_1.EmulatorLog.devIsStart;
161
113
  return new Promise((resolve) => {
162
- var _a, _b, _c;
114
+ var _a, _b;
163
115
  this.goldfishProcess = (0, child_process_1.spawn)(spawnBin, spawnArgs, {
164
116
  stdio: 'pipe',
165
117
  shell: true,
166
118
  cwd: this.sdkHome
167
119
  });
120
+ if (origin === Instance_1.IStartOrigin.Terminal) {
121
+ process.stdin.pipe(this.goldfishProcess.stdin);
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
+ });
168
130
  // 监听模拟器的退出事件
169
131
  this.goldfishProcess.on('exit', (code) => {
170
- shared_utils_1.ColorConsole.error(`### Emulator ### Goldfish emulator exited with code ${code}`);
132
+ ColorConsole_1.default.error(`### Emulator ### Goldfish emulator exited with code ${code}`);
171
133
  if (options.exitCallback) {
172
134
  options.exitCallback(code);
173
135
  }
174
136
  });
175
137
  // 监听错误流
176
- (_a = this.goldfishProcess.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
138
+ (_a = this.stderrReadline) === null || _a === void 0 ? void 0 : _a.on('line', (data) => {
177
139
  const stderrCb = options.stderrCallback || console.log;
178
140
  stderrCb(data.toString());
179
141
  });
180
142
  // 监听输出流
181
- (_c = (_b = this.goldfishProcess) === null || _b === void 0 ? void 0 : _b.stdout) === null || _c === void 0 ? void 0 : _c.on('data', (data) => {
143
+ (_b = this.stdoutReadline) === null || _b === void 0 ? void 0 : _b.on('line', (data) => {
182
144
  const msg = data.toString();
183
145
  const stdoutCb = options.stdoutCallback || console.log;
184
146
  stdoutCb(msg);
185
147
  // 应用安装成功,则启动它
186
- if (msg.match(/InstallState_Finished|install finished/)) {
187
- 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`);
188
150
  this.launchQuickapp();
189
151
  }
190
152
  // 匹配到,则认为模拟器启动成功
191
- if (msg.match(this.emulatorStartedFlag)) {
192
- shared_utils_1.ColorConsole.info(`### Emulator ### Goldfish emulator starts successfully`);
153
+ if (func(msg)) {
154
+ ColorConsole_1.default.info(`### Emulator ### Goldfish emulator starts successfully`);
193
155
  resolve();
194
156
  }
195
157
  });
@@ -216,7 +178,7 @@ class MiwearInstance extends common_1.default {
216
178
  .readdirSync(releaseDir)
217
179
  .filter((item) => item.includes(appPackageName) && item.endsWith('.rpk'));
218
180
  if (files.length === 0) {
219
- shared_utils_1.ColorConsole.error(`### Emulator the rpk does not exist`);
181
+ ColorConsole_1.default.error(`### Emulator the rpk does not exist`);
220
182
  }
221
183
  const rpkPath = path_1.default.resolve(releaseDir, files[0]);
222
184
  // 调试模式需要push一个文件至miwear中
@@ -227,7 +189,7 @@ class MiwearInstance extends common_1.default {
227
189
  else {
228
190
  yield adbMiwt.execAdbCmdAsync(`adb -s ${this.sn} shell rm /data/debugger_ip.cfg`);
229
191
  }
230
- this.installRpkToAppList(rpkPath, this.appPathInEmulator);
192
+ this.pushAndInstall(rpkPath, this.appDir);
231
193
  });
232
194
  }
233
195
  /**
@@ -237,16 +199,16 @@ class MiwearInstance extends common_1.default {
237
199
  * @param rpkPath rpk的绝对目录
238
200
  * @param targetDir 要将rpk放到模拟器的哪个目录下
239
201
  */
240
- installRpkToAppList(rpkPath, targetDir) {
202
+ pushAndInstall(rpkPath, targetDir) {
241
203
  return __awaiter(this, void 0, void 0, function* () {
242
204
  const { package: packageName } = this.projectInfo;
243
205
  // 1. adb push应用的rpk
244
206
  const targetPath = `${targetDir}/${packageName}.rpk`;
245
207
  const pushCmd = `adb -s ${this.sn} push "${rpkPath}" ${targetPath}`;
246
- shared_utils_1.ColorConsole.info(`### Emulator ### Excuting cmd: ${pushCmd}`);
208
+ ColorConsole_1.default.info(`### Emulator ### Excuting cmd: ${pushCmd}`);
247
209
  yield adbMiwt.execAdbCmdAsync(pushCmd);
248
210
  const installCmd = `adb -s ${this.sn} shell pm install ${targetPath}`;
249
- shared_utils_1.ColorConsole.info(`### Emulator ### Excuting cmd: ${installCmd}`);
211
+ ColorConsole_1.default.info(`### Emulator ### Excuting cmd: ${installCmd}`);
250
212
  yield adbMiwt.execAdbCmdAsync(installCmd);
251
213
  });
252
214
  }
@@ -255,7 +217,7 @@ class MiwearInstance extends common_1.default {
255
217
  return __awaiter(this, void 0, void 0, function* () {
256
218
  const { package: packageName } = this.projectInfo;
257
219
  const startCmd = `adb -s ${this.sn} shell am start ${packageName}`;
258
- shared_utils_1.ColorConsole.info(`### Emulator ### Excuting cmd: ${startCmd}`);
220
+ ColorConsole_1.default.info(`### Emulator ### Excuting cmd: ${startCmd}`);
259
221
  adbMiwt.execAdbCmdAsync(startCmd);
260
222
  });
261
223
  }
@@ -271,7 +233,7 @@ class MiwearInstance extends common_1.default {
271
233
  }
272
234
  this.debugSocket = new ws_1.default(`ws://localhost:${(_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.debugPort}`);
273
235
  this.debugSocket.onopen = () => {
274
- shared_utils_1.ColorConsole.info(`### Emulator debugSocket connect success`);
236
+ ColorConsole_1.default.info(`### Emulator debugSocket connect success`);
275
237
  return resolve();
276
238
  };
277
239
  this.debugSocket.onerror = (errorEvent) => {
@@ -279,7 +241,7 @@ class MiwearInstance extends common_1.default {
279
241
  // 重连机制
280
242
  (_a = this.debugSocket) === null || _a === void 0 ? void 0 : _a.terminate();
281
243
  if (this.reconnectCount < MAX_RECONNECT_COUNT) {
282
- shared_utils_1.ColorConsole.info(`### Emulator the ${this.reconnectCount + 1}th time to reconnect debug server`);
244
+ ColorConsole_1.default.info(`### Emulator the ${this.reconnectCount + 1}th time to reconnect debug server`);
283
245
  this.reconnectCount++;
284
246
  setTimeout(() => this.initDebugSocket(), 2000);
285
247
  }
@@ -292,7 +254,7 @@ class MiwearInstance extends common_1.default {
292
254
  this.debugSocket.onclose = (closeEvent) => {
293
255
  this.debugSocket = undefined;
294
256
  this.reconnectCount = 0;
295
- shared_utils_1.ColorConsole.log(`### Emulator debugSocket connect close: ${closeEvent.reason}`);
257
+ ColorConsole_1.default.log(`### Emulator debugSocket connect close: ${closeEvent.reason}`);
296
258
  };
297
259
  });
298
260
  }
@@ -315,7 +277,7 @@ class MiwearInstance extends common_1.default {
315
277
  }
316
278
  }
317
279
  catch (e) {
318
- shared_utils_1.ColorConsole.error(`${e}`);
280
+ ColorConsole_1.default.error(`${e}`);
319
281
  }
320
282
  });
321
283
  }
@@ -326,17 +288,25 @@ class MiwearInstance extends common_1.default {
326
288
  // windows平台adb push时无法使用通配符,需另外处理;
327
289
  // 项目路径包含空格时,无法通过加引号来使用 * 通配符
328
290
  if (os_1.default.platform() === 'win32' || this.projectPath.indexOf(' ') > 0) {
329
- const rmCmd = `adb -s ${this.sn} shell rm -r ${this.appPathInEmulator}/${appPackageName}`;
291
+ const rmCmd = `adb -s ${this.sn} shell rm -r ${this.appDir}/${appPackageName}`;
330
292
  yield adbMiwt.execAdbCmdAsync(rmCmd);
331
293
  const sourcePath = path_1.default.resolve(this.projectPath, './build');
332
- const pushCmd = `adb -s ${this.sn} push "${sourcePath}" ${this.appPathInEmulator}/${appPackageName}`;
294
+ const pushCmd = `adb -s ${this.sn} push "${sourcePath}" ${this.appDir}/${appPackageName}`;
333
295
  yield adbMiwt.execAdbCmdAsync(pushCmd);
334
296
  }
335
297
  else {
336
298
  const sourcePath = path_1.default.resolve(this.projectPath, './build/*');
337
- yield adbMiwt.execAdbCmdAsync(`adb -s ${this.sn} push ${sourcePath} ${this.appPathInEmulator}/${appPackageName}`);
299
+ yield adbMiwt.execAdbCmdAsync(`adb -s ${this.sn} push ${sourcePath} ${this.appDir}/${appPackageName}`);
338
300
  }
339
- shared_utils_1.ColorConsole.info(`### Emulator push to ${this.appPathInEmulator}/${appPackageName} successfully`);
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();
340
310
  });
341
311
  }
342
312
  /** 在模拟器中重启快应用(基于am命令,需要保证镜像中已经有am功能)
@@ -358,15 +328,15 @@ class MiwearInstance extends common_1.default {
358
328
  // 2. 执行am stop和am start命令
359
329
  const stopCmd = `adb -s ${this.sn} shell am stop ${appPackageName}`;
360
330
  yield adbMiwt.execAdbCmdAsync(stopCmd);
361
- shared_utils_1.ColorConsole.info(`### Emulator stop ${appPackageName} successfully`);
331
+ ColorConsole_1.default.info(`### Emulator stop ${appPackageName} successfully`);
362
332
  // 这里是为了等am stop命令清除资源等
363
333
  yield (0, utils_1.sleep)(500);
364
334
  const startCmd = `adb -s ${this.sn} shell am start ${appPackageName}`;
365
335
  yield adbMiwt.execAdbCmdAsync(startCmd);
366
- shared_utils_1.ColorConsole.info(`### Emulator start ${appPackageName} successfully`);
336
+ ColorConsole_1.default.info(`### Emulator start ${appPackageName} successfully`);
367
337
  }
368
338
  catch (e) {
369
- shared_utils_1.ColorConsole.error(`${e}`);
339
+ ColorConsole_1.default.error(`${e}`);
370
340
  }
371
341
  });
372
342
  }
@@ -380,15 +350,15 @@ class MiwearInstance extends common_1.default {
380
350
  port: (_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.serverPort
381
351
  });
382
352
  wsServer.on('connection', (socket) => {
383
- shared_utils_1.ColorConsole.success(`### App Socket server ### Websocket connects to websocket server`);
353
+ ColorConsole_1.default.success(`### App Socket server ### Websocket connects to websocket server`);
384
354
  socket.on('error', (err) => {
385
- shared_utils_1.ColorConsole.error(`### App Socket server ### Websocket server error: ${err.message}`);
355
+ ColorConsole_1.default.error(`### App Socket server ### Websocket server error: ${err.message}`);
386
356
  });
387
357
  // data的格式:{ type: string, data: any }
388
358
  socket.on('message', (data) => __awaiter(this, void 0, void 0, function* () {
389
359
  var _a;
390
360
  const message = JSON.parse(data.toString());
391
- shared_utils_1.ColorConsole.log(`### App Socket server ### Websocket server get data: ${data}`);
361
+ ColorConsole_1.default.log(`### App Socket server ### Websocket server get data: ${data}`);
392
362
  if (message.type === 'restart') {
393
363
  // 非调试模式下无法热更新
394
364
  if (!((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.devtool)) {
@@ -3,6 +3,9 @@ import GoldfishInstance from './dev';
3
3
  * 不带 miwear 的 4.0 镜像
4
4
  */
5
5
  declare class PreInstance extends GoldfishInstance {
6
- appRunDir: string;
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;
@@ -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.appRunDir = '/data/quickapp/app';
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 一致
@@ -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