@aiot-toolkit/emulator 2.0.2-beta.10 → 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.
- package/lib/avd/index.js +8 -8
- package/lib/index.d.ts +3 -1
- package/lib/index.js +4 -1
- package/lib/instance/common.d.ts +5 -0
- package/lib/instance/common.js +25 -11
- package/lib/instance/dev.d.ts +11 -1
- package/lib/instance/dev.js +90 -45
- package/lib/instance/index.d.ts +4 -2
- package/lib/instance/index.js +9 -3
- package/lib/instance/miwear.d.ts +3 -0
- package/lib/instance/miwear.js +66 -95
- package/lib/instance/pre.d.ts +8 -0
- package/lib/instance/pre.js +19 -0
- package/lib/instance/preDev.js +25 -26
- package/lib/static/constants.js +2 -2
- package/lib/typing/Instance.d.ts +2 -2
- package/lib/utils/index.d.ts +20 -0
- package/lib/utils/index.js +65 -8
- package/package.json +4 -4
package/lib/avd/index.js
CHANGED
|
@@ -3,18 +3,18 @@ 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
|
|
6
|
+
const shared_utils_1 = require("@aiot-toolkit/shared-utils");
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const os_1 = __importDefault(require("os"));
|
|
8
9
|
const path_1 = __importDefault(require("path"));
|
|
9
10
|
const constants_1 = require("../static/constants");
|
|
10
11
|
const Avd_1 = require("../typing/Avd");
|
|
11
|
-
const os_1 = __importDefault(require("os"));
|
|
12
12
|
const EAvdParamsToIni = {
|
|
13
|
-
|
|
14
|
-
abiType: 'armeabi-v7a'
|
|
13
|
+
arm: {
|
|
14
|
+
abiType: 'armeabi-v7a'
|
|
15
15
|
},
|
|
16
|
-
|
|
17
|
-
abiType: 'arm64-v8a'
|
|
16
|
+
arm64: {
|
|
17
|
+
abiType: 'arm64-v8a'
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
20
|
class VelaAvdCls {
|
|
@@ -81,7 +81,7 @@ class VelaAvdCls {
|
|
|
81
81
|
return true;
|
|
82
82
|
}
|
|
83
83
|
catch (e) {
|
|
84
|
-
throw
|
|
84
|
+
throw `createVelaAvd: ${e.message}`;
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
/** 根据AVD名字获取模拟器的详细信息 */
|
|
@@ -117,7 +117,7 @@ class VelaAvdCls {
|
|
|
117
117
|
return avdInfo;
|
|
118
118
|
}
|
|
119
119
|
catch (err) {
|
|
120
|
-
|
|
120
|
+
shared_utils_1.ColorConsole.log(`getVelaAvdInfo: ${err.message}`);
|
|
121
121
|
return avdInfo;
|
|
122
122
|
}
|
|
123
123
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { default as VelaAvdCls } from './avd';
|
|
2
|
+
import { getSystemArch } from './utils';
|
|
2
3
|
export * from './instance';
|
|
3
4
|
export * from './typing/Avd';
|
|
4
5
|
export * from './typing/Instance';
|
|
5
|
-
export
|
|
6
|
+
export * from './static/constants';
|
|
7
|
+
export { VelaAvdCls, getSystemArch };
|
package/lib/index.js
CHANGED
|
@@ -17,9 +17,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.VelaAvdCls = void 0;
|
|
20
|
+
exports.getSystemArch = exports.VelaAvdCls = void 0;
|
|
21
21
|
const avd_1 = __importDefault(require("./avd"));
|
|
22
22
|
Object.defineProperty(exports, "VelaAvdCls", { enumerable: true, get: function () { return avd_1.default; } });
|
|
23
|
+
const utils_1 = require("./utils");
|
|
24
|
+
Object.defineProperty(exports, "getSystemArch", { enumerable: true, get: function () { return utils_1.getSystemArch; } });
|
|
23
25
|
__exportStar(require("./instance"), exports);
|
|
24
26
|
__exportStar(require("./typing/Avd"), exports);
|
|
25
27
|
__exportStar(require("./typing/Instance"), exports);
|
|
28
|
+
__exportStar(require("./static/constants"), exports);
|
package/lib/instance/common.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { INewGoldfishInstanceParams, IStartOptions } from '../typing/Instance';
|
|
|
7
7
|
* CommonInstance
|
|
8
8
|
*/
|
|
9
9
|
declare class CommonInstance {
|
|
10
|
+
quickappStartedFlag: RegExp;
|
|
10
11
|
projectPath: string;
|
|
11
12
|
sdkHome: string;
|
|
12
13
|
avdHome: string;
|
|
@@ -23,6 +24,10 @@ declare class CommonInstance {
|
|
|
23
24
|
getEmulatorBinPath(): string;
|
|
24
25
|
/** 在goldfish模拟器中运行快应用 */
|
|
25
26
|
start(options: IStartOptions): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* 判断模拟器是否 ready
|
|
29
|
+
*/
|
|
30
|
+
isConnected(): Promise<boolean>;
|
|
26
31
|
/**
|
|
27
32
|
* 通过adb连接模拟器。
|
|
28
33
|
* 时间限制为 @param timeout 秒,超时则表示连接失败
|
package/lib/instance/common.js
CHANGED
|
@@ -36,21 +36,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
};
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
38
|
const UxFileUtils_1 = __importDefault(require("@aiot-toolkit/aiotpack/lib/utils/ux/UxFileUtils"));
|
|
39
|
-
const
|
|
39
|
+
const shared_utils_1 = require("@aiot-toolkit/shared-utils");
|
|
40
40
|
const adbMiwt = __importStar(require("@miwt/adb"));
|
|
41
41
|
const child_process_1 = require("child_process");
|
|
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 = require("ws");
|
|
45
46
|
const avd_1 = __importDefault(require("../avd"));
|
|
46
47
|
const constants_1 = require("../static/constants");
|
|
47
48
|
const utils_1 = require("../utils");
|
|
48
|
-
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
49
49
|
/**
|
|
50
50
|
* CommonInstance
|
|
51
51
|
*/
|
|
52
52
|
class CommonInstance {
|
|
53
53
|
constructor(params) {
|
|
54
|
+
this.quickappStartedFlag = /__loadChunks/;
|
|
54
55
|
this.isFirstStart = true;
|
|
55
56
|
this.isDistributedApp = false;
|
|
56
57
|
this.projectPath = params.projectPath;
|
|
@@ -81,6 +82,19 @@ class CommonInstance {
|
|
|
81
82
|
start(options) {
|
|
82
83
|
return __awaiter(this, void 0, void 0, function* () { });
|
|
83
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* 判断模拟器是否 ready
|
|
87
|
+
*/
|
|
88
|
+
isConnected() {
|
|
89
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
90
|
+
return (0, utils_1.tryRun)(() => __awaiter(this, void 0, void 0, function* () {
|
|
91
|
+
const devices = yield adbMiwt.getAdbDevices();
|
|
92
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### adb devices: ${JSON.stringify(devices)}`);
|
|
93
|
+
const curDev = devices.find((t) => t.sn === this.sn);
|
|
94
|
+
return (curDev === null || curDev === void 0 ? void 0 : curDev.status) === 'device';
|
|
95
|
+
}), 10, 500);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
84
98
|
/**
|
|
85
99
|
* 通过adb连接模拟器。
|
|
86
100
|
* 时间限制为 @param timeout 秒,超时则表示连接失败
|
|
@@ -95,14 +109,14 @@ class CommonInstance {
|
|
|
95
109
|
while (enableLoop && !adbConnected) {
|
|
96
110
|
if (needKill) {
|
|
97
111
|
const adbKillCmd = `adb kill-server`;
|
|
98
|
-
|
|
112
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Excuting adb cmd: ${adbKillCmd}`);
|
|
99
113
|
yield adbMiwt.execAdbCmdAsync(adbKillCmd);
|
|
100
114
|
}
|
|
101
115
|
const str = yield this.connectDevice();
|
|
102
|
-
|
|
116
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### ${str}`);
|
|
103
117
|
// 查询模拟器的状态是否为“device”
|
|
104
118
|
const devices = yield adbMiwt.getAdbDevices();
|
|
105
|
-
|
|
119
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### adb devices: ${JSON.stringify(devices)}`);
|
|
106
120
|
const curDev = devices.find((t) => t.sn === this.sn);
|
|
107
121
|
if ((curDev === null || curDev === void 0 ? void 0 : curDev.status) === 'offline')
|
|
108
122
|
needKill = true;
|
|
@@ -141,7 +155,7 @@ class CommonInstance {
|
|
|
141
155
|
}
|
|
142
156
|
}
|
|
143
157
|
catch (err) {
|
|
144
|
-
|
|
158
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### kill process get error :\n${err.stack}`);
|
|
145
159
|
}
|
|
146
160
|
}
|
|
147
161
|
}
|
|
@@ -179,13 +193,13 @@ class CommonInstance {
|
|
|
179
193
|
port: (_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.serverPort
|
|
180
194
|
});
|
|
181
195
|
wsServer.on('connection', (socket) => {
|
|
182
|
-
|
|
196
|
+
shared_utils_1.ColorConsole.success(`### App Socket server ### Websocket connects to websocket server`);
|
|
183
197
|
socket.on('error', (err) => {
|
|
184
|
-
|
|
198
|
+
shared_utils_1.ColorConsole.error(`### App Socket server ### Websocket server error: ${err.message}`);
|
|
185
199
|
});
|
|
186
200
|
socket.on('message', (data) => {
|
|
187
201
|
const message = JSON.parse(data.toString());
|
|
188
|
-
|
|
202
|
+
shared_utils_1.ColorConsole.log(`### App Socket server ### Websocket server get data: ${data}`);
|
|
189
203
|
if (message.type === 'restart') {
|
|
190
204
|
this.restart();
|
|
191
205
|
}
|
|
@@ -199,7 +213,7 @@ class CommonInstance {
|
|
|
199
213
|
connectDevice() {
|
|
200
214
|
return __awaiter(this, void 0, void 0, function* () {
|
|
201
215
|
const adbConnectCmd = `adb connect ${this.sn}`;
|
|
202
|
-
|
|
216
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Excuting adb cmd: ${adbConnectCmd}`);
|
|
203
217
|
let pending = true;
|
|
204
218
|
const p1 = adbMiwt.execAdbCmdAsync(adbConnectCmd);
|
|
205
219
|
let timer;
|
|
@@ -209,7 +223,7 @@ class CommonInstance {
|
|
|
209
223
|
timer = setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
210
224
|
if (pending) {
|
|
211
225
|
const adbKillCmd = `adb kill-server`;
|
|
212
|
-
|
|
226
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Excuting adb cmd: ${adbKillCmd}`);
|
|
213
227
|
yield adbMiwt.execAdbCmdAsync(adbKillCmd);
|
|
214
228
|
}
|
|
215
229
|
resolve();
|
package/lib/instance/dev.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { INewGoldfishInstanceParams, IStartOptions } from '../typing/Instance';
|
|
2
2
|
import CommonInstance from './common';
|
|
3
3
|
declare class GoldfishInstance extends CommonInstance {
|
|
4
|
-
|
|
4
|
+
appRunDir: string;
|
|
5
|
+
emulatorStartedFlag: string;
|
|
5
6
|
constructor(params: INewGoldfishInstanceParams);
|
|
6
7
|
/**
|
|
7
8
|
* 1. 启动模拟器
|
|
@@ -31,5 +32,14 @@ declare class GoldfishInstance extends CommonInstance {
|
|
|
31
32
|
* @param sourceRoot
|
|
32
33
|
*/
|
|
33
34
|
pushRpk(sourceRoot: string): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* 重新推送,然后重启应用
|
|
37
|
+
*/
|
|
38
|
+
pushAndReloadApp(): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* 重启应用
|
|
41
|
+
*/
|
|
42
|
+
reloadApp(): Promise<void>;
|
|
43
|
+
reboot(): Promise<boolean>;
|
|
34
44
|
}
|
|
35
45
|
export default GoldfishInstance;
|
package/lib/instance/dev.js
CHANGED
|
@@ -35,19 +35,19 @@ 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 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 path_1 = require("path");
|
|
42
|
-
const constants_1 = require("../static/constants");
|
|
43
|
-
const common_1 = __importDefault(require("./common"));
|
|
44
|
-
const os_1 = __importDefault(require("os"));
|
|
45
|
-
const fs_1 = __importDefault(require("fs"));
|
|
46
41
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
42
|
+
const fs_1 = __importDefault(require("fs"));
|
|
43
|
+
const os_1 = __importDefault(require("os"));
|
|
44
|
+
const path_1 = __importDefault(require("path"));
|
|
45
|
+
const common_1 = __importDefault(require("./common"));
|
|
47
46
|
class GoldfishInstance extends common_1.default {
|
|
48
47
|
constructor(params) {
|
|
49
48
|
super(params);
|
|
50
49
|
this.appRunDir = '/data/app';
|
|
50
|
+
this.emulatorStartedFlag = '(NSH)';
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
53
|
* 1. 启动模拟器
|
|
@@ -57,12 +57,12 @@ class GoldfishInstance extends common_1.default {
|
|
|
57
57
|
start(options) {
|
|
58
58
|
return __awaiter(this, void 0, void 0, function* () {
|
|
59
59
|
this.startOptions = options;
|
|
60
|
-
this.sn = `
|
|
60
|
+
this.sn = `emulator-${this.startOptions.adbPort}`;
|
|
61
61
|
// 启动模拟器
|
|
62
62
|
yield this.startGoldfish(options);
|
|
63
|
-
const connected = yield this.
|
|
63
|
+
const connected = yield this.isConnected();
|
|
64
64
|
if (connected) {
|
|
65
|
-
|
|
65
|
+
shared_utils_1.ColorConsole.log('### Emulator ### Goldfish emulator connected successfully');
|
|
66
66
|
if (this.isFirstStart && this.startOptions.serverPort) {
|
|
67
67
|
yield this.createWebsockeServer();
|
|
68
68
|
}
|
|
@@ -72,8 +72,8 @@ class GoldfishInstance extends common_1.default {
|
|
|
72
72
|
? this.projectPath
|
|
73
73
|
: this.isDistributedApp
|
|
74
74
|
? options.dist ||
|
|
75
|
-
path_1.
|
|
76
|
-
: path_1.
|
|
75
|
+
path_1.default.join(this.projectPath, './build', `${this.projectInfo.package}.watch`)
|
|
76
|
+
: path_1.default.join(this.projectPath, './build');
|
|
77
77
|
yield this.pushRpk(buildedFilesPath);
|
|
78
78
|
// 在模拟器中启动快应用
|
|
79
79
|
this.startupQuickApp(options);
|
|
@@ -81,7 +81,7 @@ class GoldfishInstance extends common_1.default {
|
|
|
81
81
|
}
|
|
82
82
|
else {
|
|
83
83
|
const msg = '### Emulator ### Failed to connect emulator, please check whether the adb is normal';
|
|
84
|
-
|
|
84
|
+
shared_utils_1.ColorConsole.throw(msg);
|
|
85
85
|
throw new Error(msg);
|
|
86
86
|
}
|
|
87
87
|
});
|
|
@@ -95,16 +95,16 @@ class GoldfishInstance extends common_1.default {
|
|
|
95
95
|
return __awaiter(this, void 0, void 0, function* () {
|
|
96
96
|
try {
|
|
97
97
|
const { package: packageName } = this.projectInfo;
|
|
98
|
-
let vappCmd = `adb -s
|
|
98
|
+
let vappCmd = `adb -s ${this.sn} shell vapp app/${packageName} &`;
|
|
99
99
|
if (options.devtool) {
|
|
100
|
-
vappCmd = `adb -s
|
|
100
|
+
vappCmd = `adb -s ${this.sn} shell vapp --jsdebugger=10.0.2.15:101 app/${packageName} &`;
|
|
101
101
|
}
|
|
102
|
-
|
|
102
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Excuting adb cmd: ${vappCmd}`);
|
|
103
103
|
// vapp进程会一直pending,不会退出。这里必须加stdio: 'ignore',否则快应用无法运行成功
|
|
104
104
|
adbMiwt.execAdbCmdAsync(vappCmd, { stdio: 'ignore', encoding: 'utf-8' });
|
|
105
105
|
}
|
|
106
106
|
catch (e) {
|
|
107
|
-
|
|
107
|
+
shared_utils_1.ColorConsole.error(`### Emulator ### Failed to startup quickapp: ${e.message}`);
|
|
108
108
|
}
|
|
109
109
|
});
|
|
110
110
|
}
|
|
@@ -123,25 +123,25 @@ class GoldfishInstance extends common_1.default {
|
|
|
123
123
|
return __awaiter(this, void 0, void 0, function* () {
|
|
124
124
|
const { avdName, devtool, origin = 'terminal' } = options;
|
|
125
125
|
const emulatorBin = this.getEmulatorBinPath();
|
|
126
|
-
|
|
126
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### emulator path: ${emulatorBin}`);
|
|
127
127
|
const avdInfo = this.velaAvdCls.getVelaAvdInfo(avdName);
|
|
128
128
|
const { avdArch, avdImagePath } = avdInfo;
|
|
129
|
-
|
|
129
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### adb port: ${options.adbPort}`);
|
|
130
130
|
if (!avdImagePath) {
|
|
131
|
-
return
|
|
131
|
+
return shared_utils_1.ColorConsole.throw(`### Emulator ### Unable to find vela image via avd`);
|
|
132
132
|
}
|
|
133
|
-
const nuttxBinPath = path_1.
|
|
134
|
-
|
|
133
|
+
const nuttxBinPath = path_1.default.resolve(avdImagePath, 'nuttx');
|
|
134
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### nuttx path: ${nuttxBinPath}`);
|
|
135
135
|
// 端口映射
|
|
136
|
-
let portMappingStr =
|
|
136
|
+
let portMappingStr = ``;
|
|
137
137
|
if (devtool) {
|
|
138
|
-
portMappingStr +=
|
|
138
|
+
portMappingStr += `-network-user-mode-options hostfwd=tcp:127.0.0.1:${options.debugPort}-10.0.2.15:101`;
|
|
139
139
|
}
|
|
140
140
|
// 文件系统配置,第一次使用fatfs镜像挂载,后续使用adb push更新应用
|
|
141
|
-
const systemImageBin = path_1.
|
|
142
|
-
const dataImageBin = path_1.
|
|
141
|
+
const systemImageBin = path_1.default.join(avdImagePath, 'system.img');
|
|
142
|
+
const dataImageBin = path_1.default.join(avdImagePath, 'data.img');
|
|
143
143
|
// 复制可写文件到AVD目录下(多模拟器实例时需要)
|
|
144
|
-
const dataImageBinInAvd = path_1.
|
|
144
|
+
const dataImageBinInAvd = path_1.default.join(this.avdHome, `${avdName}.avd`, 'data.img');
|
|
145
145
|
if (!fs_1.default.existsSync(dataImageBinInAvd)) {
|
|
146
146
|
// data.img不存在时直接copy
|
|
147
147
|
fs_1.default.copyFileSync(dataImageBin, dataImageBinInAvd);
|
|
@@ -155,7 +155,7 @@ class GoldfishInstance extends common_1.default {
|
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
// 复制可写文件到AVD目录下(多模拟器实例时需要)
|
|
158
|
-
const systemImageBinInAvd = path_1.
|
|
158
|
+
const systemImageBinInAvd = path_1.default.join(this.avdHome, `${avdName}.avd`, 'system.img');
|
|
159
159
|
if (!fs_1.default.existsSync(systemImageBinInAvd)) {
|
|
160
160
|
// data.img不存在时直接copy
|
|
161
161
|
fs_1.default.copyFileSync(systemImageBin, systemImageBinInAvd);
|
|
@@ -186,19 +186,18 @@ class GoldfishInstance extends common_1.default {
|
|
|
186
186
|
-drive index=1,id=userdata,if=none,format=raw,file=${dataImageBinInAvd} \
|
|
187
187
|
-device virtio-blk-device,bus=virtio-mmio-bus.1,drive=userdata \
|
|
188
188
|
-device virtio-snd,bus=virtio-mmio-bus.2 -allow-host-audio -semihosting`;
|
|
189
|
-
//
|
|
189
|
+
// grpc配置
|
|
190
190
|
let windowStr = '';
|
|
191
|
-
let
|
|
192
|
-
if ((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.
|
|
193
|
-
windowStr = '-
|
|
194
|
-
|
|
195
|
-
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}`;
|
|
196
195
|
}
|
|
197
|
-
//
|
|
198
|
-
const cmd = `${emulatorBin} -nuttx -avd ${avdName} -avd-arch ${avdArch} -show-kernel -kernel ${nuttxBinPath} ${portMappingStr} ${windowStr}
|
|
196
|
+
// 启动模拟器的命令和参数
|
|
197
|
+
const cmd = `${emulatorBin} -nuttx -avd ${avdName} -port ${options.adbPort} -avd-arch ${avdArch} -show-kernel -kernel ${nuttxBinPath} ${portMappingStr} ${windowStr} ${grpcStr} -qemu ${imageMountStr}`;
|
|
199
198
|
const spawnArgs = cmd.split(' ');
|
|
200
199
|
const spawnBin = spawnArgs.shift();
|
|
201
|
-
|
|
200
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Start CMD: ${cmd}`);
|
|
202
201
|
return new Promise((resolve) => {
|
|
203
202
|
var _a, _b, _c;
|
|
204
203
|
this.goldfishProcess = (0, child_process_1.spawn)(spawnBin, spawnArgs, { stdio: 'pipe', shell: true });
|
|
@@ -211,7 +210,7 @@ class GoldfishInstance extends common_1.default {
|
|
|
211
210
|
(_b = this.goldfishProcess.stdout) === null || _b === void 0 ? void 0 : _b.pipe(process.stdout);
|
|
212
211
|
}
|
|
213
212
|
this.goldfishProcess.on('exit', (code) => {
|
|
214
|
-
|
|
213
|
+
shared_utils_1.ColorConsole.error(`### Emulator ### Goldfish emulator exited with code ${code}`);
|
|
215
214
|
if (options.exitCallback) {
|
|
216
215
|
options.exitCallback(code);
|
|
217
216
|
}
|
|
@@ -222,8 +221,8 @@ class GoldfishInstance extends common_1.default {
|
|
|
222
221
|
const stdoutCb = options.stdoutCallback || console.log;
|
|
223
222
|
stdoutCb(msg);
|
|
224
223
|
}
|
|
225
|
-
if (msg.includes(
|
|
226
|
-
|
|
224
|
+
if (msg.includes(this.emulatorStartedFlag)) {
|
|
225
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Goldfish emulator starts successfully`);
|
|
227
226
|
resolve();
|
|
228
227
|
}
|
|
229
228
|
});
|
|
@@ -236,10 +235,10 @@ class GoldfishInstance extends common_1.default {
|
|
|
236
235
|
*/
|
|
237
236
|
pushRpk(sourceRoot) {
|
|
238
237
|
return __awaiter(this, void 0, void 0, function* () {
|
|
239
|
-
const sn =
|
|
238
|
+
const sn = this.sn;
|
|
240
239
|
const { package: appPackageName } = this.projectInfo;
|
|
241
240
|
// 获取最后一层目录,比如build
|
|
242
|
-
const basename = path_1.
|
|
241
|
+
const basename = path_1.default.basename(sourceRoot);
|
|
243
242
|
if (os_1.default.platform() === 'win32' || this.projectPath.indexOf(' ') > 0) {
|
|
244
243
|
// windows系统或者项目路径有空格:1. adb push目录;2. 在模拟器中使用mv命令重命名
|
|
245
244
|
yield adbMiwt.execAdbCmdAsync(`adb -s ${sn} push ${sourceRoot} ${this.appRunDir}`);
|
|
@@ -247,11 +246,57 @@ class GoldfishInstance extends common_1.default {
|
|
|
247
246
|
}
|
|
248
247
|
else {
|
|
249
248
|
// 支持通配符处理: 1. 模拟器中mkdir创建目录 2. adb push ./XXXXX/* /XXX
|
|
250
|
-
const sourcePath = path_1.
|
|
251
|
-
|
|
252
|
-
|
|
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);
|
|
253
256
|
}
|
|
254
|
-
|
|
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();
|
|
255
300
|
});
|
|
256
301
|
}
|
|
257
302
|
}
|
package/lib/instance/index.d.ts
CHANGED
|
@@ -1,13 +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
|
|
4
|
+
import MiwearInstance from './miwear';
|
|
5
5
|
import OldGoldfishInstance from './preDev';
|
|
6
|
+
import PreInstance from './pre';
|
|
6
7
|
/**
|
|
7
8
|
* 根据镜像决定使用哪个instance
|
|
8
9
|
* Vela正式版(4.0) -> MiwearInstance
|
|
10
|
+
* Vela正式版(不带 miwear 版本) -> PreInstance
|
|
9
11
|
* Vela开发版(dev, 0.0.2) -> OldGoldfishInstance
|
|
10
12
|
* Vela开发版(dev),除0.0.2的其他版本 -> GoldfishInstance
|
|
11
13
|
*/
|
|
12
14
|
declare function findInstance(avdName: string, params: INewGoldfishInstanceParams): GoldfishInstance | MiwearInstance | OldGoldfishInstance | undefined;
|
|
13
|
-
export { CommonInstance, GoldfishInstance, MiwearInstance, OldGoldfishInstance, findInstance };
|
|
15
|
+
export { CommonInstance, GoldfishInstance, MiwearInstance, OldGoldfishInstance, PreInstance, findInstance };
|
package/lib/instance/index.js
CHANGED
|
@@ -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
|
|
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,9 +14,12 @@ 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;
|
|
17
19
|
/**
|
|
18
20
|
* 根据镜像决定使用哪个instance
|
|
19
21
|
* Vela正式版(4.0) -> MiwearInstance
|
|
22
|
+
* Vela正式版(不带 miwear 版本) -> PreInstance
|
|
20
23
|
* Vela开发版(dev, 0.0.2) -> OldGoldfishInstance
|
|
21
24
|
* Vela开发版(dev),除0.0.2的其他版本 -> GoldfishInstance
|
|
22
25
|
*/
|
|
@@ -24,9 +27,12 @@ function findInstance(avdName, params) {
|
|
|
24
27
|
const { sdkHome, avdHome } = params;
|
|
25
28
|
const { avdImagePath } = new avd_1.default({ sdkHome, avdHome }).getVelaAvdInfo(avdName);
|
|
26
29
|
if (!avdImagePath) {
|
|
27
|
-
|
|
30
|
+
shared_utils_1.ColorConsole.throw(`### Emulator ### Unable to find vela image via avd`);
|
|
28
31
|
return;
|
|
29
32
|
}
|
|
33
|
+
if (avdImagePath.includes('vela-pre-4.0')) {
|
|
34
|
+
return new pre_1.default(params);
|
|
35
|
+
}
|
|
30
36
|
if (avdImagePath.includes('release')) {
|
|
31
37
|
return new miwear_1.default(params);
|
|
32
38
|
}
|
package/lib/instance/miwear.d.ts
CHANGED
|
@@ -6,9 +6,11 @@ import CommonInstance from './common';
|
|
|
6
6
|
*/
|
|
7
7
|
declare class MiwearInstance extends CommonInstance {
|
|
8
8
|
private params;
|
|
9
|
+
quickappStartedFlag: RegExp;
|
|
9
10
|
private appPathInEmulator;
|
|
10
11
|
private debugSocket?;
|
|
11
12
|
private reconnectCount;
|
|
13
|
+
emulatorStartedFlag: RegExp;
|
|
12
14
|
constructor(params: INewGoldfishInstanceParams);
|
|
13
15
|
/**
|
|
14
16
|
* 1. 启动模拟器
|
|
@@ -65,6 +67,7 @@ declare class MiwearInstance extends CommonInstance {
|
|
|
65
67
|
* 2. nsh中执行am stop命令退出快应用
|
|
66
68
|
* 3. nsh中执行am start命令启动快应用
|
|
67
69
|
*/
|
|
70
|
+
pushAndReloadApp(): Promise<void>;
|
|
68
71
|
reloadApp(): Promise<void>;
|
|
69
72
|
/**
|
|
70
73
|
* 创建server端,监听打包过程中client端发来的消息
|
package/lib/instance/miwear.js
CHANGED
|
@@ -35,14 +35,13 @@ 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 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
41
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
42
42
|
const os_1 = __importDefault(require("os"));
|
|
43
43
|
const path_1 = __importDefault(require("path"));
|
|
44
44
|
const ws_1 = __importStar(require("ws"));
|
|
45
|
-
const constants_1 = require("../static/constants");
|
|
46
45
|
const utils_1 = require("../utils");
|
|
47
46
|
const common_1 = __importDefault(require("./common"));
|
|
48
47
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
@@ -55,8 +54,10 @@ class MiwearInstance extends common_1.default {
|
|
|
55
54
|
constructor(params) {
|
|
56
55
|
super(params);
|
|
57
56
|
this.params = params;
|
|
57
|
+
this.quickappStartedFlag = /quickapp_rpk_installer_init|rpk installer init done/;
|
|
58
58
|
this.appPathInEmulator = '/data/quickapp/app';
|
|
59
59
|
this.reconnectCount = 0;
|
|
60
|
+
this.emulatorStartedFlag = /quickapp_rpk_installer_init|rpk installer init done/;
|
|
60
61
|
}
|
|
61
62
|
/**
|
|
62
63
|
* 1. 启动模拟器
|
|
@@ -66,13 +67,13 @@ class MiwearInstance extends common_1.default {
|
|
|
66
67
|
start(options) {
|
|
67
68
|
return __awaiter(this, void 0, void 0, function* () {
|
|
68
69
|
this.startOptions = options;
|
|
69
|
-
this.sn = `
|
|
70
|
+
this.sn = `emulator-${this.startOptions.adbPort}`;
|
|
70
71
|
// 启动模拟器
|
|
71
72
|
yield this.startGoldfish(options);
|
|
72
73
|
// adb连接模拟器
|
|
73
|
-
const connected = yield this.
|
|
74
|
+
const connected = yield this.isConnected();
|
|
74
75
|
if (connected) {
|
|
75
|
-
|
|
76
|
+
shared_utils_1.ColorConsole.info('### Emulator ### Goldfish emulator connected successfully');
|
|
76
77
|
// 如果是首次启动,创建server端监听事件
|
|
77
78
|
if (this.isFirstStart && this.startOptions.serverPort) {
|
|
78
79
|
yield this.createWebsockeServer();
|
|
@@ -83,7 +84,7 @@ class MiwearInstance extends common_1.default {
|
|
|
83
84
|
}
|
|
84
85
|
else {
|
|
85
86
|
const msg = '### Emulator ### Failed to connect emulator, please check whether the adb is normal';
|
|
86
|
-
|
|
87
|
+
shared_utils_1.ColorConsole.throw(msg);
|
|
87
88
|
throw new Error(msg);
|
|
88
89
|
}
|
|
89
90
|
});
|
|
@@ -104,20 +105,20 @@ class MiwearInstance extends common_1.default {
|
|
|
104
105
|
const { avdName, devtool, origin = 'terminal' } = options;
|
|
105
106
|
// 获取emulator bin的绝对路径
|
|
106
107
|
const emulatorBin = this.getEmulatorBinPath();
|
|
107
|
-
|
|
108
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### emulator path: ${emulatorBin}`);
|
|
108
109
|
// 获取vela镜像的绝对路径
|
|
109
110
|
const avdInfo = this.velaAvdCls.getVelaAvdInfo(avdName);
|
|
110
111
|
const { avdArch, avdImagePath } = avdInfo;
|
|
111
|
-
|
|
112
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### adb port: ${options.adbPort}`);
|
|
112
113
|
if (!avdImagePath) {
|
|
113
|
-
return
|
|
114
|
+
return shared_utils_1.ColorConsole.throw(`### Emulator ### Unable to find vela image via avd`);
|
|
114
115
|
}
|
|
115
116
|
const nuttxBinPath = path_1.default.resolve(avdImagePath, 'nuttx');
|
|
116
|
-
|
|
117
|
-
//
|
|
118
|
-
let portMappingStr =
|
|
117
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### nuttx path: ${nuttxBinPath}`);
|
|
118
|
+
// 端口映射
|
|
119
|
+
let portMappingStr = ``;
|
|
119
120
|
if (devtool) {
|
|
120
|
-
portMappingStr +=
|
|
121
|
+
portMappingStr += `-network-user-mode-options hostfwd=tcp:127.0.0.1:${options.debugPort}-10.0.2.15:101`;
|
|
121
122
|
}
|
|
122
123
|
// 设备挂载节点
|
|
123
124
|
const systemImageBin = path_1.default.resolve(avdImagePath, 'vela_resource.bin'); // 只读
|
|
@@ -145,61 +146,50 @@ class MiwearInstance extends common_1.default {
|
|
|
145
146
|
-drive index=2,id=vendor,if=none,format=raw,file=${coreBin},read-only \
|
|
146
147
|
-device virtio-blk-device,bus=virtio-mmio-bus.4,drive=vendor \
|
|
147
148
|
-device virtio-snd,bus=virtio-mmio-bus.2 -allow-host-audio -semihosting`;
|
|
148
|
-
//
|
|
149
|
+
// grpc配置
|
|
149
150
|
let windowStr = '';
|
|
150
|
-
let
|
|
151
|
-
if ((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.
|
|
152
|
-
windowStr = '-
|
|
153
|
-
|
|
154
|
-
vncStr = `-vnc :${portSuffix}`;
|
|
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
155
|
}
|
|
156
156
|
// 启动模拟器的命令和参数
|
|
157
|
-
const cmd = `${emulatorBin} -nuttx -avd ${avdName} -avd-arch ${avdArch} -show-kernel -kernel ${nuttxBinPath} ${portMappingStr} ${windowStr}
|
|
157
|
+
const cmd = `${emulatorBin} -nuttx -avd ${avdName} -port ${options.adbPort} -avd-arch ${avdArch} -show-kernel -kernel ${nuttxBinPath} ${portMappingStr} ${windowStr} ${grpcStr} -qemu ${imageMountStr}`;
|
|
158
158
|
const spawnArgs = cmd.split(' ');
|
|
159
159
|
const spawnBin = spawnArgs.shift();
|
|
160
|
-
|
|
160
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Start CMD: ${cmd}`);
|
|
161
161
|
return new Promise((resolve) => {
|
|
162
|
-
var _a, _b, _c
|
|
162
|
+
var _a, _b, _c;
|
|
163
163
|
this.goldfishProcess = (0, child_process_1.spawn)(spawnBin, spawnArgs, {
|
|
164
164
|
stdio: 'pipe',
|
|
165
165
|
shell: true,
|
|
166
166
|
cwd: this.sdkHome
|
|
167
167
|
});
|
|
168
|
-
// 处理origin为terminal
|
|
169
|
-
if (origin === 'terminal') {
|
|
170
|
-
process.stdout.pipe(this.goldfishProcess.stdin);
|
|
171
|
-
(_a = this.goldfishProcess.stdout) === null || _a === void 0 ? void 0 : _a.pipe(process.stdout);
|
|
172
|
-
(_b = this.goldfishProcess.stderr) === null || _b === void 0 ? void 0 : _b.pipe(process.stderr);
|
|
173
|
-
}
|
|
174
168
|
// 监听模拟器的退出事件
|
|
175
169
|
this.goldfishProcess.on('exit', (code) => {
|
|
176
|
-
|
|
170
|
+
shared_utils_1.ColorConsole.error(`### Emulator ### Goldfish emulator exited with code ${code}`);
|
|
177
171
|
if (options.exitCallback) {
|
|
178
172
|
options.exitCallback(code);
|
|
179
173
|
}
|
|
180
174
|
});
|
|
181
175
|
// 监听错误流
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
});
|
|
187
|
-
}
|
|
176
|
+
(_a = this.goldfishProcess.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
177
|
+
const stderrCb = options.stderrCallback || console.log;
|
|
178
|
+
stderrCb(data.toString());
|
|
179
|
+
});
|
|
188
180
|
// 监听输出流
|
|
189
|
-
(
|
|
181
|
+
(_c = (_b = this.goldfishProcess) === null || _b === void 0 ? void 0 : _b.stdout) === null || _c === void 0 ? void 0 : _c.on('data', (data) => {
|
|
190
182
|
const msg = data.toString();
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
// this.launchQuickapp()
|
|
198
|
-
// }
|
|
183
|
+
const stdoutCb = options.stdoutCallback || console.log;
|
|
184
|
+
stdoutCb(msg);
|
|
185
|
+
// 应用安装成功,则启动它
|
|
186
|
+
if (msg.match(/InstallState_Finished|install finished/)) {
|
|
187
|
+
shared_utils_1.ColorConsole.info(`### Emulator ### Install quickapp successfully`);
|
|
188
|
+
this.launchQuickapp();
|
|
199
189
|
}
|
|
200
190
|
// 匹配到,则认为模拟器启动成功
|
|
201
|
-
if (msg.match(
|
|
202
|
-
|
|
191
|
+
if (msg.match(this.emulatorStartedFlag)) {
|
|
192
|
+
shared_utils_1.ColorConsole.info(`### Emulator ### Goldfish emulator starts successfully`);
|
|
203
193
|
resolve();
|
|
204
194
|
}
|
|
205
195
|
});
|
|
@@ -226,7 +216,7 @@ class MiwearInstance extends common_1.default {
|
|
|
226
216
|
.readdirSync(releaseDir)
|
|
227
217
|
.filter((item) => item.includes(appPackageName) && item.endsWith('.rpk'));
|
|
228
218
|
if (files.length === 0) {
|
|
229
|
-
|
|
219
|
+
shared_utils_1.ColorConsole.error(`### Emulator the rpk does not exist`);
|
|
230
220
|
}
|
|
231
221
|
const rpkPath = path_1.default.resolve(releaseDir, files[0]);
|
|
232
222
|
// 调试模式需要push一个文件至miwear中
|
|
@@ -235,7 +225,7 @@ class MiwearInstance extends common_1.default {
|
|
|
235
225
|
yield adbMiwt.execAdbCmdAsync(`adb -s ${this.sn} push ${debuggerCfgFile} /data/debugger_ip.cfg`);
|
|
236
226
|
}
|
|
237
227
|
else {
|
|
238
|
-
adbMiwt.execAdbCmdAsync(`adb -s ${this.sn} shell rm /data/debugger_ip.cfg`);
|
|
228
|
+
yield adbMiwt.execAdbCmdAsync(`adb -s ${this.sn} shell rm /data/debugger_ip.cfg`);
|
|
239
229
|
}
|
|
240
230
|
this.installRpkToAppList(rpkPath, this.appPathInEmulator);
|
|
241
231
|
});
|
|
@@ -249,39 +239,15 @@ class MiwearInstance extends common_1.default {
|
|
|
249
239
|
*/
|
|
250
240
|
installRpkToAppList(rpkPath, targetDir) {
|
|
251
241
|
return __awaiter(this, void 0, void 0, function* () {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const installCmd = `adb -s ${this.sn} shell pm install ${targetPath}`;
|
|
262
|
-
ColorConsole_1.default.info(`### Emulator ### Excuting cmd: ${installCmd}`);
|
|
263
|
-
yield adbMiwt.execAdbCmdAsync(installCmd);
|
|
264
|
-
// 3. 应用安装成功后,启动应用
|
|
265
|
-
const lsCmd = `adb -s ${this.sn} shell ls ${this.appPathInEmulator}`;
|
|
266
|
-
let installed = false;
|
|
267
|
-
let currCount = 0;
|
|
268
|
-
while (!installed && currCount < 10) {
|
|
269
|
-
yield (0, utils_1.sleep)(1000);
|
|
270
|
-
const res = yield adbMiwt.execAdbCmdAsync(lsCmd);
|
|
271
|
-
// 如果没有上传的rpk了,则表示安装成功
|
|
272
|
-
installed = !res.includes(`${packageName}.rpk`);
|
|
273
|
-
currCount++;
|
|
274
|
-
}
|
|
275
|
-
if (installed) {
|
|
276
|
-
this.launchQuickapp();
|
|
277
|
-
}
|
|
278
|
-
else {
|
|
279
|
-
ColorConsole_1.default.error(`### Emulator ### install ${packageName} failed`);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
catch (e) {
|
|
283
|
-
ColorConsole_1.default.error(`### Emulator ### ${e.message}`);
|
|
284
|
-
}
|
|
242
|
+
const { package: packageName } = this.projectInfo;
|
|
243
|
+
// 1. adb push应用的rpk
|
|
244
|
+
const targetPath = `${targetDir}/${packageName}.rpk`;
|
|
245
|
+
const pushCmd = `adb -s ${this.sn} push "${rpkPath}" ${targetPath}`;
|
|
246
|
+
shared_utils_1.ColorConsole.info(`### Emulator ### Excuting cmd: ${pushCmd}`);
|
|
247
|
+
yield adbMiwt.execAdbCmdAsync(pushCmd);
|
|
248
|
+
const installCmd = `adb -s ${this.sn} shell pm install ${targetPath}`;
|
|
249
|
+
shared_utils_1.ColorConsole.info(`### Emulator ### Excuting cmd: ${installCmd}`);
|
|
250
|
+
yield adbMiwt.execAdbCmdAsync(installCmd);
|
|
285
251
|
});
|
|
286
252
|
}
|
|
287
253
|
/** 使用am start启动快应用 */
|
|
@@ -289,7 +255,7 @@ class MiwearInstance extends common_1.default {
|
|
|
289
255
|
return __awaiter(this, void 0, void 0, function* () {
|
|
290
256
|
const { package: packageName } = this.projectInfo;
|
|
291
257
|
const startCmd = `adb -s ${this.sn} shell am start ${packageName}`;
|
|
292
|
-
|
|
258
|
+
shared_utils_1.ColorConsole.info(`### Emulator ### Excuting cmd: ${startCmd}`);
|
|
293
259
|
adbMiwt.execAdbCmdAsync(startCmd);
|
|
294
260
|
});
|
|
295
261
|
}
|
|
@@ -305,7 +271,7 @@ class MiwearInstance extends common_1.default {
|
|
|
305
271
|
}
|
|
306
272
|
this.debugSocket = new ws_1.default(`ws://localhost:${(_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.debugPort}`);
|
|
307
273
|
this.debugSocket.onopen = () => {
|
|
308
|
-
|
|
274
|
+
shared_utils_1.ColorConsole.info(`### Emulator debugSocket connect success`);
|
|
309
275
|
return resolve();
|
|
310
276
|
};
|
|
311
277
|
this.debugSocket.onerror = (errorEvent) => {
|
|
@@ -313,7 +279,7 @@ class MiwearInstance extends common_1.default {
|
|
|
313
279
|
// 重连机制
|
|
314
280
|
(_a = this.debugSocket) === null || _a === void 0 ? void 0 : _a.terminate();
|
|
315
281
|
if (this.reconnectCount < MAX_RECONNECT_COUNT) {
|
|
316
|
-
|
|
282
|
+
shared_utils_1.ColorConsole.info(`### Emulator the ${this.reconnectCount + 1}th time to reconnect debug server`);
|
|
317
283
|
this.reconnectCount++;
|
|
318
284
|
setTimeout(() => this.initDebugSocket(), 2000);
|
|
319
285
|
}
|
|
@@ -326,7 +292,7 @@ class MiwearInstance extends common_1.default {
|
|
|
326
292
|
this.debugSocket.onclose = (closeEvent) => {
|
|
327
293
|
this.debugSocket = undefined;
|
|
328
294
|
this.reconnectCount = 0;
|
|
329
|
-
|
|
295
|
+
shared_utils_1.ColorConsole.log(`### Emulator debugSocket connect close: ${closeEvent.reason}`);
|
|
330
296
|
};
|
|
331
297
|
});
|
|
332
298
|
}
|
|
@@ -349,7 +315,7 @@ class MiwearInstance extends common_1.default {
|
|
|
349
315
|
}
|
|
350
316
|
}
|
|
351
317
|
catch (e) {
|
|
352
|
-
|
|
318
|
+
shared_utils_1.ColorConsole.error(`${e}`);
|
|
353
319
|
}
|
|
354
320
|
});
|
|
355
321
|
}
|
|
@@ -370,7 +336,7 @@ class MiwearInstance extends common_1.default {
|
|
|
370
336
|
const sourcePath = path_1.default.resolve(this.projectPath, './build/*');
|
|
371
337
|
yield adbMiwt.execAdbCmdAsync(`adb -s ${this.sn} push ${sourcePath} ${this.appPathInEmulator}/${appPackageName}`);
|
|
372
338
|
}
|
|
373
|
-
|
|
339
|
+
shared_utils_1.ColorConsole.info(`### Emulator push to ${this.appPathInEmulator}/${appPackageName} successfully`);
|
|
374
340
|
});
|
|
375
341
|
}
|
|
376
342
|
/** 在模拟器中重启快应用(基于am命令,需要保证镜像中已经有am功能)
|
|
@@ -378,24 +344,29 @@ class MiwearInstance extends common_1.default {
|
|
|
378
344
|
* 2. nsh中执行am stop命令退出快应用
|
|
379
345
|
* 3. nsh中执行am start命令启动快应用
|
|
380
346
|
*/
|
|
347
|
+
pushAndReloadApp() {
|
|
348
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
349
|
+
// 1. 将整包重新推到miwear中(TODO:增量更新)
|
|
350
|
+
yield this.pushBuild();
|
|
351
|
+
yield this.reloadApp();
|
|
352
|
+
});
|
|
353
|
+
}
|
|
381
354
|
reloadApp() {
|
|
382
355
|
return __awaiter(this, void 0, void 0, function* () {
|
|
383
356
|
try {
|
|
384
|
-
// 1. 将整包重新推到miwear中(TODO:增量更新)
|
|
385
357
|
const { package: appPackageName } = this.projectInfo;
|
|
386
|
-
yield this.pushBuild();
|
|
387
358
|
// 2. 执行am stop和am start命令
|
|
388
359
|
const stopCmd = `adb -s ${this.sn} shell am stop ${appPackageName}`;
|
|
389
360
|
yield adbMiwt.execAdbCmdAsync(stopCmd);
|
|
390
|
-
|
|
361
|
+
shared_utils_1.ColorConsole.info(`### Emulator stop ${appPackageName} successfully`);
|
|
391
362
|
// 这里是为了等am stop命令清除资源等
|
|
392
363
|
yield (0, utils_1.sleep)(500);
|
|
393
364
|
const startCmd = `adb -s ${this.sn} shell am start ${appPackageName}`;
|
|
394
365
|
yield adbMiwt.execAdbCmdAsync(startCmd);
|
|
395
|
-
|
|
366
|
+
shared_utils_1.ColorConsole.info(`### Emulator start ${appPackageName} successfully`);
|
|
396
367
|
}
|
|
397
368
|
catch (e) {
|
|
398
|
-
|
|
369
|
+
shared_utils_1.ColorConsole.error(`${e}`);
|
|
399
370
|
}
|
|
400
371
|
});
|
|
401
372
|
}
|
|
@@ -409,15 +380,15 @@ class MiwearInstance extends common_1.default {
|
|
|
409
380
|
port: (_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.serverPort
|
|
410
381
|
});
|
|
411
382
|
wsServer.on('connection', (socket) => {
|
|
412
|
-
|
|
383
|
+
shared_utils_1.ColorConsole.success(`### App Socket server ### Websocket connects to websocket server`);
|
|
413
384
|
socket.on('error', (err) => {
|
|
414
|
-
|
|
385
|
+
shared_utils_1.ColorConsole.error(`### App Socket server ### Websocket server error: ${err.message}`);
|
|
415
386
|
});
|
|
416
387
|
// data的格式:{ type: string, data: any }
|
|
417
388
|
socket.on('message', (data) => __awaiter(this, void 0, void 0, function* () {
|
|
418
389
|
var _a;
|
|
419
390
|
const message = JSON.parse(data.toString());
|
|
420
|
-
|
|
391
|
+
shared_utils_1.ColorConsole.log(`### App Socket server ### Websocket server get data: ${data}`);
|
|
421
392
|
if (message.type === 'restart') {
|
|
422
393
|
// 非调试模式下无法热更新
|
|
423
394
|
if (!((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.devtool)) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const dev_1 = __importDefault(require("./dev"));
|
|
7
|
+
const miwear_1 = __importDefault(require("./miwear"));
|
|
8
|
+
/**
|
|
9
|
+
* 不带 miwear 的 4.0 镜像
|
|
10
|
+
*/
|
|
11
|
+
class PreInstance extends dev_1.default {
|
|
12
|
+
constructor() {
|
|
13
|
+
super(...arguments);
|
|
14
|
+
this.appRunDir = '/data/quickapp/app';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
// pre 镜像的 启动 方式与 MiwearInstance 一致
|
|
18
|
+
PreInstance.prototype.startGoldfish = miwear_1.default.prototype.startGoldfish;
|
|
19
|
+
exports.default = PreInstance;
|
package/lib/instance/preDev.js
CHANGED
|
@@ -35,8 +35,7 @@ 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
|
|
39
|
-
const FileUtil_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/utils/FileUtil"));
|
|
38
|
+
const shared_utils_1 = require("@aiot-toolkit/shared-utils");
|
|
40
39
|
const adbMiwt = __importStar(require("@miwt/adb"));
|
|
41
40
|
const child_process_1 = require("child_process");
|
|
42
41
|
const find_process_1 = __importDefault(require("find-process"));
|
|
@@ -78,7 +77,7 @@ class OldGoldfishInstance extends common_1.default {
|
|
|
78
77
|
// adb连接快应用
|
|
79
78
|
const connected = yield this.connectGoldfish();
|
|
80
79
|
if (connected) {
|
|
81
|
-
|
|
80
|
+
shared_utils_1.ColorConsole.log('### Emulator ### Goldfish emulator connected successfully');
|
|
82
81
|
// 如果是首次启动,创建server端监听事件
|
|
83
82
|
if (this.isFirstStart && this.startOptions.serverPort) {
|
|
84
83
|
yield this.createWebsockeServer();
|
|
@@ -88,7 +87,7 @@ class OldGoldfishInstance extends common_1.default {
|
|
|
88
87
|
this.isFirstStart = false;
|
|
89
88
|
}
|
|
90
89
|
else {
|
|
91
|
-
|
|
90
|
+
shared_utils_1.ColorConsole.throw('### Emulator ### Failed to connect emulator, please check whether the adb is normal');
|
|
92
91
|
}
|
|
93
92
|
});
|
|
94
93
|
}
|
|
@@ -103,19 +102,19 @@ class OldGoldfishInstance extends common_1.default {
|
|
|
103
102
|
const { package: packageName } = this.projectInfo;
|
|
104
103
|
const appMountDir = path_1.default.resolve(this.sdkHome, 'qa');
|
|
105
104
|
const mountCmd = `adb -s 127.0.0.1:${options.adbPort} shell mount -t v9fs -o tag=10.0.2.2,port=${this.host9pPort},aname=${appMountDir} /data`;
|
|
106
|
-
|
|
105
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Excuting adb cmd: ${mountCmd}`);
|
|
107
106
|
adbMiwt.execAdbCmdSync(mountCmd);
|
|
108
107
|
let vappCmd = `adb -s 127.0.0.1:${options.adbPort} shell vapp app/${packageName} &`;
|
|
109
108
|
// 调试情况下,需要加--jsdebugger=10.0.2.15:101
|
|
110
109
|
if (options.devtool) {
|
|
111
110
|
vappCmd = `adb -s 127.0.0.1:${options.adbPort} shell vapp --jsdebugger=10.0.2.15:101 app/${packageName} &`;
|
|
112
111
|
}
|
|
113
|
-
|
|
112
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Excuting adb cmd: ${vappCmd}`);
|
|
114
113
|
// vapp进程会一直pending,不会退出。这里必须加stdio: 'ignore',否则快应用无法运行成功
|
|
115
114
|
adbMiwt.execAdbCmdAsync(vappCmd, { stdio: 'ignore', encoding: 'utf-8' });
|
|
116
115
|
}
|
|
117
116
|
catch (e) {
|
|
118
|
-
|
|
117
|
+
shared_utils_1.ColorConsole.error(`### Emulator ### Failed to startup quickapp: ${e.message}`);
|
|
119
118
|
}
|
|
120
119
|
}
|
|
121
120
|
/** host启动9pServer
|
|
@@ -127,10 +126,10 @@ class OldGoldfishInstance extends common_1.default {
|
|
|
127
126
|
const yaFileName = os_1.default.platform() === 'win32' ? 'ya-vm-file-server.exe' : 'ya-vm-file-server';
|
|
128
127
|
const pidList = yield (0, find_process_1.default)('name', yaFileName);
|
|
129
128
|
if (pidList.length > 0) {
|
|
130
|
-
|
|
129
|
+
shared_utils_1.ColorConsole.log('### Emulator ### 9p server started in host');
|
|
131
130
|
return resolve();
|
|
132
131
|
}
|
|
133
|
-
|
|
132
|
+
shared_utils_1.ColorConsole.log('### Emulator ### Starting 9p server in host');
|
|
134
133
|
const quickappMountDir = path_1.default.resolve(this.sdkHome, 'qa');
|
|
135
134
|
const toolsHome = path_1.default.resolve(this.sdkHome, 'tools');
|
|
136
135
|
const serverBinPath = path_1.default.resolve(toolsHome, yaFileName);
|
|
@@ -148,14 +147,14 @@ class OldGoldfishInstance extends common_1.default {
|
|
|
148
147
|
(_a = this.v9fsProcess.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
149
148
|
const output = data.toString();
|
|
150
149
|
if (output.match(/Server started, listening on: 127.0.0.1:(\d+)/)) {
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
shared_utils_1.ColorConsole.log(output);
|
|
151
|
+
shared_utils_1.ColorConsole.log('### Emulator ### 9p server starts successfully');
|
|
153
152
|
return resolve();
|
|
154
153
|
}
|
|
155
154
|
});
|
|
156
155
|
// 监听exit事件,判断9p server是否退出了
|
|
157
156
|
this.v9fsProcess.on('exit', (code) => {
|
|
158
|
-
|
|
157
|
+
shared_utils_1.ColorConsole.error(`### Emulator ### ya-vm-file-server exited with code ${code}`);
|
|
159
158
|
return reject();
|
|
160
159
|
});
|
|
161
160
|
}));
|
|
@@ -175,29 +174,29 @@ class OldGoldfishInstance extends common_1.default {
|
|
|
175
174
|
const { avdName, devtool, origin = 'terminal' } = options;
|
|
176
175
|
// 获取emulator bin的绝对路径
|
|
177
176
|
const emulatorBin = this.getEmulatorBinPath();
|
|
178
|
-
|
|
177
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### emulator path: ${emulatorBin}`);
|
|
179
178
|
// 获取vela镜像的绝对路径
|
|
180
179
|
const avdInfo = this.velaAvdCls.getVelaAvdInfo(avdName);
|
|
181
180
|
const { avdArch, avdImagePath } = avdInfo;
|
|
182
|
-
|
|
181
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### adb port: ${options.adbPort}`);
|
|
183
182
|
if (!avdImagePath) {
|
|
184
|
-
return
|
|
183
|
+
return shared_utils_1.ColorConsole.throw(`### Emulator ### Unable to find vela image via avd`);
|
|
185
184
|
}
|
|
186
185
|
const nuttxBinPath = path_1.default.resolve(avdImagePath, 'nuttx');
|
|
187
|
-
|
|
186
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### nuttx path: ${nuttxBinPath}`);
|
|
188
187
|
// 端口映射,adb端口和debug端口
|
|
189
188
|
let portMappingStr = `user,id=u1,hostfwd=tcp:127.0.0.1:${options.adbPort}-10.0.2.15:5555`;
|
|
190
189
|
if (devtool) {
|
|
191
|
-
|
|
190
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### debug port: ${options.debugPort}`);
|
|
192
191
|
portMappingStr += `,hostfwd=tcp:127.0.0.1:${options.debugPort}-10.0.2.15:101`;
|
|
193
192
|
}
|
|
194
|
-
|
|
193
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Start qemu with TCP: ${portMappingStr}`);
|
|
195
194
|
// vnc配置
|
|
196
195
|
let noWindow = false;
|
|
197
196
|
let vncStr = '';
|
|
198
|
-
if (options.
|
|
197
|
+
if (options.grpcPort) {
|
|
199
198
|
noWindow = true;
|
|
200
|
-
const portSuffix = options.
|
|
199
|
+
const portSuffix = options.grpcPort - constants_1.defaultVncPort;
|
|
201
200
|
vncStr = `-vnc :${portSuffix}`;
|
|
202
201
|
}
|
|
203
202
|
// 启动goldfish的命令和参数
|
|
@@ -219,7 +218,7 @@ class OldGoldfishInstance extends common_1.default {
|
|
|
219
218
|
'-device',
|
|
220
219
|
'virtio-net-device,netdev=u1,bus=virtio-mmio-bus.3'
|
|
221
220
|
];
|
|
222
|
-
|
|
221
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Start CMD: ${spawnBin} ${spawnArgs.join(' ')}`);
|
|
223
222
|
return new Promise((resolve) => {
|
|
224
223
|
var _a, _b, _c, _d;
|
|
225
224
|
this.goldfishProcess = (0, child_process_1.spawn)(spawnBin, spawnArgs, { stdio: 'pipe', shell: true });
|
|
@@ -234,7 +233,7 @@ class OldGoldfishInstance extends common_1.default {
|
|
|
234
233
|
}
|
|
235
234
|
// 监听模拟器的退出事件
|
|
236
235
|
this.goldfishProcess.on('exit', (code) => {
|
|
237
|
-
|
|
236
|
+
shared_utils_1.ColorConsole.error(`### Emulator ### Goldfish emulator exited with code ${code}`);
|
|
238
237
|
if (options.exitCallback) {
|
|
239
238
|
options.exitCallback(code);
|
|
240
239
|
}
|
|
@@ -247,7 +246,7 @@ class OldGoldfishInstance extends common_1.default {
|
|
|
247
246
|
stdoutCb(msg);
|
|
248
247
|
}
|
|
249
248
|
if (msg.includes('(NSH)')) {
|
|
250
|
-
|
|
249
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Goldfish emulator starts successfully`);
|
|
251
250
|
resolve();
|
|
252
251
|
}
|
|
253
252
|
});
|
|
@@ -262,10 +261,10 @@ class OldGoldfishInstance extends common_1.default {
|
|
|
262
261
|
return __awaiter(this, void 0, void 0, function* () {
|
|
263
262
|
const { package: appPackageName } = this.projectInfo;
|
|
264
263
|
const appRunDir = path_1.default.resolve(this.sdkHome, 'qa/app', appPackageName);
|
|
265
|
-
|
|
264
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Pushing ${appPackageName} to ${appRunDir}`);
|
|
266
265
|
fs_1.default.rmSync(appRunDir, { recursive: true, force: true });
|
|
267
|
-
|
|
268
|
-
|
|
266
|
+
shared_utils_1.FileUtil.copyFiles(sourceRoot, appRunDir);
|
|
267
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Push ${appPackageName} to ${appRunDir} successfully`);
|
|
269
268
|
});
|
|
270
269
|
}
|
|
271
270
|
/** 停止模拟器并释放相关资源 */
|
package/lib/static/constants.js
CHANGED
package/lib/typing/Instance.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import IJavascriptCompileOption from '@aiot-toolkit/aiotpack
|
|
2
|
+
import { IJavascriptCompileOption } from '@aiot-toolkit/aiotpack';
|
|
3
3
|
import { IAvdResourcePaths } from './Avd';
|
|
4
4
|
export interface INewGoldfishInstanceParams extends IAvdResourcePaths {
|
|
5
5
|
projectPath: string;
|
|
@@ -13,7 +13,7 @@ export interface IStartOptions {
|
|
|
13
13
|
disableNSH?: boolean;
|
|
14
14
|
origin?: 'ide' | 'terminal';
|
|
15
15
|
serverPort?: number;
|
|
16
|
-
|
|
16
|
+
grpcPort?: number;
|
|
17
17
|
adbPort: number;
|
|
18
18
|
debugPort?: number;
|
|
19
19
|
stdoutCallback?: (buffer: Buffer) => void;
|
package/lib/utils/index.d.ts
CHANGED
|
@@ -11,3 +11,23 @@ export declare function killProcessByPid(pid: string): void;
|
|
|
11
11
|
export declare function killProcessByCmd(cmd: string): Promise<void>;
|
|
12
12
|
/** 延迟函数 */
|
|
13
13
|
export declare function sleep(time: number): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* 重复执行某个任务直到成功,或者超过最大次数
|
|
16
|
+
* @param task 任务,需要返回 bool 值表示是否执行成功
|
|
17
|
+
* @param {Number=} maxCount 最大重试次数
|
|
18
|
+
* @param {number=} duration 每次重试的间隔
|
|
19
|
+
*/
|
|
20
|
+
export declare function tryRun(task: (...args: any[]) => Promise<any>, maxCount?: number, duration?: number, currentCount?: number): Promise<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* 延迟执行某个任务
|
|
23
|
+
* @param task
|
|
24
|
+
* @param duration
|
|
25
|
+
* @returns
|
|
26
|
+
*/
|
|
27
|
+
export declare function delayRun<T = any>(task: (...args: any[]) => Promise<T> | T, duration?: number): Promise<T>;
|
|
28
|
+
/**
|
|
29
|
+
* 为avdPort寻找一个不被占用的端口
|
|
30
|
+
* 端口号必须是偶数且在5555和5585之间
|
|
31
|
+
* @returns {number}
|
|
32
|
+
*/
|
|
33
|
+
export declare function getEvenPort(): Promise<number | false | undefined>;
|
package/lib/utils/index.js
CHANGED
|
@@ -12,17 +12,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.sleep = exports.killProcessByCmd = exports.killProcessByPid = exports.getSystemArch = void 0;
|
|
16
|
-
const
|
|
15
|
+
exports.getEvenPort = exports.delayRun = exports.tryRun = exports.sleep = exports.killProcessByCmd = exports.killProcessByPid = exports.getSystemArch = void 0;
|
|
16
|
+
const shared_utils_1 = require("@aiot-toolkit/shared-utils");
|
|
17
17
|
const child_process_1 = require("child_process");
|
|
18
18
|
const find_process_1 = __importDefault(require("find-process"));
|
|
19
19
|
const os_1 = __importDefault(require("os"));
|
|
20
20
|
const semver_1 = __importDefault(require("semver"));
|
|
21
|
+
const portfinder_1 = __importDefault(require("portfinder"));
|
|
21
22
|
const cpuArch = {
|
|
22
23
|
arm64: 'aarch64',
|
|
23
24
|
aarch64: 'aarch64',
|
|
24
25
|
x64: 'x86_64',
|
|
25
|
-
x86_64: 'x86_64'
|
|
26
|
+
x86_64: 'x86_64'
|
|
26
27
|
};
|
|
27
28
|
/** 获取mac电脑的CPU架构
|
|
28
29
|
* node 15.0.0之后,m1芯片的mac的os.arch()才是arm64,在这之前都是x86
|
|
@@ -42,7 +43,7 @@ function getSystemArch() {
|
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
if (osArch !== 'arm64' && osArch !== 'x64') {
|
|
45
|
-
return
|
|
46
|
+
return shared_utils_1.ColorConsole.throw(`unsupport system`);
|
|
46
47
|
}
|
|
47
48
|
return cpuArch[osArch];
|
|
48
49
|
}
|
|
@@ -50,9 +51,7 @@ exports.getSystemArch = getSystemArch;
|
|
|
50
51
|
/** 根据PID杀死进程 */
|
|
51
52
|
function killProcessByPid(pid) {
|
|
52
53
|
try {
|
|
53
|
-
const cmd = os_1.default.platform() ===
|
|
54
|
-
? `taskkill /pid ${pid} /T /F`
|
|
55
|
-
: `kill -9 ${pid}`;
|
|
54
|
+
const cmd = os_1.default.platform() === 'win32' ? `taskkill /pid ${pid} /T /F` : `kill -9 ${pid}`;
|
|
56
55
|
(0, child_process_1.execSync)(cmd);
|
|
57
56
|
}
|
|
58
57
|
catch (e) {
|
|
@@ -82,7 +81,65 @@ exports.killProcessByCmd = killProcessByCmd;
|
|
|
82
81
|
/** 延迟函数 */
|
|
83
82
|
function sleep(time) {
|
|
84
83
|
return __awaiter(this, void 0, void 0, function* () {
|
|
85
|
-
return new Promise(resolve => setTimeout(resolve, time));
|
|
84
|
+
return new Promise((resolve) => setTimeout(resolve, time));
|
|
86
85
|
});
|
|
87
86
|
}
|
|
88
87
|
exports.sleep = sleep;
|
|
88
|
+
/**
|
|
89
|
+
* 重复执行某个任务直到成功,或者超过最大次数
|
|
90
|
+
* @param task 任务,需要返回 bool 值表示是否执行成功
|
|
91
|
+
* @param {Number=} maxCount 最大重试次数
|
|
92
|
+
* @param {number=} duration 每次重试的间隔
|
|
93
|
+
*/
|
|
94
|
+
function tryRun(task, maxCount = 5, duration = 1000, currentCount = 0) {
|
|
95
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
96
|
+
if (currentCount > maxCount)
|
|
97
|
+
return false;
|
|
98
|
+
return (Boolean(yield task()) ||
|
|
99
|
+
(yield delayRun(() => tryRun(task, maxCount, duration, currentCount + 1), duration)));
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
exports.tryRun = tryRun;
|
|
103
|
+
/**
|
|
104
|
+
* 延迟执行某个任务
|
|
105
|
+
* @param task
|
|
106
|
+
* @param duration
|
|
107
|
+
* @returns
|
|
108
|
+
*/
|
|
109
|
+
function delayRun(task, duration = 1000) {
|
|
110
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
return new Promise((resolve) => {
|
|
112
|
+
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
113
|
+
return resolve(task());
|
|
114
|
+
}), duration);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
exports.delayRun = delayRun;
|
|
119
|
+
/**
|
|
120
|
+
* 为avdPort寻找一个不被占用的端口
|
|
121
|
+
* 端口号必须是偶数且在5555和5585之间
|
|
122
|
+
* @returns {number}
|
|
123
|
+
*/
|
|
124
|
+
function getEvenPort() {
|
|
125
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
126
|
+
const startPort = 5555;
|
|
127
|
+
const stopPort = 5585;
|
|
128
|
+
let index = 1;
|
|
129
|
+
let port = yield portfinder_1.default.getPortPromise({
|
|
130
|
+
port: startPort,
|
|
131
|
+
stopPort
|
|
132
|
+
});
|
|
133
|
+
while (port % 2 !== 0) {
|
|
134
|
+
if (index > 30)
|
|
135
|
+
return false;
|
|
136
|
+
port = yield portfinder_1.default.getPortPromise({
|
|
137
|
+
port: startPort + index,
|
|
138
|
+
stopPort
|
|
139
|
+
});
|
|
140
|
+
index++;
|
|
141
|
+
return port;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
exports.getEvenPort = getEvenPort;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiot-toolkit/emulator",
|
|
3
|
-
"version": "2.0.2-beta.
|
|
3
|
+
"version": "2.0.2-beta.11",
|
|
4
4
|
"description": "vela emulator tool.",
|
|
5
5
|
"homepage": "",
|
|
6
6
|
"license": "ISC",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"emulator"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@aiot-toolkit/aiotpack": "2.0.2-beta.
|
|
39
|
-
"@aiot-toolkit/shared-utils": "2.0.2-beta.
|
|
38
|
+
"@aiot-toolkit/aiotpack": "2.0.2-beta.11",
|
|
39
|
+
"@aiot-toolkit/shared-utils": "2.0.2-beta.11",
|
|
40
40
|
"find-process": "^1.4.7",
|
|
41
41
|
"portfinder": "^1.0.32"
|
|
42
42
|
},
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"@types/fs-extra": "^11.0.4",
|
|
45
45
|
"fs-extra": "^11.2.0"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "07c38dd12ba0d932c6dc1fd16fe25aaf15ab9fbb"
|
|
48
48
|
}
|