@aiot-toolkit/emulator 2.0.2-dev.8 → 2.0.3-beta.1
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/README.md +14 -1
- package/lib/avd/index.d.ts +16 -0
- package/lib/avd/index.js +52 -28
- package/lib/emulatorutil/EmulatorCmd.d.ts +9 -0
- package/lib/emulatorutil/EmulatorCmd.js +226 -0
- package/lib/emulatorutil/EmulatorLog.d.ts +11 -0
- package/lib/emulatorutil/EmulatorLog.js +21 -0
- package/lib/emulatorutil/constants.d.ts +31 -0
- package/lib/emulatorutil/constants.js +63 -0
- package/lib/emulatorutil/index.d.ts +3 -0
- package/lib/emulatorutil/index.js +10 -0
- package/lib/index.d.ts +3 -1
- package/lib/index.js +4 -1
- package/lib/instance/common.d.ts +15 -12
- package/lib/instance/common.js +89 -153
- package/lib/instance/dev.d.ts +42 -6
- package/lib/instance/dev.js +137 -83
- package/lib/instance/index.d.ts +10 -2
- package/lib/instance/index.js +14 -2
- package/lib/instance/miwear.d.ts +66 -12
- package/lib/instance/miwear.js +220 -182
- package/lib/instance/pre.d.ts +11 -0
- package/lib/instance/pre.js +100 -0
- package/lib/instance/preDev.d.ts +37 -7
- package/lib/instance/preDev.js +80 -106
- package/lib/static/advancedFeatures.ini +1 -0
- package/lib/static/avdConfigIni.json +4 -4
- package/lib/typing/Avd.d.ts +1 -0
- package/lib/typing/Instance.d.ts +16 -3
- package/lib/typing/Instance.js +6 -0
- package/lib/utils/index.d.ts +21 -0
- package/lib/utils/index.js +67 -10
- package/package.json +15 -5
- package/lib/static/constants.d.ts +0 -19
- package/lib/static/constants.js +0 -27
package/lib/instance/preDev.d.ts
CHANGED
|
@@ -1,21 +1,51 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
import { ChildProcess } from 'child_process';
|
|
2
|
+
import readline from 'readline';
|
|
3
3
|
import { INewGoldfishInstanceParams, IStartOptions } from '../typing/Instance';
|
|
4
4
|
import CommonInstance from './common';
|
|
5
|
+
/**
|
|
6
|
+
* OldGoldfishInstance
|
|
7
|
+
* 针对 Vela开发版(dev, 0.0.2)的镜像
|
|
8
|
+
*/
|
|
5
9
|
declare class OldGoldfishInstance extends CommonInstance {
|
|
6
10
|
private host9pPort;
|
|
7
11
|
v9fsProcess: ChildProcess | undefined;
|
|
12
|
+
stdoutReadline: readline.Interface;
|
|
13
|
+
stderrReadline: readline.Interface;
|
|
8
14
|
constructor(params: INewGoldfishInstanceParams);
|
|
9
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* 1. 启动9p server
|
|
17
|
+
* 2. 将打包好的rpk推到host的挂载目录
|
|
18
|
+
* 3. 启动模拟器
|
|
19
|
+
* 4. 模拟器启动成功后,adb连接模拟器
|
|
20
|
+
* 5. 连接成功后,在模拟器中启动快应用
|
|
21
|
+
*/
|
|
10
22
|
start(options: IStartOptions): Promise<void>;
|
|
11
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* 在模拟器中启动快应用(快应用都在模拟器的/data/app目录下)
|
|
25
|
+
* 1. 是否为调试模式
|
|
26
|
+
* 若是,在模拟器终端执行vapp app/${packageName} &
|
|
27
|
+
* 若否,在模拟器终端执行vapp --jsdebugger=10.0.2.15:101 app/${packageName} &
|
|
28
|
+
*/
|
|
12
29
|
startupQuickApp(options: IStartOptions): void;
|
|
13
|
-
/** host启动9pServer
|
|
30
|
+
/** host启动9pServer
|
|
31
|
+
* 作用是将本地的quickappMountDir目录挂载到模拟器的/data目录
|
|
32
|
+
*/
|
|
14
33
|
ensure9pServerRunnning(): Promise<void>;
|
|
15
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* 启动模拟器
|
|
36
|
+
* 1. 通过options生成模拟器的启动命令
|
|
37
|
+
* 2. 执行启动命令
|
|
38
|
+
* 3. 判断模拟器是否启动成功
|
|
39
|
+
* 3.1 若disableNSH=true,输出流中匹配到/quickapp_rpk_installer_init|rpk installer init done/,认为模拟器启动成功了
|
|
40
|
+
* 3.2 若disableNSH=false,认为8s过后模拟器启动成功了
|
|
41
|
+
* @param options
|
|
42
|
+
* @returns
|
|
43
|
+
*/
|
|
16
44
|
startGoldfish(options: IStartOptions): Promise<void>;
|
|
17
|
-
/**
|
|
18
|
-
|
|
45
|
+
/**
|
|
46
|
+
* 推送文件到本地的${sdkHome}/qa/app/${packageName}目录
|
|
47
|
+
* @param sourceRoot 源目录
|
|
48
|
+
*/
|
|
19
49
|
pushRpk(sourceRoot: string): Promise<void>;
|
|
20
50
|
/** 停止模拟器并释放相关资源 */
|
|
21
51
|
stop(): Promise<void>;
|
package/lib/instance/preDev.js
CHANGED
|
@@ -44,27 +44,44 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
44
44
|
const os_1 = __importDefault(require("os"));
|
|
45
45
|
const path_1 = __importDefault(require("path"));
|
|
46
46
|
const portfinder_1 = __importDefault(require("portfinder"));
|
|
47
|
-
const
|
|
47
|
+
const readline_1 = __importDefault(require("readline"));
|
|
48
|
+
const Instance_1 = require("../typing/Instance");
|
|
49
|
+
const emulatorutil_1 = require("../emulatorutil");
|
|
48
50
|
const common_1 = __importDefault(require("./common"));
|
|
51
|
+
/**
|
|
52
|
+
* OldGoldfishInstance
|
|
53
|
+
* 针对 Vela开发版(dev, 0.0.2)的镜像
|
|
54
|
+
*/
|
|
49
55
|
class OldGoldfishInstance extends common_1.default {
|
|
50
56
|
constructor(params) {
|
|
51
57
|
super(params);
|
|
52
58
|
this.host9pPort = 7878;
|
|
53
59
|
}
|
|
54
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* 1. 启动9p server
|
|
62
|
+
* 2. 将打包好的rpk推到host的挂载目录
|
|
63
|
+
* 3. 启动模拟器
|
|
64
|
+
* 4. 模拟器启动成功后,adb连接模拟器
|
|
65
|
+
* 5. 连接成功后,在模拟器中启动快应用
|
|
66
|
+
*/
|
|
55
67
|
start(options) {
|
|
56
68
|
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
this.startOptions = options;
|
|
70
|
+
this.sn = `127.0.0.1:${this.startOptions.adbPort}`;
|
|
57
71
|
// host启动9p server
|
|
58
72
|
yield this.ensure9pServerRunnning();
|
|
59
|
-
this.startOptions = options;
|
|
60
73
|
// 将rpk推到host的./export/qa/app目录
|
|
61
|
-
const buildedFilesPath = this.isRpk
|
|
74
|
+
const buildedFilesPath = this.isRpk
|
|
75
|
+
? this.projectPath
|
|
76
|
+
: path_1.default.resolve(this.projectPath, './build');
|
|
62
77
|
this.pushRpk(buildedFilesPath);
|
|
63
78
|
// 启动模拟器
|
|
64
79
|
yield this.startGoldfish(options);
|
|
80
|
+
// adb连接快应用
|
|
65
81
|
const connected = yield this.connectGoldfish();
|
|
66
82
|
if (connected) {
|
|
67
83
|
ColorConsole_1.default.log('### Emulator ### Goldfish emulator connected successfully');
|
|
84
|
+
// 如果是首次启动,创建server端监听事件
|
|
68
85
|
if (this.isFirstStart && this.startOptions.serverPort) {
|
|
69
86
|
yield this.createWebsockeServer();
|
|
70
87
|
}
|
|
@@ -77,17 +94,23 @@ class OldGoldfishInstance extends common_1.default {
|
|
|
77
94
|
}
|
|
78
95
|
});
|
|
79
96
|
}
|
|
80
|
-
/**
|
|
97
|
+
/**
|
|
98
|
+
* 在模拟器中启动快应用(快应用都在模拟器的/data/app目录下)
|
|
99
|
+
* 1. 是否为调试模式
|
|
100
|
+
* 若是,在模拟器终端执行vapp app/${packageName} &
|
|
101
|
+
* 若否,在模拟器终端执行vapp --jsdebugger=10.0.2.15:101 app/${packageName} &
|
|
102
|
+
*/
|
|
81
103
|
startupQuickApp(options) {
|
|
82
104
|
try {
|
|
83
105
|
const { package: packageName } = this.projectInfo;
|
|
84
106
|
const appMountDir = path_1.default.resolve(this.sdkHome, 'qa');
|
|
85
|
-
const mountCmd = `adb -s 127.0.0.1:${
|
|
107
|
+
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`;
|
|
86
108
|
ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${mountCmd}`);
|
|
87
109
|
adbMiwt.execAdbCmdSync(mountCmd);
|
|
88
|
-
let vappCmd = `adb -s 127.0.0.1:${
|
|
110
|
+
let vappCmd = `adb -s 127.0.0.1:${options.adbPort} shell vapp app/${packageName} &`;
|
|
111
|
+
// 调试情况下,需要加--jsdebugger=10.0.2.15:101
|
|
89
112
|
if (options.devtool) {
|
|
90
|
-
vappCmd = `adb -s 127.0.0.1:${
|
|
113
|
+
vappCmd = `adb -s 127.0.0.1:${options.adbPort} shell vapp --jsdebugger=10.0.2.15:101 app/${packageName} &`;
|
|
91
114
|
}
|
|
92
115
|
ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${vappCmd}`);
|
|
93
116
|
// vapp进程会一直pending,不会退出。这里必须加stdio: 'ignore',否则快应用无法运行成功
|
|
@@ -97,7 +120,9 @@ class OldGoldfishInstance extends common_1.default {
|
|
|
97
120
|
ColorConsole_1.default.error(`### Emulator ### Failed to startup quickapp: ${e.message}`);
|
|
98
121
|
}
|
|
99
122
|
}
|
|
100
|
-
/** host启动9pServer
|
|
123
|
+
/** host启动9pServer
|
|
124
|
+
* 作用是将本地的quickappMountDir目录挂载到模拟器的/data目录
|
|
125
|
+
*/
|
|
101
126
|
ensure9pServerRunnning() {
|
|
102
127
|
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
103
128
|
var _a;
|
|
@@ -121,133 +146,82 @@ class OldGoldfishInstance extends common_1.default {
|
|
|
121
146
|
address,
|
|
122
147
|
'--debug'
|
|
123
148
|
]);
|
|
149
|
+
// 监听stderr,判断9p server是否启动成功了
|
|
124
150
|
(_a = this.v9fsProcess.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
125
151
|
const output = data.toString();
|
|
126
|
-
if (
|
|
127
|
-
ColorConsole_1.default.log(output);
|
|
152
|
+
if (emulatorutil_1.EmulatorLog.preDevIsStart(output)) {
|
|
128
153
|
ColorConsole_1.default.log('### Emulator ### 9p server starts successfully');
|
|
129
154
|
return resolve();
|
|
130
155
|
}
|
|
131
156
|
});
|
|
157
|
+
// 监听exit事件,判断9p server是否退出了
|
|
132
158
|
this.v9fsProcess.on('exit', (code) => {
|
|
133
159
|
ColorConsole_1.default.error(`### Emulator ### ya-vm-file-server exited with code ${code}`);
|
|
134
160
|
return reject();
|
|
135
161
|
});
|
|
136
162
|
}));
|
|
137
163
|
}
|
|
138
|
-
/**
|
|
164
|
+
/**
|
|
165
|
+
* 启动模拟器
|
|
166
|
+
* 1. 通过options生成模拟器的启动命令
|
|
167
|
+
* 2. 执行启动命令
|
|
168
|
+
* 3. 判断模拟器是否启动成功
|
|
169
|
+
* 3.1 若disableNSH=true,输出流中匹配到/quickapp_rpk_installer_init|rpk installer init done/,认为模拟器启动成功了
|
|
170
|
+
* 3.2 若disableNSH=false,认为8s过后模拟器启动成功了
|
|
171
|
+
* @param options
|
|
172
|
+
* @returns
|
|
173
|
+
*/
|
|
139
174
|
startGoldfish(options) {
|
|
140
175
|
return __awaiter(this, void 0, void 0, function* () {
|
|
141
|
-
const {
|
|
142
|
-
const emulatorBin = this.getEmulatorBinPath();
|
|
143
|
-
ColorConsole_1.default.log(`### Emulator ### emulator path: ${emulatorBin}`);
|
|
144
|
-
const avdInfo = this.velaAvdCls.getVelaAvdInfo(avdName);
|
|
145
|
-
const { avdArch, avdImagePath } = avdInfo;
|
|
146
|
-
this.adbPort = yield portfinder_1.default.getPortPromise({ port: this.adbPort });
|
|
147
|
-
ColorConsole_1.default.log(`### Emulator ### adb port: ${this.adbPort}`);
|
|
148
|
-
if (!avdImagePath) {
|
|
149
|
-
return ColorConsole_1.default.throw(`### Emulator ### Unable to find vela image via avd`);
|
|
150
|
-
}
|
|
151
|
-
const nuttxBinPath = path_1.default.resolve(avdImagePath, 'nuttx');
|
|
152
|
-
ColorConsole_1.default.log(`### Emulator ### nuttx path: ${nuttxBinPath}`);
|
|
153
|
-
let portMappingStr = `user,id=u1,hostfwd=tcp:127.0.0.1:${this.adbPort}-10.0.2.15:5555`;
|
|
154
|
-
if (devtool) {
|
|
155
|
-
this.debugPort = yield portfinder_1.default.getPortPromise({ port: this.debugPort });
|
|
156
|
-
ColorConsole_1.default.log(`### Emulator ### debug port: ${this.debugPort}`);
|
|
157
|
-
portMappingStr += `,hostfwd=tcp:127.0.0.1:${this.debugPort}-10.0.2.15:101`;
|
|
158
|
-
}
|
|
159
|
-
ColorConsole_1.default.log(`### Emulator ### Start qemu with TCP: ${portMappingStr}`);
|
|
160
|
-
const stdioType = options.disableNSH ? 'pipe' : 'inherit';
|
|
161
|
-
// vnc配置
|
|
162
|
-
let noWindow = false;
|
|
163
|
-
let vncStr = '';
|
|
164
|
-
if (options.vncPort) {
|
|
165
|
-
noWindow = true;
|
|
166
|
-
const portSuffix = options.vncPort - constants_1.defaultVncPort;
|
|
167
|
-
vncStr = `-vnc :${portSuffix}`;
|
|
168
|
-
}
|
|
176
|
+
const { origin = Instance_1.IStartOrigin.Terminal } = options;
|
|
169
177
|
// 启动goldfish的命令和参数
|
|
170
|
-
const
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
'-avd-arch',
|
|
176
|
-
avdArch,
|
|
177
|
-
'-show-kernel',
|
|
178
|
-
'-kernel',
|
|
179
|
-
nuttxBinPath,
|
|
180
|
-
noWindow ? '-no-window' : '',
|
|
181
|
-
'-qemu',
|
|
182
|
-
vncStr,
|
|
183
|
-
'-netdev',
|
|
184
|
-
portMappingStr,
|
|
185
|
-
'-device',
|
|
186
|
-
'virtio-net-device,netdev=u1,bus=virtio-mmio-bus.3'
|
|
187
|
-
];
|
|
188
|
-
ColorConsole_1.default.log(`### Emulator ### Start CMD: ${spawnBin} ${spawnArgs.join(' ')}`);
|
|
178
|
+
const spawnArgs = emulatorutil_1.EmulatorCmd.createPreCmd(options, this.sdkHome, this.avdHome);
|
|
179
|
+
const spawnBin = spawnArgs && spawnArgs.shift();
|
|
180
|
+
if (!spawnArgs || !spawnBin)
|
|
181
|
+
return;
|
|
182
|
+
ColorConsole_1.default.log(`### Emulator ### Start CMD preDev: ${spawnBin} ${spawnArgs.join(' ')}`);
|
|
189
183
|
return new Promise((resolve) => {
|
|
190
|
-
var _a;
|
|
191
|
-
this.goldfishProcess = (0, child_process_1.spawn)(spawnBin, spawnArgs, { stdio:
|
|
184
|
+
var _a, _b, _c;
|
|
185
|
+
this.goldfishProcess = (0, child_process_1.spawn)(spawnBin, spawnArgs, { stdio: 'pipe', shell: true });
|
|
186
|
+
// 监听错误流
|
|
192
187
|
(_a = this.goldfishProcess.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
193
188
|
const stderrCb = options.stderrCallback || console.log;
|
|
194
189
|
stderrCb(data.toString());
|
|
195
190
|
});
|
|
191
|
+
if (origin === Instance_1.IStartOrigin.Terminal) {
|
|
192
|
+
process.stdout.pipe(this.goldfishProcess.stdin);
|
|
193
|
+
}
|
|
194
|
+
// 利用 readline 接口可解决子进程日志换行的问题
|
|
195
|
+
this.stdoutReadline = readline_1.default.createInterface({
|
|
196
|
+
input: this.goldfishProcess.stdout
|
|
197
|
+
});
|
|
198
|
+
this.stderrReadline = readline_1.default.createInterface({
|
|
199
|
+
input: this.goldfishProcess.stderr
|
|
200
|
+
});
|
|
201
|
+
// 监听模拟器的退出事件
|
|
196
202
|
this.goldfishProcess.on('exit', (code) => {
|
|
197
203
|
ColorConsole_1.default.error(`### Emulator ### Goldfish emulator exited with code ${code}`);
|
|
198
204
|
if (options.exitCallback) {
|
|
199
205
|
options.exitCallback(code);
|
|
200
206
|
}
|
|
201
207
|
});
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
});
|
|
208
|
+
// 监听输出流。输出了'(NSH)'标识后则认为模拟器启动成功
|
|
209
|
+
(_c = (_b = this.goldfishProcess) === null || _b === void 0 ? void 0 : _b.stdout) === null || _c === void 0 ? void 0 : _c.on('data', (data) => {
|
|
210
|
+
const msg = data.toString();
|
|
211
|
+
const stdoutCb = options.stdoutCallback || console.log;
|
|
212
|
+
stdoutCb(msg);
|
|
213
|
+
if (emulatorutil_1.EmulatorLog.devIsStart(msg)) {
|
|
214
|
+
ColorConsole_1.default.log(`### Emulator ### Goldfish emulator starts successfully`);
|
|
215
|
+
resolve();
|
|
216
|
+
}
|
|
212
217
|
});
|
|
213
|
-
const p2 = setTimeout(() => {
|
|
214
|
-
ColorConsole_1.default.log(`### Emulator ### Goldfish emulator starts successfully`);
|
|
215
|
-
resolve();
|
|
216
|
-
}, 2000);
|
|
217
|
-
return Promise.race([p1, p2]);
|
|
218
218
|
});
|
|
219
219
|
});
|
|
220
220
|
}
|
|
221
|
-
/**
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
const connectFn = () => __awaiter(this, void 0, void 0, function* () {
|
|
226
|
-
const sn = `127.0.0.1:${this.adbPort}`;
|
|
227
|
-
while (!adbConnected) {
|
|
228
|
-
const adbKillCmd = `adb kill-server`;
|
|
229
|
-
ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${adbKillCmd}`);
|
|
230
|
-
adbMiwt.execAdbCmdSync(adbKillCmd);
|
|
231
|
-
const adbConnectCmd = `adb connect ${sn}`;
|
|
232
|
-
ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${adbConnectCmd}`);
|
|
233
|
-
const str = adbMiwt.execAdbCmdSync(adbConnectCmd);
|
|
234
|
-
ColorConsole_1.default.log(`### Emulator ### ${str}`);
|
|
235
|
-
const devices = yield adbMiwt.getAdbDevices();
|
|
236
|
-
ColorConsole_1.default.log(`### Emulator ### adb devices: ${JSON.stringify(devices)}`);
|
|
237
|
-
adbConnected =
|
|
238
|
-
devices.filter((item) => item.sn === sn && item.status === 'device').length > 0;
|
|
239
|
-
}
|
|
240
|
-
Promise.resolve(adbConnected);
|
|
241
|
-
});
|
|
242
|
-
yield Promise.race([
|
|
243
|
-
connectFn(),
|
|
244
|
-
new Promise((resolve) => {
|
|
245
|
-
setTimeout(() => resolve(false), 600 * 1000);
|
|
246
|
-
})
|
|
247
|
-
]);
|
|
248
|
-
return adbConnected;
|
|
249
|
-
});
|
|
250
|
-
}
|
|
221
|
+
/**
|
|
222
|
+
* 推送文件到本地的${sdkHome}/qa/app/${packageName}目录
|
|
223
|
+
* @param sourceRoot 源目录
|
|
224
|
+
*/
|
|
251
225
|
pushRpk(sourceRoot) {
|
|
252
226
|
return __awaiter(this, void 0, void 0, function* () {
|
|
253
227
|
const { package: appPackageName } = this.projectInfo;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ModemSimulator = on
|
|
@@ -10,14 +10,14 @@
|
|
|
10
10
|
"hw.arc": false,
|
|
11
11
|
"hw.audioInput": "yes",
|
|
12
12
|
"hw.battery": "yes",
|
|
13
|
-
"hw.camera.back": "
|
|
14
|
-
"hw.camera.front": "
|
|
13
|
+
"hw.camera.back": "None",
|
|
14
|
+
"hw.camera.front": "None",
|
|
15
15
|
"hw.cpu.arch": "arm",
|
|
16
16
|
"hw.cpu.ncore": 4,
|
|
17
17
|
"hw.dPad": "no",
|
|
18
18
|
"hw.gps": "yes",
|
|
19
19
|
"hw.gpu.enabled": "no",
|
|
20
|
-
"hw.gpu.mode
|
|
20
|
+
"hw.gpu.mode": "off",
|
|
21
21
|
"hw.initialOrientation": "Portrait",
|
|
22
22
|
"hw.keyboard": "yes",
|
|
23
23
|
"hw.lcd.density": 420,
|
|
@@ -36,4 +36,4 @@
|
|
|
36
36
|
"skin.dynamic": "no",
|
|
37
37
|
"skin.name": "",
|
|
38
38
|
"skin.path": ""
|
|
39
|
-
}
|
|
39
|
+
}
|
package/lib/typing/Avd.d.ts
CHANGED
package/lib/typing/Instance.d.ts
CHANGED
|
@@ -1,16 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
import { IAvdResourcePaths } from
|
|
1
|
+
import { IJavascriptCompileOption } from '@aiot-toolkit/aiotpack';
|
|
2
|
+
import { IAvdResourcePaths } from './Avd';
|
|
3
3
|
export interface INewGoldfishInstanceParams extends IAvdResourcePaths {
|
|
4
4
|
projectPath: string;
|
|
5
5
|
sourceRoot?: string;
|
|
6
|
+
compilerOption?: Partial<IJavascriptCompileOption>;
|
|
6
7
|
}
|
|
7
8
|
export interface IStartOptions {
|
|
8
9
|
avdName: string;
|
|
9
10
|
devtool?: string;
|
|
11
|
+
/** @deprecated */
|
|
10
12
|
disableNSH?: boolean;
|
|
13
|
+
origin?: IStartOrigin;
|
|
11
14
|
serverPort?: number;
|
|
12
|
-
|
|
15
|
+
grpcPort?: number;
|
|
16
|
+
adbPort: number;
|
|
17
|
+
debugPort?: number;
|
|
13
18
|
stdoutCallback?: (buffer: Buffer) => void;
|
|
14
19
|
stderrCallback?: (buffer: Buffer) => void;
|
|
15
20
|
exitCallback?: (code: number | null) => void;
|
|
21
|
+
/** 要推送的目录路径 */
|
|
22
|
+
dist?: string;
|
|
23
|
+
/** 要推送到的目的路径 */
|
|
24
|
+
tar?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare enum IStartOrigin {
|
|
27
|
+
Terminal = "terminal",
|
|
28
|
+
Ide = "ide"
|
|
16
29
|
}
|
package/lib/typing/Instance.js
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IStartOrigin = void 0;
|
|
4
|
+
var IStartOrigin;
|
|
5
|
+
(function (IStartOrigin) {
|
|
6
|
+
IStartOrigin["Terminal"] = "terminal";
|
|
7
|
+
IStartOrigin["Ide"] = "ide";
|
|
8
|
+
})(IStartOrigin || (exports.IStartOrigin = IStartOrigin = {}));
|
package/lib/utils/index.d.ts
CHANGED
|
@@ -9,4 +9,25 @@ export declare function killProcessByPid(pid: string): void;
|
|
|
9
9
|
* 根据命令杀死进程
|
|
10
10
|
*/
|
|
11
11
|
export declare function killProcessByCmd(cmd: string): Promise<void>;
|
|
12
|
+
/** 延迟函数 */
|
|
12
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>;
|
package/lib/utils/index.js
CHANGED
|
@@ -12,17 +12,24 @@ 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.
|
|
15
|
+
exports.getSystemArch = getSystemArch;
|
|
16
|
+
exports.killProcessByPid = killProcessByPid;
|
|
17
|
+
exports.killProcessByCmd = killProcessByCmd;
|
|
18
|
+
exports.sleep = sleep;
|
|
19
|
+
exports.tryRun = tryRun;
|
|
20
|
+
exports.delayRun = delayRun;
|
|
21
|
+
exports.getEvenPort = getEvenPort;
|
|
16
22
|
const ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
|
|
17
23
|
const child_process_1 = require("child_process");
|
|
18
24
|
const find_process_1 = __importDefault(require("find-process"));
|
|
19
25
|
const os_1 = __importDefault(require("os"));
|
|
20
26
|
const semver_1 = __importDefault(require("semver"));
|
|
27
|
+
const portfinder_1 = __importDefault(require("portfinder"));
|
|
21
28
|
const cpuArch = {
|
|
22
29
|
arm64: 'aarch64',
|
|
23
30
|
aarch64: 'aarch64',
|
|
24
31
|
x64: 'x86_64',
|
|
25
|
-
x86_64: 'x86_64'
|
|
32
|
+
x86_64: 'x86_64'
|
|
26
33
|
};
|
|
27
34
|
/** 获取mac电脑的CPU架构
|
|
28
35
|
* node 15.0.0之后,m1芯片的mac的os.arch()才是arm64,在这之前都是x86
|
|
@@ -46,20 +53,16 @@ function getSystemArch() {
|
|
|
46
53
|
}
|
|
47
54
|
return cpuArch[osArch];
|
|
48
55
|
}
|
|
49
|
-
exports.getSystemArch = getSystemArch;
|
|
50
56
|
/** 根据PID杀死进程 */
|
|
51
57
|
function killProcessByPid(pid) {
|
|
52
58
|
try {
|
|
53
|
-
const cmd = os_1.default.platform() ===
|
|
54
|
-
? `taskkill /pid ${pid} /T /F`
|
|
55
|
-
: `kill -9 ${pid}`;
|
|
59
|
+
const cmd = os_1.default.platform() === 'win32' ? `taskkill /pid ${pid} /T /F` : `kill -9 ${pid}`;
|
|
56
60
|
(0, child_process_1.execSync)(cmd);
|
|
57
61
|
}
|
|
58
62
|
catch (e) {
|
|
59
63
|
console.error(`kill process ${pid} get error: ${e}`);
|
|
60
64
|
}
|
|
61
65
|
}
|
|
62
|
-
exports.killProcessByPid = killProcessByPid;
|
|
63
66
|
/**
|
|
64
67
|
* 根据命令杀死进程
|
|
65
68
|
*/
|
|
@@ -78,10 +81,64 @@ function killProcessByCmd(cmd) {
|
|
|
78
81
|
}
|
|
79
82
|
});
|
|
80
83
|
}
|
|
81
|
-
|
|
84
|
+
/** 延迟函数 */
|
|
82
85
|
function sleep(time) {
|
|
83
86
|
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
-
return new Promise(resolve => setTimeout(resolve, time));
|
|
87
|
+
return new Promise((resolve) => setTimeout(resolve, time));
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 重复执行某个任务直到成功,或者超过最大次数
|
|
92
|
+
* @param task 任务,需要返回 bool 值表示是否执行成功
|
|
93
|
+
* @param {Number=} maxCount 最大重试次数
|
|
94
|
+
* @param {number=} duration 每次重试的间隔
|
|
95
|
+
*/
|
|
96
|
+
function tryRun(task_1) {
|
|
97
|
+
return __awaiter(this, arguments, void 0, function* (task, maxCount = 5, duration = 1000, currentCount = 0) {
|
|
98
|
+
if (currentCount > maxCount)
|
|
99
|
+
return false;
|
|
100
|
+
return (Boolean(yield task()) ||
|
|
101
|
+
(yield delayRun(() => tryRun(task, maxCount, duration, currentCount + 1), duration)));
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* 延迟执行某个任务
|
|
106
|
+
* @param task
|
|
107
|
+
* @param duration
|
|
108
|
+
* @returns
|
|
109
|
+
*/
|
|
110
|
+
function delayRun(task_1) {
|
|
111
|
+
return __awaiter(this, arguments, void 0, function* (task, duration = 1000) {
|
|
112
|
+
return new Promise((resolve) => {
|
|
113
|
+
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
114
|
+
return resolve(task());
|
|
115
|
+
}), duration);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
}
|
|
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 = 5556;
|
|
127
|
+
const stopPort = 5584;
|
|
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 > 13)
|
|
135
|
+
return false;
|
|
136
|
+
port = yield portfinder_1.default.getPortPromise({
|
|
137
|
+
port: startPort + 2,
|
|
138
|
+
stopPort
|
|
139
|
+
});
|
|
140
|
+
index++;
|
|
141
|
+
}
|
|
142
|
+
return port;
|
|
85
143
|
});
|
|
86
144
|
}
|
|
87
|
-
exports.sleep = sleep;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiot-toolkit/emulator",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3-beta.1",
|
|
4
4
|
"description": "vela emulator tool.",
|
|
5
5
|
"homepage": "",
|
|
6
6
|
"license": "ISC",
|
|
@@ -35,10 +35,20 @@
|
|
|
35
35
|
"emulator"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@aiot-toolkit/aiotpack": "2.0.
|
|
39
|
-
"@aiot-toolkit/shared-utils": "2.0.
|
|
38
|
+
"@aiot-toolkit/aiotpack": "2.0.3-beta.1",
|
|
39
|
+
"@aiot-toolkit/shared-utils": "2.0.3-beta.1",
|
|
40
|
+
"@miwt/adb": "^0.9.0",
|
|
41
|
+
"dayjs": "^1.11.12",
|
|
40
42
|
"find-process": "^1.4.7",
|
|
41
|
-
"
|
|
43
|
+
"fs-extra": "^11.2.0",
|
|
44
|
+
"ini": "^4.1.3",
|
|
45
|
+
"portfinder": "^1.0.32",
|
|
46
|
+
"semver": "^7.6.3",
|
|
47
|
+
"ws": "^8.18.0"
|
|
42
48
|
},
|
|
43
|
-
"
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/fs-extra": "^11.0.4",
|
|
51
|
+
"@types/ini": "^4.1.1"
|
|
52
|
+
},
|
|
53
|
+
"gitHead": "77b1b0aab9b5c227b5cc355b585a7c93761cc9a3"
|
|
44
54
|
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export declare const defaultSDKHome: string;
|
|
2
|
-
export declare const defaultAvdHome: string;
|
|
3
|
-
export declare const defaultImageHome: string;
|
|
4
|
-
export declare const defaultEmulatorHome: string;
|
|
5
|
-
export declare const defaultSkinHome: string;
|
|
6
|
-
export declare const defaultQuickappHome: string;
|
|
7
|
-
export declare const defaultToolsHome: string;
|
|
8
|
-
export declare const defaultVncPort = 5900;
|
|
9
|
-
export declare const emulatorEnvVersion: {
|
|
10
|
-
name: string;
|
|
11
|
-
emulator: string;
|
|
12
|
-
qa: string;
|
|
13
|
-
skins: string;
|
|
14
|
-
'system-images': {
|
|
15
|
-
release: string;
|
|
16
|
-
dev: string;
|
|
17
|
-
};
|
|
18
|
-
tools: string;
|
|
19
|
-
};
|
package/lib/static/constants.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
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
|
-
exports.emulatorEnvVersion = exports.defaultVncPort = exports.defaultToolsHome = exports.defaultQuickappHome = exports.defaultSkinHome = exports.defaultEmulatorHome = exports.defaultImageHome = exports.defaultAvdHome = exports.defaultSDKHome = void 0;
|
|
7
|
-
const os_1 = __importDefault(require("os"));
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
exports.defaultSDKHome = path_1.default.resolve(os_1.default.homedir(), '.export');
|
|
10
|
-
exports.defaultAvdHome = path_1.default.resolve(os_1.default.homedir(), '.android', 'avd');
|
|
11
|
-
exports.defaultImageHome = path_1.default.resolve(exports.defaultSDKHome, 'system-images/arm');
|
|
12
|
-
exports.defaultEmulatorHome = path_1.default.resolve(exports.defaultSDKHome, 'emulator');
|
|
13
|
-
exports.defaultSkinHome = path_1.default.resolve(exports.defaultSDKHome, 'skins');
|
|
14
|
-
exports.defaultQuickappHome = path_1.default.resolve(exports.defaultSDKHome, 'qa');
|
|
15
|
-
exports.defaultToolsHome = path_1.default.resolve(exports.defaultSDKHome, 'tools');
|
|
16
|
-
exports.defaultVncPort = 5900;
|
|
17
|
-
exports.emulatorEnvVersion = {
|
|
18
|
-
name: '模拟器资源版本管理',
|
|
19
|
-
emulator: '0.0.1',
|
|
20
|
-
qa: '0.0.1',
|
|
21
|
-
skins: '0.0.1',
|
|
22
|
-
'system-images': {
|
|
23
|
-
release: '4.0',
|
|
24
|
-
dev: '0.0.2'
|
|
25
|
-
},
|
|
26
|
-
tools: '0.0.2'
|
|
27
|
-
};
|