@aiot-toolkit/emulator 2.0.2-beta.1 → 2.0.2-beta.11

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,149 +35,268 @@ 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 ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
38
+ const shared_utils_1 = require("@aiot-toolkit/shared-utils");
39
39
  const adbMiwt = __importStar(require("@miwt/adb"));
40
40
  const child_process_1 = require("child_process");
41
+ const dayjs_1 = __importDefault(require("dayjs"));
42
+ const fs_1 = __importDefault(require("fs"));
43
+ const os_1 = __importDefault(require("os"));
41
44
  const path_1 = __importDefault(require("path"));
42
- const portfinder_1 = __importDefault(require("portfinder"));
43
- const constants_1 = require("../static/constants");
44
45
  const common_1 = __importDefault(require("./common"));
45
46
  class GoldfishInstance extends common_1.default {
46
47
  constructor(params) {
47
48
  super(params);
48
49
  this.appRunDir = '/data/app';
50
+ this.emulatorStartedFlag = '(NSH)';
49
51
  }
50
- /** 在goldfish模拟器中运行快应用 */
52
+ /**
53
+ * 1. 启动模拟器
54
+ * 2. 启动成功后,adb连接模拟器
55
+ * 3. 连接成功后,在模拟器中启动快应用
56
+ */
51
57
  start(options) {
52
58
  return __awaiter(this, void 0, void 0, function* () {
53
59
  this.startOptions = options;
60
+ this.sn = `emulator-${this.startOptions.adbPort}`;
54
61
  // 启动模拟器
55
62
  yield this.startGoldfish(options);
56
- const connected = yield this.connectGoldfish();
63
+ const connected = yield this.isConnected();
57
64
  if (connected) {
58
- ColorConsole_1.default.log('### Emulator ### Goldfish emulator connected successfully');
65
+ shared_utils_1.ColorConsole.log('### Emulator ### Goldfish emulator connected successfully');
59
66
  if (this.isFirstStart && this.startOptions.serverPort) {
60
67
  yield this.createWebsockeServer();
61
68
  }
62
69
  // adb push快应用到模拟器的/data/app目录
63
- const buildedFilesPath = this.isRpk ? this.projectPath : path_1.default.resolve(this.projectPath, './build');
70
+ // aspect应用后续要考虑各种形状表盘的推包
71
+ const buildedFilesPath = this.isRpk
72
+ ? this.projectPath
73
+ : this.isDistributedApp
74
+ ? options.dist ||
75
+ path_1.default.join(this.projectPath, './build', `${this.projectInfo.package}.watch`)
76
+ : path_1.default.join(this.projectPath, './build');
64
77
  yield this.pushRpk(buildedFilesPath);
65
78
  // 在模拟器中启动快应用
66
79
  this.startupQuickApp(options);
67
80
  this.isFirstStart = false;
68
81
  }
69
82
  else {
70
- ColorConsole_1.default.throw('### Emulator ### Failed to connect emulator, please check whether the adb is normal');
83
+ const msg = '### Emulator ### Failed to connect emulator, please check whether the adb is normal';
84
+ shared_utils_1.ColorConsole.throw(msg);
85
+ throw new Error(msg);
71
86
  }
72
87
  });
73
88
  }
74
- /** 在goldfish中启动快应用 */
89
+ /**
90
+ * 在模拟器中启动快应用
91
+ * 通过vapp命令启动,调试时需额外配置--jsdebugger参数
92
+ * @param options
93
+ */
75
94
  startupQuickApp(options) {
76
95
  return __awaiter(this, void 0, void 0, function* () {
77
96
  try {
78
97
  const { package: packageName } = this.projectInfo;
79
- let vappCmd = `adb -s 127.0.0.1:${this.adbPort} shell vapp app/${packageName} &`;
98
+ let vappCmd = `adb -s ${this.sn} shell vapp app/${packageName} &`;
80
99
  if (options.devtool) {
81
- vappCmd = `adb -s 127.0.0.1:${this.adbPort} shell vapp --jsdebugger=10.0.2.15:101 app/${packageName} &`;
100
+ vappCmd = `adb -s ${this.sn} shell vapp --jsdebugger=10.0.2.15:101 app/${packageName} &`;
82
101
  }
83
- ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${vappCmd}`);
102
+ shared_utils_1.ColorConsole.log(`### Emulator ### Excuting adb cmd: ${vappCmd}`);
84
103
  // vapp进程会一直pending,不会退出。这里必须加stdio: 'ignore',否则快应用无法运行成功
85
104
  adbMiwt.execAdbCmdAsync(vappCmd, { stdio: 'ignore', encoding: 'utf-8' });
86
105
  }
87
106
  catch (e) {
88
- ColorConsole_1.default.error(`### Emulator ### Failed to startup quickapp: ${e.message}`);
107
+ shared_utils_1.ColorConsole.error(`### Emulator ### Failed to startup quickapp: ${e.message}`);
89
108
  }
90
109
  });
91
110
  }
92
- /** 启动goldfish模拟器 */
111
+ /**
112
+ * 启动模拟器
113
+ * 1. 通过options生成模拟器的启动命令
114
+ * 2. 执行启动命令
115
+ * 3. 判断模拟器是否启动成功
116
+ * 3.1 若disableNSH=true,输出流中匹配到(NSH),认为模拟器启动成功了
117
+ * 3.2 若disableNSH=false,认为2s过后模拟器启动成功了
118
+ * @param options
119
+ * @returns
120
+ */
93
121
  startGoldfish(options) {
94
122
  var _a;
95
123
  return __awaiter(this, void 0, void 0, function* () {
96
- const { avdName, devtool } = options;
124
+ const { avdName, devtool, origin = 'terminal' } = options;
97
125
  const emulatorBin = this.getEmulatorBinPath();
98
- ColorConsole_1.default.log(`### Emulator ### emulator path: ${emulatorBin}`);
126
+ shared_utils_1.ColorConsole.log(`### Emulator ### emulator path: ${emulatorBin}`);
99
127
  const avdInfo = this.velaAvdCls.getVelaAvdInfo(avdName);
100
128
  const { avdArch, avdImagePath } = avdInfo;
101
- this.adbPort = yield portfinder_1.default.getPortPromise({ port: this.adbPort });
102
- ColorConsole_1.default.log(`### Emulator ### adb port: ${this.adbPort}`);
129
+ shared_utils_1.ColorConsole.log(`### Emulator ### adb port: ${options.adbPort}`);
103
130
  if (!avdImagePath) {
104
- return ColorConsole_1.default.throw(`### Emulator ### Unable to find vela image via avd`);
131
+ return shared_utils_1.ColorConsole.throw(`### Emulator ### Unable to find vela image via avd`);
105
132
  }
106
133
  const nuttxBinPath = path_1.default.resolve(avdImagePath, 'nuttx');
107
- ColorConsole_1.default.log(`### Emulator ### nuttx path: ${nuttxBinPath}`);
134
+ shared_utils_1.ColorConsole.log(`### Emulator ### nuttx path: ${nuttxBinPath}`);
108
135
  // 端口映射
109
- let portMappingStr = `-network-user-mode-options hostfwd=tcp:127.0.0.1:${this.adbPort}-10.0.2.15:5555`;
136
+ let portMappingStr = ``;
110
137
  if (devtool) {
111
- portMappingStr += `,hostfwd=tcp:127.0.0.1:${this.debugPort}-10.0.2.15:101`;
138
+ portMappingStr += `-network-user-mode-options hostfwd=tcp:127.0.0.1:${options.debugPort}-10.0.2.15:101`;
112
139
  }
113
140
  // 文件系统配置,第一次使用fatfs镜像挂载,后续使用adb push更新应用
114
- const systemImageBin = path_1.default.resolve(this.sdkHome, 'tools/image/system.img');
115
- const dataImageBin = path_1.default.resolve(this.sdkHome, 'tools/image/data.img');
116
- const imageMountStr = `-drive index=0,id=system,if=none,format=raw,file=${systemImageBin} \
141
+ const systemImageBin = path_1.default.join(avdImagePath, 'system.img');
142
+ const dataImageBin = path_1.default.join(avdImagePath, 'data.img');
143
+ // 复制可写文件到AVD目录下(多模拟器实例时需要)
144
+ const dataImageBinInAvd = path_1.default.join(this.avdHome, `${avdName}.avd`, 'data.img');
145
+ if (!fs_1.default.existsSync(dataImageBinInAvd)) {
146
+ // data.img不存在时直接copy
147
+ fs_1.default.copyFileSync(dataImageBin, dataImageBinInAvd);
148
+ }
149
+ else {
150
+ // data.img存在时,如果.export里的时间晚于avd里的时候,说明更新了镜像,需要重新copy
151
+ const statsInAvd = fs_1.default.statSync(dataImageBinInAvd);
152
+ const stats = fs_1.default.statSync(dataImageBin);
153
+ if ((0, dayjs_1.default)(stats.mtime).isAfter(statsInAvd.mtime)) {
154
+ fs_1.default.copyFileSync(dataImageBin, dataImageBinInAvd);
155
+ }
156
+ }
157
+ // 复制可写文件到AVD目录下(多模拟器实例时需要)
158
+ const systemImageBinInAvd = path_1.default.join(this.avdHome, `${avdName}.avd`, 'system.img');
159
+ if (!fs_1.default.existsSync(systemImageBinInAvd)) {
160
+ // data.img不存在时直接copy
161
+ fs_1.default.copyFileSync(systemImageBin, systemImageBinInAvd);
162
+ }
163
+ else {
164
+ // data.img存在时,如果.export里的时间晚于avd里的时候,说明更新了镜像,需要重新copy
165
+ const statsInAvd = fs_1.default.statSync(systemImageBinInAvd);
166
+ const stats = fs_1.default.statSync(systemImageBin);
167
+ if ((0, dayjs_1.default)(stats.mtime).isAfter(statsInAvd.mtime)) {
168
+ fs_1.default.copyFileSync(systemImageBin, systemImageBinInAvd);
169
+ }
170
+ }
171
+ // 复制可写文件到AVD目录下(多模拟器实例时需要)
172
+ // const nuttxBinInAvd = path.join(this.avdHome, `${avdName}.avd`, 'nuttx')
173
+ // if (!fs.existsSync(nuttxBinInAvd)) {
174
+ // // data.img不存在时直接copy
175
+ // fs.copyFileSync(nuttxBinPath, nuttxBinInAvd)
176
+ // } else {
177
+ // // data.img存在时,如果.export里的时间晚于avd里的时候,说明更新了镜像,需要重新copy
178
+ // const statsInAvd = fs.statSync(nuttxBinInAvd)
179
+ // const stats = fs.statSync(nuttxBinPath)
180
+ // if (dayjs(stats.mtime).isAfter(statsInAvd.mtime)) {
181
+ // fs.copyFileSync(nuttxBinPath, nuttxBinInAvd)
182
+ // }
183
+ // }
184
+ const imageMountStr = `-drive index=0,id=system,if=none,format=raw,file=${systemImageBinInAvd} \
117
185
  -device virtio-blk-device,bus=virtio-mmio-bus.0,drive=system \
118
- -drive index=1,id=userdata,if=none,format=raw,file=${dataImageBin} \
186
+ -drive index=1,id=userdata,if=none,format=raw,file=${dataImageBinInAvd} \
119
187
  -device virtio-blk-device,bus=virtio-mmio-bus.1,drive=userdata \
120
188
  -device virtio-snd,bus=virtio-mmio-bus.2 -allow-host-audio -semihosting`;
121
- // vnc配置
189
+ // grpc配置
122
190
  let windowStr = '';
123
- let vncStr = '';
124
- if ((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.vncPort) {
125
- windowStr = '-no-window';
126
- const portSuffix = this.startOptions.vncPort - constants_1.defaultVncPort;
127
- vncStr = `-vnc :${portSuffix}`;
191
+ let grpcStr = '';
192
+ if ((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.grpcPort) {
193
+ windowStr = '-qt-hide-window';
194
+ grpcStr = ` -idle-grpc-timeout 300 -grpc ${this.startOptions.grpcPort}`;
128
195
  }
129
- const stdioType = options.disableNSH ? 'pipe' : 'inherit';
130
- // 启动goldfish的命令和参数
131
- const cmd = `${emulatorBin} -nuttx -avd ${avdName} -avd-arch ${avdArch} -show-kernel -kernel ${nuttxBinPath} ${portMappingStr} ${windowStr} -qemu ${vncStr} ${imageMountStr}`;
196
+ // 启动模拟器的命令和参数
197
+ const cmd = `${emulatorBin} -nuttx -avd ${avdName} -port ${options.adbPort} -avd-arch ${avdArch} -show-kernel -kernel ${nuttxBinPath} ${portMappingStr} ${windowStr} ${grpcStr} -qemu ${imageMountStr}`;
132
198
  const spawnArgs = cmd.split(' ');
133
199
  const spawnBin = spawnArgs.shift();
134
- ColorConsole_1.default.log(`### Emulator ### Start CMD: ${cmd}`);
200
+ shared_utils_1.ColorConsole.log(`### Emulator ### Start CMD: ${cmd}`);
135
201
  return new Promise((resolve) => {
136
- var _a, _b;
137
- this.goldfishProcess = (0, child_process_1.spawn)(spawnBin, spawnArgs, { stdio: stdioType, shell: true });
138
- if (options.disableNSH) {
139
- (_a = this.goldfishProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
140
- if (options.stdoutCallback) {
141
- options.stdoutCallback(data);
142
- }
143
- else {
144
- console.log(data.toString());
145
- }
146
- if (data.toString().includes('(NSH)')) {
147
- ColorConsole_1.default.log(`### Emulator ### Goldfish emulator starts successfully`);
148
- resolve();
149
- }
150
- });
151
- (_b = this.goldfishProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
152
- const stderrCb = options.stderrCallback || console.log;
153
- stderrCb(data.toString());
154
- });
155
- }
156
- else {
157
- setTimeout(() => {
158
- ColorConsole_1.default.log(`### Emulator ### Goldfish emulator starts successfully`);
159
- resolve();
160
- }, 2000);
202
+ var _a, _b, _c;
203
+ this.goldfishProcess = (0, child_process_1.spawn)(spawnBin, spawnArgs, { stdio: 'pipe', shell: true });
204
+ (_a = this.goldfishProcess.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
205
+ const stderrCb = options.stderrCallback || console.log;
206
+ stderrCb(data.toString());
207
+ });
208
+ if (origin === 'terminal') {
209
+ process.stdout.pipe(this.goldfishProcess.stdin);
210
+ (_b = this.goldfishProcess.stdout) === null || _b === void 0 ? void 0 : _b.pipe(process.stdout);
161
211
  }
162
212
  this.goldfishProcess.on('exit', (code) => {
163
- ColorConsole_1.default.error(`### Emulator ### Goldfish emulator exited with code ${code}`);
213
+ shared_utils_1.ColorConsole.error(`### Emulator ### Goldfish emulator exited with code ${code}`);
164
214
  if (options.exitCallback) {
165
215
  options.exitCallback(code);
166
216
  }
167
217
  });
218
+ (_c = this.goldfishProcess.stdout) === null || _c === void 0 ? void 0 : _c.on('data', (data) => {
219
+ const msg = data.toString();
220
+ if (origin === 'ide') {
221
+ const stdoutCb = options.stdoutCallback || console.log;
222
+ stdoutCb(msg);
223
+ }
224
+ if (msg.includes(this.emulatorStartedFlag)) {
225
+ shared_utils_1.ColorConsole.log(`### Emulator ### Goldfish emulator starts successfully`);
226
+ resolve();
227
+ }
228
+ });
168
229
  });
169
230
  });
