@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 +39 -34
- package/lib/instance/miwear.d.ts +1 -0
- package/lib/instance/miwear.js +51 -18
- package/package.json +4 -5
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
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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 {
|
package/lib/instance/miwear.d.ts
CHANGED
|
@@ -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>;
|
package/lib/instance/miwear.js
CHANGED
|
@@ -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
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
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.
|
|
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.
|
|
39
|
-
"@aiot-toolkit/shared-utils": "2.0.2-dev.
|
|
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
|
}
|