@aiot-toolkit/emulator 2.0.2-dev.5 → 2.0.2-dev.7

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 CHANGED
@@ -3,6 +3,7 @@ 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
+ const ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
6
7
  const fs_1 = __importDefault(require("fs"));
7
8
  const path_1 = __importDefault(require("path"));
8
9
  const constants_1 = require("../static/constants");
@@ -20,6 +21,9 @@ class VelaAvdCls {
20
21
  const { avdHome, sdkHome } = avdResourcePaths;
21
22
  this.avdHome = avdHome || constants_1.defaultAvdHome;
22
23
  this.sdkHome = sdkHome || constants_1.defaultSDKHome;
24
+ if (!fs_1.default.existsSync(this.avdHome)) {
25
+ fs_1.default.mkdirSync(this.avdHome, { recursive: true });
26
+ }
23
27
  }
24
28
  createVelaAvd(avdParams) {
25
29
  const { avdName, avdArch, avdWidth, avdHeight, avdSkin, avdImagePath = constants_1.defaultImageHome } = avdParams;
@@ -62,7 +66,7 @@ class VelaAvdCls {
62
66
  return true;
63
67
  }
64
68
  catch (e) {
65
- return false;
69
+ throw (`createVelaAvd: ${e.message}`);
66
70
  }
67
71
  }
68
72
  getVelaAvdInfo(avdName) {
@@ -76,24 +80,30 @@ class VelaAvdCls {
76
80
  };
77
81
  const currAvdDir = path_1.default.resolve(this.avdHome, `${avdName}.avd`);
78
82
  const configIni = path_1.default.resolve(currAvdDir, 'config.ini');
79
- const contents = fs_1.default.readFileSync(configIni, 'utf-8');
80
- // 这里需要使用惰性匹配
81
- const archRegex = /hw.cpu.arch = ([\d\D]+?)\n/;
82
- const archMatcher = contents.match(archRegex);
83
- const heightRegex = /hw.lcd.height = ([\d\D]+?)\n/;
84
- const heightMatcher = contents.match(heightRegex);
85
- const widthRegex = /hw.lcd.width = ([\d\D]+?)\n/;
86
- const widthMatcher = contents.match(widthRegex);
87
- const skinRegex = /skin.name = ([\d\D]+?)\n/;
88
- const skinMatcher = contents.match(skinRegex);
89
- const imagePathRegex = /image.sysdir.1 = ([\d\D]+?)\n/;
90
- const imagePathMather = contents.match(imagePathRegex);
91
- archMatcher && (avdInfo.avdArch = archMatcher[1]);
92
- heightMatcher && (avdInfo.avdHeight = heightMatcher[1]);
93
- widthMatcher && (avdInfo.avdWidth = widthMatcher[1]);
94
- skinMatcher && (avdInfo.avdSkin = skinMatcher[1]);
95
- imagePathMather && (avdInfo.avdImagePath = imagePathMather[1]);
96
- return avdInfo;
83
+ try {
84
+ const contents = fs_1.default.readFileSync(configIni, 'utf-8');
85
+ // 这里需要使用惰性匹配
86
+ const archRegex = /hw.cpu.arch = ([\d\D]+?)\n/;
87
+ const archMatcher = contents.match(archRegex);
88
+ const heightRegex = /hw.lcd.height = ([\d\D]+?)\n/;
89
+ const heightMatcher = contents.match(heightRegex);
90
+ const widthRegex = /hw.lcd.width = ([\d\D]+?)\n/;
91
+ const widthMatcher = contents.match(widthRegex);
92
+ const skinRegex = /skin.name = ([\d\D]+?)\n/;
93
+ const skinMatcher = contents.match(skinRegex);
94
+ const imagePathRegex = /image.sysdir.1 = ([\d\D]+?)\n/;
95
+ const imagePathMather = contents.match(imagePathRegex);
96
+ archMatcher && (avdInfo.avdArch = archMatcher[1]);
97
+ heightMatcher && (avdInfo.avdHeight = heightMatcher[1]);
98
+ widthMatcher && (avdInfo.avdWidth = widthMatcher[1]);
99
+ skinMatcher && (avdInfo.avdSkin = skinMatcher[1]);
100
+ imagePathMather && (avdInfo.avdImagePath = imagePathMather[1]);
101
+ return avdInfo;
102
+ }
103
+ catch (err) {
104
+ ColorConsole_1.default.log(`getVelaAvdInfo: ${err.message}`);
105
+ return avdInfo;
106
+ }
97
107
  }