170
231
  }
171
- /** 将打包后的文件推到挂载的快应用目录 */
232
+ /**
233
+ * 将目录通过adb push到模拟器中
234
+ * @param sourceRoot
235
+ */
172
236
  pushRpk(sourceRoot) {
173
237
  return __awaiter(this, void 0, void 0, function* () {
174
- const sn = `127.0.0.1:${this.adbPort}`;
238
+ const sn = this.sn;
175
239
  const { package: appPackageName } = this.projectInfo;
176
- const sourcePath = path_1.default.resolve(sourceRoot, './*');
177
- ColorConsole_1.default.log(`### Emulator ### Pushing ${appPackageName} to ${this.appRunDir}`);
178
- yield adbMiwt.execAdbCmdAsync(`adb -s ${sn} shell mkdir ${this.appRunDir}/${appPackageName}`);
179
- yield adbMiwt.execAdbCmdAsync(`adb -s ${sn} push ${sourcePath} ${this.appRunDir}/${appPackageName}`);
180
- ColorConsole_1.default.log(`### Emulator ### Push ${appPackageName} to ${this.appRunDir} successfully`);
240
+ // 获取最后一层目录,比如build
241
+ const basename = path_1.default.basename(sourceRoot);
242
+ if (os_1.default.platform() === 'win32' || this.projectPath.indexOf(' ') > 0) {
243
+ // windows系统或者项目路径有空格:1. adb push目录;2. 在模拟器中使用mv命令重命名
244
+ yield adbMiwt.execAdbCmdAsync(`adb -s ${sn} push ${sourceRoot} ${this.appRunDir}`);
245
+ yield adbMiwt.execAdbCmdAsync(`adb -s ${sn} shell mv ${this.appRunDir}/${basename} ${this.appRunDir}/${appPackageName}`);
246
+ }
247
+ else {
248
+ // 支持通配符处理: 1. 模拟器中mkdir创建目录 2. adb push ./XXXXX/* /XXX
249
+ const sourcePath = path_1.default.join(sourceRoot, './*');
250
+ const mkdirCmd = `adb -s ${sn} shell mkdir ${this.appRunDir}/${appPackageName}`;
251
+ shared_utils_1.ColorConsole.log(`### Emulator ### mkdir CMD: ${mkdirCmd}`);
252
+ yield adbMiwt.execAdbCmdAsync(mkdirCmd);
253
+ const pushCmd = `adb -s ${sn} push ${sourcePath} ${this.appRunDir}/${appPackageName}`;
254
+ shared_utils_1.ColorConsole.log(`### Emulator ### pushCmd CMD: ${pushCmd}`);
255
+ yield adbMiwt.execAdbCmdAsync(pushCmd);
256
+ }
257
+ shared_utils_1.ColorConsole.info(`### Emulator push to ${this.appRunDir}/${appPackageName} successfully`);
258
+ });
259
+ }
260
+ /**
261
+ * 重新推送,然后重启应用
262
+ */
263
+ pushAndReloadApp() {
264
+ var _a;
265
+ return __awaiter(this, void 0, void 0, function* () {
266
+ try {
267
+ // 1. 将整包重新推到miwear中(TODO:增量更新)
268
+ // adb push快应用到模拟器的/data/app目录
269
+ // aspect应用后续要考虑各种形状表盘的推包
270
+ const buildedFilesPath = this.isRpk
271
+ ? this.projectPath
272
+ : this.isDistributedApp
273
+ ? ((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.dist) ||
274
+ path_1.default.join(this.projectPath, './build', `${this.projectInfo.package}.watch`)
275
+ : path_1.default.join(this.projectPath, './build');
276
+ yield this.pushRpk(buildedFilesPath);
277
+ this.reloadApp();
278
+ }
279
+ catch (e) {
280
+ shared_utils_1.ColorConsole.error(`${e}`);
281
+ }
282
+ });
283
+ }
284
+ /**
285
+ * 重启应用
286
+ */
287
+ reloadApp() {
288
+ return __awaiter(this, void 0, void 0, function* () {
289
+ const { package: appPackageName } = this.projectInfo;
290
+ this.startupQuickApp(this.startOptions);
291
+ shared_utils_1.ColorConsole.info(`### Emulator start ${appPackageName} successfully`);
292
+ });
293
+ }
294
+ reboot() {
295
+ return __awaiter(this, void 0, void 0, function* () {
296
+ const rebootCmd = `adb -s ${this.sn} shell reboot`;
297
+ shared_utils_1.ColorConsole.log(`### Emulator ### Excuting adb cmd: ${rebootCmd}`);
298
+ yield adbMiwt.execAdbCmdAsync(rebootCmd);
299
+ return this.isConnected();
181
300
  });
182
301
  }
183
302
  }
@@ -1,7 +1,15 @@
1
1
  import { INewGoldfishInstanceParams } from '../typing/Instance';
2
2
  import CommonInstance from './common';
3
3
  import GoldfishInstance from './dev';
4
- import MiwearInstance from "./miwear";
4
+ import MiwearInstance from './miwear';
5
5
  import OldGoldfishInstance from './preDev';
6
+ import PreInstance from './pre';
7
+ /**
8
+ * 根据镜像决定使用哪个instance
9
+ * Vela正式版(4.0) -> MiwearInstance
10
+ * Vela正式版(不带 miwear 版本) -> PreInstance
11
+ * Vela开发版(dev, 0.0.2) -> OldGoldfishInstance
12
+ * Vela开发版(dev),除0.0.2的其他版本 -> GoldfishInstance
13
+ */
6
14
  declare function findInstance(avdName: string, params: INewGoldfishInstanceParams): GoldfishInstance | MiwearInstance | OldGoldfishInstance | undefined;
7
- export { CommonInstance, GoldfishInstance, MiwearInstance, OldGoldfishInstance, findInstance };
15
+ export { CommonInstance, GoldfishInstance, MiwearInstance, OldGoldfishInstance, PreInstance, findInstance };
@@ -3,8 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.findInstance = exports.OldGoldfishInstance = exports.MiwearInstance = exports.GoldfishInstance = exports.CommonInstance = void 0;
7
- const ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
6
+ exports.findInstance = exports.PreInstance = exports.OldGoldfishInstance = exports.MiwearInstance = exports.GoldfishInstance = exports.CommonInstance = void 0;
7
+ const shared_utils_1 = require("@aiot-toolkit/shared-utils");
8
8
  const avd_1 = __importDefault(require("../avd"));