98
108
  deleteVelaAvd(avdName) {
99
109
  const avdDir = path_1.default.resolve(this.avdHome, `${avdName}.avd`);
@@ -108,23 +118,18 @@ class VelaAvdCls {
108
118
  }
109
119
  }
110
120
  getVelaAvdList() {
111
- try {
112
- const avdList = [];
113
- const files = fs_1.default.readdirSync(constants_1.defaultAvdHome);
114
- const regex = /^(Vela[\d\D]*)\.avd$/;
115
- for (const fileName of files) {
116
- const matcher = fileName.match(regex);
117
- if (matcher) {
118
- const avdName = matcher[1];
119
- const avdInfo = this.getVelaAvdInfo(avdName);
120
- avdList.push(avdInfo);
121
- }
121
+ const avdList = [];
122
+ const files = fs_1.default.readdirSync(this.avdHome);
123
+ const regex = /^(Vela[\d\D]*)\.avd$/;
124
+ for (const fileName of files) {
125
+ const matcher = fileName.match(regex);
126
+ if (matcher) {
127
+ const avdName = matcher[1];
128
+ const avdInfo = this.getVelaAvdInfo(avdName);
129
+ avdList.push(avdInfo);
122
130
  }
123
- return avdList;
124
- }
125
- catch (err) {
126
- return [];
127
131
  }
132
+ return avdList;
128
133
  }
129
134
  getVelaSkinList() {
130
135
  try {
@@ -7,6 +7,7 @@ import CommonInstance from './common';
7
7
  declare class MiwearInstance extends CommonInstance {
8
8
  private appPathInEmulator;
9
9
  private debugSocket?;
10
+ private reconnectCount;
10
11
  constructor(params: INewGoldfishInstanceParams);
11
12
  /** 在goldfish模拟器中运行快应用 */
12
13
  start(options: IStartOptions): Promise<void>;
@@ -40,12 +40,14 @@ const ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/C
40
40
  const adbMiwt = __importStar(require("@miwt/adb"));
41
41
  const child_process_1 = require("child_process");
42
42
  const fs_extra_1 = __importDefault(require("fs-extra"));
43
+ const os_1 = __importDefault(require("os"));
43
44
  const path_1 = __importDefault(require("path"));
44
45
  const portfinder_1 = __importDefault(require("portfinder"));
45
46
  const ws_1 = __importStar(require("ws"));
46
47
  const constants_1 = require("../static/constants");
47
48
  const utils_1 = require("../utils");
48
49
  const common_1 = __importDefault(require("./common"));
50
+ const MAX_RECONNECT_COUNT = 8;
49
51
  /**
50
52
  * MiwearInstance
51
53
  * 针对 vela4.0 的镜像
@@ -54,6 +56,7 @@ class MiwearInstance extends common_1.default {
54
56
  constructor(params) {
55
57
  super(params);
56
58
  this.appPathInEmulator = '/data/quickapp/app';
59
+ this.reconnectCount = 0;
57
60
  }
58
61
  /** 在goldfish模拟器中运行快应用 */
59
62
  start(options) {
@@ -95,6 +98,7 @@ class MiwearInstance extends common_1.default {
95
98
  // 端口映射
96
99
  let portMappingStr = `-network-user-mode-options hostfwd=tcp:127.0.0.1:${this.adbPort}-10.0.2.15:5555`;
97
100
  if (devtool) {
101
+ this.debugPort = yield portfinder_1.default.getPortPromise({ port: this.debugPort });
98
102
  portMappingStr += `,hostfwd=tcp:127.0.0.1:${this.debugPort}-10.0.2.15:101`;
99
103
  }
100
104
  // 文件系统配置,第一次使用fatfs镜像挂载,后续使用adb push更新应用
@@ -137,7 +141,7 @@ class MiwearInstance extends common_1.default {
137
141
  const msg = data.toString();
138
142
  const stdoutCb = options.stdoutCallback || console.log;
139
143
  stdoutCb(msg);
140
- if (msg.match(/quickapp_rpk_installer_init | rpk installer init done/)) {
144
+ if (msg.match(/quickapp_rpk_installer_init|rpk installer init done/)) {
141
145
  ColorConsole_1.default.info(`### Emulator ### Goldfish emulator starts successfully`);
142
146
  resolve();
143
147
  }
@@ -226,12 +230,12 @@ class MiwearInstance extends common_1.default {
226
230
  yield (0, utils_1.sleep)(2000);
227
231
  }
228
232
  // 2. adb push应用的rpk
229
- const pushCmd = `adb -s ${sn} push ${rpkPath} ${targetDir}`;
233
+ const targetPath = `${targetDir}/${packageName}.rpk`;
234
+ const pushCmd = `adb -s ${sn} push ${rpkPath} ${targetPath}`;
230
235
  ColorConsole_1.default.info(`### Emulator ### Excuting cmd: ${pushCmd}`);
231
236
  yield adbMiwt.execAdbCmdAsync(pushCmd);
232
237
  yield (0, utils_1.sleep)(100);
233
238
  // 3. 安装应用
234
- const targetPath = `${targetDir}/${rpkName}`;
235
239
  const installCmd = `adb -s ${sn} shell pm install ${targetPath}`;
236
240
  ColorConsole_1.default.info(`### Emulator ### Excuting cmd: ${installCmd}`);
237
241
  adbMiwt.execAdbCmdAsync(installCmd);
@@ -240,36 +244,65 @@ class MiwearInstance extends common_1.default {
240
244
  });
241
245
  }
242
246
  initDebugSocket() {
243
- if (this.debugSocket) {
247
+ if (this.debugSocket && this.debugSocket.OPEN) {
244
248
  return Promise.resolve();
245
249
  }
246
250
  this.debugSocket = new ws_1.default(`ws://localhost:${this.debugPort}`);
247
- this.debugSocket.onopen = e => {
248
- ColorConsole_1.default.info(`### debugSocket connect success`);
251
+ this.debugSocket.onopen = () => {
252
+ ColorConsole_1.default.info(`### Emulator debugSocket connect success`);
249
253
  return Promise.resolve();
250
254
  };
251
255
  this.debugSocket.onerror = (e) => {
252
- ColorConsole_1.default.error(`### Emulator ${e.data}`);
256
+ var _a;
257
+ // 重连机制
258
+ (_a = this.debugSocket) === null || _a === void 0 ? void 0 : _a.terminate();
259
+ if (this.reconnectCount < MAX_RECONNECT_COUNT) {
260
+ ColorConsole_1.default.info(`### Emulator the ${this.reconnectCount + 1}th time to reconnect debug server`);
261
+ this.reconnectCount++;
262
+ setTimeout(() => this.initDebugSocket(), 2000);
263
+ }
264
+ else {
265
+ this.debugSocket = undefined;
266
+ this.reconnectCount = 0;
267
+ return Promise.reject(`### Emulator debugSocket connect failed`);
268
+ }
253
269
  };
254
270
  this.debugSocket.onclose = (e) => {
255
- ColorConsole_1.default.error(`### Emulator debugSocket connect close: ${e.data}`);
256
271
  this.debugSocket = undefined;
272
+ this.reconnectCount = 0;
273
+ ColorConsole_1.default.log(`### Emulator debugSocket connect close: ${e.data}`);
257
274
  };
258
275
  }
259
276
  /** 通知模拟器更新 */
260
277
  handleUpdate() {
261
278
  var _a, _b;
262
279
  return __awaiter(this, void 0, void 0, function* () {
263
- yield this.initDebugSocket();
264
- // 1. 将整包重新推到miwear中(TODO:增量更新)
265
- const sn = `127.0.0.1:${this.adbPort}`;
266
- const { package: appPackageName } = this.projectInfo;
267
- const sourcePath = path_1.default.resolve(this.projectPath, './build/*');
268
- yield adbMiwt.execAdbCmdAsync(`adb -s ${sn} push ${sourcePath} ${this.appPathInEmulator}/${appPackageName}`);
269
- ColorConsole_1.default.info(`### Emulator push to ${this.appPathInEmulator}/${appPackageName} successfully`);
270
- // 2. 下发CDP命令给调试服务告知刷新
271
- if (((_a = this.debugSocket) === null || _a === void 0 ? void 0 : _a.readyState) === ws_1.default.OPEN) {
272
- (_b = this.debugSocket) === null || _b === void 0 ? void 0 : _b.send(JSON.stringify({ id: 10000, method: 'Page.reload', params: {} }));
280
+ try {
281
+ this.reconnectCount = 0;
282
+ yield this.initDebugSocket();
283
+ // 1. 将整包重新推到miwear中(TODO:增量更新)
284
+ const sn = `127.0.0.1:${this.adbPort}`;
285
+ const { package: appPackageName } = this.projectInfo;
286
+ // windows平台adb push时无法使用通配符,需另外处理
287
+ if (os_1.default.platform() === 'win32') {
288
+ const rmCmd = `adb -s ${sn} shell rm -r ${this.appPathInEmulator}/${appPackageName}`;
289
+ yield adbMiwt.execAdbCmdAsync(rmCmd);
290
+ const sourcePath = path_1.default.resolve(this.projectPath, './build');
291
+ const pushCmd = `adb -s ${sn} push ${sourcePath} ${this.appPathInEmulator}/${appPackageName}`;
292
+ yield adbMiwt.execAdbCmdAsync(pushCmd);
293
+ }
294
+ else {
295
+ const sourcePath = path_1.default.resolve(this.projectPath, './build/*');
296
+ yield adbMiwt.execAdbCmdAsync(`adb -s ${sn} push ${sourcePath} ${this.appPathInEmulator}/${appPackageName}`);
297
+ }
298
+ ColorConsole_1.default.info(`### Emulator push to ${this.appPathInEmulator}/${appPackageName} successfully`);
299
+ // 2. 下发CDP命令给调试服务告知刷新
300
+ if (((_a = this.debugSocket) === null || _a === void 0 ? void 0 : _a.readyState) === ws_1.default.OPEN) {
301
+ (_b = this.debugSocket) === null || _b === void 0 ? void 0 : _b.send(JSON.stringify({ id: 10000, method: 'Page.reload', params: {} }));
302
+ }
303
+ }
304
+ catch (e) {
305
+ ColorConsole_1.default.error(`${e}`);
273
306
  }
274
307
  });
275
308
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiot-toolkit/emulator",
3
- "version": "2.0.2-dev.5",
3
+ "version": "2.0.2-dev.7",
4
4
  "description": "vela emulator tool.",
5
5
  "homepage": "",
6
6
  "license": "ISC",
@@ -35,10 +35,9 @@
35
35
  "emulator"
36
36
  ],
37
37
  "dependencies": {
38
- "@aiot-toolkit/aiotpack": "2.0.2-dev.5",
39
- "@aiot-toolkit/shared-utils": "2.0.2-dev.5",
38
+ "@aiot-toolkit/aiotpack": "2.0.2-dev.7",
39
+ "@aiot-toolkit/shared-utils": "2.0.2-dev.7",
40
40
  "find-process": "^1.4.7",
41
41
  "portfinder": "^1.0.32"
42
- },
43
- "gitHead": "0c123fdd458966a4ca438cca03cc9efc2b5f634c"
42
+ }
44
43
  }