9
9
  const common_1 = __importDefault(require("./common"));
10
10
  exports.CommonInstance = common_1.default;
@@ -14,13 +14,25 @@ const miwear_1 = __importDefault(require("./miwear"));
14
14
  exports.MiwearInstance = miwear_1.default;
15
15
  const preDev_1 = __importDefault(require("./preDev"));
16
16
  exports.OldGoldfishInstance = preDev_1.default;
17
+ const pre_1 = __importDefault(require("./pre"));
18
+ exports.PreInstance = pre_1.default;
19
+ /**
20
+ * 根据镜像决定使用哪个instance
21
+ * Vela正式版(4.0) -> MiwearInstance
22
+ * Vela正式版(不带 miwear 版本) -> PreInstance
23
+ * Vela开发版(dev, 0.0.2) -> OldGoldfishInstance
24
+ * Vela开发版(dev),除0.0.2的其他版本 -> GoldfishInstance
25
+ */
17
26
  function findInstance(avdName, params) {
18
27
  const { sdkHome, avdHome } = params;
19
28
  const { avdImagePath } = new avd_1.default({ sdkHome, avdHome }).getVelaAvdInfo(avdName);
20
29
  if (!avdImagePath) {
21
- ColorConsole_1.default.throw(`### Emulator ### Unable to find vela image via avd`);
30
+ shared_utils_1.ColorConsole.throw(`### Emulator ### Unable to find vela image via avd`);
22
31
  return;
23
32
  }
33
+ if (avdImagePath.includes('vela-pre-4.0')) {
34
+ return new pre_1.default(params);
35
+ }
24
36
  if (avdImagePath.includes('release')) {
25
37
  return new miwear_1.default(params);
26
38
  }
@@ -2,27 +2,76 @@ import { INewGoldfishInstanceParams, IStartOptions } from '../typing/Instance';
2
2
  import CommonInstance from './common';
3
3
  /**
4
4
  * MiwearInstance
5
- * 针对 vela4.0 的镜像
5
+ * 针对 Vela正式版(4.0)的镜像
6
6
  */
7
7
  declare class MiwearInstance extends CommonInstance {
8
+ private params;
9
+ quickappStartedFlag: RegExp;
8
10
  private appPathInEmulator;
9
11
  private debugSocket?;
10
12
  private reconnectCount;
13
+ emulatorStartedFlag: RegExp;
11
14
  constructor(params: INewGoldfishInstanceParams);
12
- /** 在goldfish模拟器中运行快应用 */
15
+ /**
16
+ * 1. 启动模拟器
17
+ * 2. 启动成功后,adb连接模拟器
18
+ * 3. 连接成功后,在模拟器中启动快应用
19
+ */
13
20
  start(options: IStartOptions): Promise<void>;
14
- /** 启动goldfish模拟器 */
21
+ /**
22
+ * 启动模拟器
23
+ * 1. 通过options生成模拟器的启动命令
24
+ * 2. 执行启动命令
25
+ * 3. 判断模拟器是否启动成功
26
+ * 3.1 若disableNSH=true,输出流中匹配到/quickapp_rpk_installer_init|rpk installer init done/,认为模拟器启动成功了
27
+ * 3.2 若disableNSH=false,认为8s过后模拟器启动成功了
28
+ * @param options
29
+ * @returns
30
+ */
15
31
  startGoldfish(options: IStartOptions): Promise<void>;
16
- /** 通过adb连接模拟器 */
17
- connectGoldfish(): Promise<boolean>;
18
- /** 在goldfish中启动快应用 */
32
+ /**
33
+ * 在模拟器中启动快应用
34
+ * 1. 检查release目录是否有打包好的rpk
35
+ * 2. 检查当前是否为调试模式.
36
+ * 若是,将debugger_ip.cfg推到模拟器的/data/目录下
37
+ * 若否,则要删除模拟器中已有的data/debugger_ip.cfg
38
+ * 3. 调用installRpkToAppList将当前快应用安装到模拟器的应用列表中
39
+ * @param options
40
+ */
19
41
  startupQuickApp(options: IStartOptions): Promise<void>;
20
- /** 将快应用安装到应用列表 */
42
+ /**
43
+ * 将快应用安装到模拟器的应用列表
44
+ * 1. 使用adb push将打包好的rpk推到模拟器的/data/quickapp/app/
45
+ * 2. nsh中调用pm install命令安装应用
46
+ * @param rpkPath rpk的绝对目录
47
+ * @param targetDir 要将rpk放到模拟器的哪个目录下
48
+ */
21
49
  installRpkToAppList(rpkPath: string, targetDir: string): Promise<void>;
22
- initDebugSocket(): Promise<void> | undefined;
23
- /** 通知模拟器更新 */
50
+ /** 使用am start启动快应用 */
51
+ launchQuickapp(): Promise<void>;
52
+ /** 连接模拟器中的调试服务,创建debugSocket
53
+ * 主要用于热更新时,通过debugSocket通知调试服务更新页面
54
+ * 设置了重连机制,会重复连接8次
55
+ */
56
+ initDebugSocket(): Promise<void>;
57
+ /** 通知模拟器更新
58
+ * 1. 确保已经成功连接模拟器中的调试服务
59
+ * 2. 使用adb push将build文件下的内容推到/data/quickapp/app/${packageName}
60
+ * 3. 发送Page.reload命令给调试服务,通知更新
61
+ */
24
62
  handleUpdate(): Promise<void>;
25
- /** 创建server */
63
+ /** 热更新时push目录 */
64
+ pushBuild(): Promise<void>;
65
+ /** 在模拟器中重启快应用(基于am命令,需要保证镜像中已经有am功能)
66
+ * 1. 使用adb push将build文件下的内容推到/data/quickapp/app/${packageName}
67
+ * 2. nsh中执行am stop命令退出快应用
68
+ * 3. nsh中执行am start命令启动快应用
69
+ */
70
+ pushAndReloadApp(): Promise<void>;
71
+ reloadApp(): Promise<void>;
72
+ /**
73
+ * 创建server端,监听打包过程中client端发来的消息
74
+ */
26
75
  createWebsockeServer(): Promise<void>;
27
76
  }
28
77
  export default MiwearInstance;