@aiot-toolkit/emulator 2.0.1-alpha.8 → 2.0.2-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.
@@ -35,8 +35,6 @@ 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 UxFileUtils_1 = __importDefault(require("@aiot-toolkit/aiotpack/lib/utils/ux/UxFileUtils"));
39
- const shared_utils_1 = require("@aiot-toolkit/shared-utils");
40
38
  const ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
41
39
  const FileUtil_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/utils/FileUtil"));
42
40
  const adbMiwt = __importStar(require("@miwt/adb"));
@@ -46,78 +44,57 @@ const fs_1 = __importDefault(require("fs"));
46
44
  const os_1 = __importDefault(require("os"));
47
45
  const path_1 = __importDefault(require("path"));
48
46
  const portfinder_1 = __importDefault(require("portfinder"));
49
- const avd_1 = __importDefault(require("../avd"));
50
47
  const constants_1 = require("../static/constants");
51
- class GoldfishInstance {
48
+ const common_1 = __importDefault(require("./common"));
49
+ class OldGoldfishInstance extends common_1.default {
52
50
  constructor(params) {
53
- this.adbPort = 15555;
54
- this.debugPort = 10055;
51
+ super(params);
55
52
  this.host9pPort = 7878;
56
- this.projectPath = params.projectPath;
57
- this.sdkHome = params.sdkHome || constants_1.defaultSDKHome;
58
- this.avdHome = params.avdHome || constants_1.defaultAvdHome;
59
- this.velaAvdCls = new avd_1.default({
60
- sdkHome: this.sdkHome,
61
- avdHome: this.avdHome
62
- });
63
- const { package: appPackageName } = UxFileUtils_1.default.getMainfestInfo(this.projectPath, params.sourceRoot);
64
- this.packageName = appPackageName;
65
- }
66
- /** 获取模拟器二进制文件所在位置 */
67
- getEmulatorBinPath() {
68
- const osPlatform = os_1.default.platform();
69
- const osArch = os_1.default.arch();
70
- const platform = osPlatform === 'win32' ? 'windows' : osPlatform;
71
- const arch = (osArch === 'arm64' || osArch === 'aarch64') ? 'aarch64' : 'x86_64';
72
- return path_1.default.resolve(constants_1.defaultEmulatorHome, `${platform}-${arch}`, 'emulator');
73
53
  }
74
54
  /** 在goldfish模拟器中运行快应用 */
75
55
  start(options) {
76
56
  return __awaiter(this, void 0, void 0, function* () {
77
57
  // host启动9p server
78
58
  yield this.ensure9pServerRunnning();
79
- // TODO: 打包快应用
80
- // 将rpk推到host的defaultQuickappHome目录
81
- this.pushRpk();
59
+ this.startOptions = options;
60
+ // 将rpk推到host的./export/qa/app目录
61
+ const buildedFilesPath = this.isRpk ? this.projectPath : path_1.default.resolve(this.projectPath, './build');
62
+ this.pushRpk(buildedFilesPath);
82
63
  // 启动模拟器
83
64
  yield this.startGoldfish(options);
84
65
  const connected = yield this.connectGoldfish();
85
66
  if (connected) {
86
- ColorConsole_1.default.log({
87
- message: '### Emulator ### Goldfish emulator connected successfully'
88
- });
67
+ ColorConsole_1.default.log('### Emulator ### Goldfish emulator connected successfully');
68
+ if (this.isFirstStart && this.startOptions.serverPort) {
69
+ yield this.createWebsockeServer();
70
+ }
89
71
  // 在模拟器中启动快应用
90
72
  this.startupQuickApp(options);
73
+ this.isFirstStart = false;
91
74
  }
92
75
  else {
93
- ColorConsole_1.default.log({
94
- level: shared_utils_1.LOG_LEVEL.Error,
95
- message: '### Emulator ### Failed to connect emulator, please check whether the adb is normal'
96
- });
76
+ ColorConsole_1.default.throw('### Emulator ### Failed to connect emulator, please check whether the adb is normal');
97
77
  }
98
78
  });
99
79
  }
100
80
  /** 在goldfish中启动快应用 */
101
81
  startupQuickApp(options) {
102
82
  try {
83
+ const { package: packageName } = this.projectInfo;
103
84
  const appMountDir = path_1.default.resolve(this.sdkHome, 'qa');
104
85
  const mountCmd = `adb -s 127.0.0.1:${this.adbPort} shell mount -t v9fs -o tag=10.0.2.2,port=${this.host9pPort},aname=${appMountDir} /data`;
105
- ColorConsole_1.default.log({ message: `### Emulator ### Excuting adb cmd: ${mountCmd}` });
86
+ ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${mountCmd}`);
106
87
  adbMiwt.execAdbCmdSync(mountCmd);
107
- let vappCmd = `adb -s 127.0.0.1:${this.adbPort} shell vapp app/${this.packageName} &`;
88
+ let vappCmd = `adb -s 127.0.0.1:${this.adbPort} shell vapp app/${packageName} &`;
108
89
  if (options.devtool) {
109
- vappCmd = `adb -s 127.0.0.1:${this.adbPort} shell vapp --jsdebugger=10.0.2.15:101 app/${this.packageName} &`;
90
+ vappCmd = `adb -s 127.0.0.1:${this.adbPort} shell vapp --jsdebugger=10.0.2.15:101 app/${packageName} &`;
110
91
  }
111
- ColorConsole_1.default.log({ message: `### Emulator ### Excuting adb cmd: ${vappCmd}` });
92
+ ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${vappCmd}`);
112
93
  // vapp进程会一直pending,不会退出。这里必须加stdio: 'ignore',否则快应用无法运行成功
113
94
  adbMiwt.execAdbCmdAsync(vappCmd, { stdio: 'ignore', encoding: 'utf-8' });
114
95
  }
115
96
  catch (e) {
116
- ColorConsole_1.default.log({
117
- level: shared_utils_1.LOG_LEVEL.Error,
118
- message: `### Emulator ### Failed to startup quickapp: ${e.message}`,
119
- isOnlyPrintError: true
120
- });
97
+ ColorConsole_1.default.error(`### Emulator ### Failed to startup quickapp: ${e.message}`);
121
98
  }
122
99
  }
123
100
  /** host启动9pServer */
@@ -127,12 +104,13 @@ class GoldfishInstance {
127
104
  const yaFileName = os_1.default.platform() === 'win32' ? 'ya-vm-file-server.exe' : 'ya-vm-file-server';
128
105
  const pidList = yield (0, find_process_1.default)('name', yaFileName);
129
106
  if (pidList.length > 0) {
130
- ColorConsole_1.default.log({ message: '### Emulator ### 9p server started in host' });
107
+ ColorConsole_1.default.log('### Emulator ### 9p server started in host');
131
108
  return resolve();
132
109
  }
133
- ColorConsole_1.default.log({ message: '### Emulator ### Starting 9p server in host' });
110
+ ColorConsole_1.default.log('### Emulator ### Starting 9p server in host');
134
111
  const quickappMountDir = path_1.default.resolve(this.sdkHome, 'qa');
135
- const serverBinPath = path_1.default.resolve(constants_1.defaultToolsHome, yaFileName);
112
+ const toolsHome = path_1.default.resolve(this.sdkHome, 'tools');
113
+ const serverBinPath = path_1.default.resolve(toolsHome, yaFileName);
136
114
  fs_1.default.chmodSync(serverBinPath, 0o777);
137
115
  this.host9pPort = yield portfinder_1.default.getPortPromise({ port: 7878 });
138
116
  const address = `127.0.0.1:${this.host9pPort}`;
@@ -146,17 +124,13 @@ class GoldfishInstance {
146
124
  (_a = this.v9fsProcess.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
147
125
  const output = data.toString();
148
126
  if (output.match(/Server started, listening on: 127.0.0.1:(\d+)/)) {
149
- ColorConsole_1.default.log({ message: output });
150
- ColorConsole_1.default.log({ message: '### Emulator ### 9p server starts successfully' });
127
+ ColorConsole_1.default.log(output);
128
+ ColorConsole_1.default.log('### Emulator ### 9p server starts successfully');
151
129
  return resolve();
152
130
  }
153
131
  });
154
132
  this.v9fsProcess.on('exit', (code) => {
155
- ColorConsole_1.default.log({
156
- level: shared_utils_1.LOG_LEVEL.Error,
157
- message: `### Emulator ### ya-vm-file-server exited with code ${code}`,
158
- isOnlyPrintError: true
159
- });
133
+ ColorConsole_1.default.error(`### Emulator ### ya-vm-file-server exited with code ${code}`);
160
134
  return reject();
161
135
  });
162
136
  }));
@@ -166,70 +140,81 @@ class GoldfishInstance {
166
140
  return __awaiter(this, void 0, void 0, function* () {
167
141
  const { avdName, devtool } = options;
168
142
  const emulatorBin = this.getEmulatorBinPath();
169
- ColorConsole_1.default.log({ message: `### Emulator ### emulator path: ${emulatorBin}` });
143
+ ColorConsole_1.default.log(`### Emulator ### emulator path: ${emulatorBin}`);
170
144
  const avdInfo = this.velaAvdCls.getVelaAvdInfo(avdName);
171
145
  const { avdArch, avdImagePath } = avdInfo;
172
146
  this.adbPort = yield portfinder_1.default.getPortPromise({ port: this.adbPort });
173
- ColorConsole_1.default.log({ message: `### Emulator ### adb port: ${this.adbPort}` });
147
+ ColorConsole_1.default.log(`### Emulator ### adb port: ${this.adbPort}`);
174
148
  if (!avdImagePath) {
175
- ColorConsole_1.default.log({
176
- level: shared_utils_1.LOG_LEVEL.Error,
177
- message: `### Emulator ### Unable to find vela image via avd`
178
- });
179
- process.exit();
149
+ return ColorConsole_1.default.throw(`### Emulator ### Unable to find vela image via avd`);
180
150
  }
181
151
  const nuttxBinPath = path_1.default.resolve(avdImagePath, 'nuttx');
182
- ColorConsole_1.default.log({ message: `### Emulator ### nuttx path: ${nuttxBinPath}` });
152
+ ColorConsole_1.default.log(`### Emulator ### nuttx path: ${nuttxBinPath}`);
183
153
  let portMappingStr = `user,id=u1,hostfwd=tcp:127.0.0.1:${this.adbPort}-10.0.2.15:5555`;
184
154
  if (devtool) {
185
155
  this.debugPort = yield portfinder_1.default.getPortPromise({ port: this.debugPort });
186
- ColorConsole_1.default.log({ message: `### Emulator ### debug port: ${this.debugPort}` });
156
+ ColorConsole_1.default.log(`### Emulator ### debug port: ${this.debugPort}`);
187
157
  portMappingStr += `,hostfwd=tcp:127.0.0.1:${this.debugPort}-10.0.2.15:101`;
188
158
  }
189
- ColorConsole_1.default.log({ message: `### Emulator ### Start qemu with TCP: ${portMappingStr}` });
159
+ ColorConsole_1.default.log(`### Emulator ### Start qemu with TCP: ${portMappingStr}`);
190
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
+ }
169
+ // 启动goldfish的命令和参数
170
+ const spawnBin = emulatorBin;
171
+ const spawnArgs = [
172
+ '-nuttx',
173
+ '-avd',
174
+ avdName,
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(' ')}`);
191
189
  return new Promise((resolve) => {
192
- var _a, _b;
193
- this.goldfishProcess = (0, child_process_1.spawn)(emulatorBin, [
194
- '-nuttx',
195
- '-avd',
196
- avdName,
197
- '-avd-arch',
198
- avdArch,
199
- '-show-kernel',
200
- '-kernel',
201
- nuttxBinPath,
202
- '-qemu',
203
- '-netdev',
204
- portMappingStr,
205
- '-device',
206
- 'virtio-net-device,netdev=u1,bus=virtio-mmio-bus.3'
207
- ], { stdio: stdioType });
208
- if (options.disableNSH) {
209
- (_a = this.goldfishProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
210
- console.log(data.toString());
190
+ var _a;
191
+ this.goldfishProcess = (0, child_process_1.spawn)(spawnBin, spawnArgs, { stdio: stdioType, shell: true });
192
+ (_a = this.goldfishProcess.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
193
+ const stderrCb = options.stderrCallback || console.log;
194
+ stderrCb(data.toString());
195
+ });
196
+ this.goldfishProcess.on('exit', (code) => {
197
+ ColorConsole_1.default.error(`### Emulator ### Goldfish emulator exited with code ${code}`);
198
+ if (options.exitCallback) {
199
+ options.exitCallback(code);
200
+ }
201
+ });
202
+ const p1 = new Promise((resolve) => {
203
+ var _a, _b;
204
+ (_b = (_a = this.goldfishProcess) === null || _a === void 0 ? void 0 : _a.stdout) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
205
+ const stdoutCb = options.stdoutCallback || console.log;
206
+ stdoutCb(data.toString());
211
207
  if (data.toString().includes('(NSH)')) {
212
- ColorConsole_1.default.log({ message: `### Emulator ### Goldfish emulator starts successfully` });
208
+ ColorConsole_1.default.log(`### Emulator ### Goldfish emulator starts successfully`);
213
209
  resolve();
214
210
  }
215
211
  });
216
- (_b = this.goldfishProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
217
- console.log(data.toString());
218
- });
219
- }
220
- else {
221
- setTimeout(() => {
222
- ColorConsole_1.default.log({ message: `### Emulator ### Goldfish emulator starts successfully` });
223
- resolve();
224
- }, 2000);
225
- }
226
- this.goldfishProcess.on('exit', (code) => {
227
- ColorConsole_1.default.log({
228
- level: shared_utils_1.LOG_LEVEL.Error,
229
- message: `### Emulator ### Goldfish emulator exited with code ${code}`,
230
- isOnlyPrintError: true
231
- });
232
212
  });
213
+ const p2 = setTimeout(() => {
214
+ ColorConsole_1.default.log(`### Emulator ### Goldfish emulator starts successfully`);
215
+ resolve();
216
+ }, 2000);
217
+ return Promise.race([p1, p2]);
233
218
  });
234
219
  });
235
220
  }
@@ -241,14 +226,14 @@ class GoldfishInstance {
241
226
  const sn = `127.0.0.1:${this.adbPort}`;
242
227
  while (!adbConnected) {
243
228
  const adbKillCmd = `adb kill-server`;
244
- ColorConsole_1.default.log({ message: `### Emulator ### Excuting adb cmd: ${adbKillCmd}` });
229
+ ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${adbKillCmd}`);
245
230
  adbMiwt.execAdbCmdSync(adbKillCmd);
246
231
  const adbConnectCmd = `adb connect ${sn}`;
247
- ColorConsole_1.default.log({ message: `### Emulator ### Excuting adb cmd: ${adbConnectCmd}` });
232
+ ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${adbConnectCmd}`);
248
233
  const str = adbMiwt.execAdbCmdSync(adbConnectCmd);
249
- ColorConsole_1.default.log({ message: `### Emulator ### ${str}` });
234
+ ColorConsole_1.default.log(`### Emulator ### ${str}`);
250
235
  const devices = yield adbMiwt.getAdbDevices();
251
- ColorConsole_1.default.log({ message: `### Emulator ### adb devices: ${JSON.stringify(devices)}` });
236
+ ColorConsole_1.default.log(`### Emulator ### adb devices: ${JSON.stringify(devices)}`);
252
237
  adbConnected =
253
238
  devices.filter((item) => item.sn === sn && item.status === 'device').length > 0;
254
239
  }
@@ -263,50 +248,28 @@ class GoldfishInstance {
263
248
  return adbConnected;
264
249
  });
265
250
  }
266
- /** 将打包后的文件推到挂载的快应用目录 */
267
- pushRpk() {
268
- const buildDir = path_1.default.resolve(this.projectPath, 'build');
269
- const { package: appPackageName } = UxFileUtils_1.default.getMainfestInfo(this.projectPath);
270
- const appRunDir = path_1.default.resolve(this.sdkHome, 'qa/app', appPackageName);
271
- ColorConsole_1.default.log({ message: `### Emulator ### Pushing ${appPackageName} to ${appRunDir}` });
272
- fs_1.default.rmSync(appRunDir, { recursive: true, force: true });
273
- FileUtil_1.default.copyFiles(buildDir, appRunDir);
274
- ColorConsole_1.default.log({
275
- message: `### Emulator ### Push ${appPackageName} to ${appRunDir} successfully`
251
+ pushRpk(sourceRoot) {
252
+ return __awaiter(this, void 0, void 0, function* () {
253
+ const { package: appPackageName } = this.projectInfo;
254
+ const appRunDir = path_1.default.resolve(this.sdkHome, 'qa/app', appPackageName);
255
+ ColorConsole_1.default.log(`### Emulator ### Pushing ${appPackageName} to ${appRunDir}`);
256
+ fs_1.default.rmSync(appRunDir, { recursive: true, force: true });
257
+ FileUtil_1.default.copyFiles(sourceRoot, appRunDir);
258
+ ColorConsole_1.default.log(`### Emulator ### Push ${appPackageName} to ${appRunDir} successfully`);
276
259
  });
277
260
  }
278
- /** 杀死进程 */
279
- killProcess(currProcess) {
280
- if (currProcess && currProcess.pid && currProcess.exitCode === null) {
281
- console.log('process pid:', currProcess.pid);
282
- try {
283
- if (os_1.default.platform() === 'win32') {
284
- (0, child_process_1.execSync)(`taskkill /pid ${currProcess.pid} /T /F`);
285
- }
286
- else if (os_1.default.platform() === 'darwin') {
287
- process.kill(currProcess.pid);
288
- }
289
- else {
290
- currProcess.kill();
291
- }
292
- }
293
- catch (err) {
294
- ColorConsole_1.default.log({ message: `kill process get error :\n${err.stack}` });
295
- }
296
- }
297
- }
298
261
  /** 停止模拟器并释放相关资源 */
299
262
  stop() {
300
- if (this.goldfishProcess) {
301
- this.killProcess(this.goldfishProcess);
302
- this.goldfishProcess = undefined;
303
- }
304
- if (this.v9fsProcess) {
305
- this.killProcess(this.v9fsProcess);
306
- this.v9fsProcess = undefined;
307
- }
263
+ const _super = Object.create(null, {
264
+ stop: { get: () => super.stop }
265
+ });
266
+ return __awaiter(this, void 0, void 0, function* () {
267
+ _super.stop.call(this);
268
+ if (this.v9fsProcess) {
269
+ this.killProcess(this.v9fsProcess);
270
+ this.v9fsProcess = undefined;
271
+ }
272
+ });
308
273
  }
309
274
  }
310
- exports.default = GoldfishInstance;
311
-
312
- //# sourceMappingURL=goldfish.js.map
275
+ exports.default = OldGoldfishInstance;
@@ -5,3 +5,15 @@ export declare const defaultEmulatorHome: string;
5
5
  export declare const defaultSkinHome: string;
6
6
  export declare const defaultQuickappHome: string;
7
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
+ };
@@ -3,7 +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
- exports.defaultToolsHome = exports.defaultQuickappHome = exports.defaultSkinHome = exports.defaultEmulatorHome = exports.defaultImageHome = exports.defaultAvdHome = exports.defaultSDKHome = void 0;
6
+ exports.emulatorEnvVersion = exports.defaultVncPort = exports.defaultToolsHome = exports.defaultQuickappHome = exports.defaultSkinHome = exports.defaultEmulatorHome = exports.defaultImageHome = exports.defaultAvdHome = exports.defaultSDKHome = void 0;
7
7
  const os_1 = __importDefault(require("os"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  exports.defaultSDKHome = path_1.default.resolve(os_1.default.homedir(), '.export');
@@ -13,5 +13,15 @@ exports.defaultEmulatorHome = path_1.default.resolve(exports.defaultSDKHome, 'em
13
13
  exports.defaultSkinHome = path_1.default.resolve(exports.defaultSDKHome, 'skins');
14
14
  exports.defaultQuickappHome = path_1.default.resolve(exports.defaultSDKHome, 'qa');
15
15
  exports.defaultToolsHome = path_1.default.resolve(exports.defaultSDKHome, 'tools');
16
-
17
- //# sourceMappingURL=constants.js.map
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
+ };
@@ -0,0 +1 @@
1
+ 10.0.2.15:101
package/lib/typing/Avd.js CHANGED
@@ -6,5 +6,3 @@ var IAvdArchType;
6
6
  IAvdArchType["arm"] = "arm";
7
7
  IAvdArchType["arm64"] = "arm64";
8
8
  })(IAvdArchType || (exports.IAvdArchType = IAvdArchType = {}));
9
-
10
- //# sourceMappingURL=Avd.js.map
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import { IAvdResourcePaths } from "./Avd";
2
3
  export interface INewGoldfishInstanceParams extends IAvdResourcePaths {
3
4
  projectPath: string;
@@ -7,4 +8,9 @@ export interface IStartOptions {
7
8
  avdName: string;
8
9
  devtool?: string;
9
10
  disableNSH?: boolean;
11
+ serverPort?: number;
12
+ vncPort?: number;
13
+ stdoutCallback?: (buffer: Buffer) => void;
14
+ stderrCallback?: (buffer: Buffer) => void;
15
+ exitCallback?: (code: number | null) => void;
10
16
  }
@@ -1,4 +1,2 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
-
4
- //# sourceMappingURL=Instance.js.map
@@ -0,0 +1,12 @@
1
+ /** 获取mac电脑的CPU架构
2
+ * node 15.0.0之后,m1芯片的mac的os.arch()才是arm64,在这之前都是x86
3
+ * 所以15.0.0之前无法通过os.arch()区分,也无法通过execSync('uname -m')区分
4
+ */
5
+ export declare function getSystemArch(): string | void;
6
+ /** 根据PID杀死进程 */
7
+ export declare function killProcessByPid(pid: string): void;
8
+ /**
9
+ * 根据命令杀死进程
10
+ */
11
+ export declare function killProcessByCmd(cmd: string): Promise<void>;
12
+ export declare function sleep(time: number): Promise<void>;
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.sleep = exports.killProcessByCmd = exports.killProcessByPid = exports.getSystemArch = void 0;
16
+ const ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
17
+ const child_process_1 = require("child_process");
18
+ const find_process_1 = __importDefault(require("find-process"));
19
+ const os_1 = __importDefault(require("os"));
20
+ const semver_1 = __importDefault(require("semver"));
21
+ const cpuArch = {
22
+ arm64: 'aarch64',
23
+ aarch64: 'aarch64',
24
+ x64: 'x86_64',
25
+ x86_64: 'x86_64',
26
+ };
27
+ /** 获取mac电脑的CPU架构
28
+ * node 15.0.0之后,m1芯片的mac的os.arch()才是arm64,在这之前都是x86
29
+ * 所以15.0.0之前无法通过os.arch()区分,也无法通过execSync('uname -m')区分
30
+ */
31
+ function getSystemArch() {
32
+ const platform = os_1.default.platform();
33
+ let osArch = os_1.default.arch();
34
+ const nodeVersion = process.version;
35
+ if (semver_1.default.lt(nodeVersion, '15.0.0') && platform === 'darwin') {
36
+ try {
37
+ (0, child_process_1.execSync)('sysctl -n sysctl.proc_translated');
38
+ osArch = 'arm64';
39
+ }
40
+ catch (_a) {
41
+ osArch = 'x64';
42
+ }
43
+ }
44
+ if (osArch !== 'arm64' && osArch !== 'x64') {
45
+ return ColorConsole_1.default.throw(`unsupport system`);
46
+ }
47
+ return cpuArch[osArch];
48
+ }
49
+ exports.getSystemArch = getSystemArch;
50
+ /** 根据PID杀死进程 */
51
+ function killProcessByPid(pid) {
52
+ try {
53
+ const cmd = os_1.default.platform() === "win32"
54
+ ? `taskkill /pid ${pid} /T /F`
55
+ : `kill -9 ${pid}`;
56
+ (0, child_process_1.execSync)(cmd);
57
+ }
58
+ catch (e) {
59
+ console.error(`kill process ${pid} get error: ${e}`);
60
+ }
61
+ }
62
+ exports.killProcessByPid = killProcessByPid;
63
+ /**
64
+ * 根据命令杀死进程
65
+ */
66
+ function killProcessByCmd(cmd) {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ if (!cmd)
69
+ return;
70
+ try {
71
+ const list = yield (0, find_process_1.default)('name', cmd);
72
+ list.forEach((item) => __awaiter(this, void 0, void 0, function* () {
73
+ killProcessByPid(item.pid.toString());
74
+ }));
75
+ }
76
+ catch (e) {
77
+ console.error(`kill process ${cmd} get error: ${e}`);
78
+ }
79
+ });
80
+ }
81
+ exports.killProcessByCmd = killProcessByCmd;
82
+ function sleep(time) {
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ return new Promise(resolve => setTimeout(resolve, time));
85
+ });
86
+ }
87
+ exports.sleep = sleep;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiot-toolkit/emulator",
3
- "version": "2.0.1-alpha.8",
3
+ "version": "2.0.2-beta.1",
4
4
  "description": "vela emulator tool.",
5
5
  "homepage": "",
6
6
  "license": "ISC",
@@ -35,10 +35,10 @@
35
35
  "emulator"
36
36
  ],
37
37
  "dependencies": {
38
- "@aiot-toolkit/aiotpack": "2.0.1-alpha.8",
39
- "@aiot-toolkit/shared-utils": "2.0.1-alpha.8",
38
+ "@aiot-toolkit/aiotpack": "2.0.2-beta.1",
39
+ "@aiot-toolkit/shared-utils": "2.0.2-beta.1",
40
40
  "find-process": "^1.4.7",
41
41
  "portfinder": "^1.0.32"
42
42
  },
43
- "gitHead": "67e2c953dfce560a6133656136fe71326140e91c"
43
+ "gitHead": "9244af36e617295ea4ff11a2f4f07f0e4f9f5f59"
44
44
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["avd/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport { defaultAvdHome, defaultImageHome, defaultSDKHome } from '../static/constants'\nimport { IAvdArchType, IAvdParams, IAvdResourcePaths } from '../typing/Avd'\n\nconst EAvdParamsToIni = {\n 'arm': {\n abiType: 'armeabi-v7a',\n },\n 'arm64': {\n abiType: 'arm64-v8a',\n }\n}\n\nclass VelaAvdCls {\n private avdHome: string\n private sdkHome: string\n\n constructor(avdResourcePaths: IAvdResourcePaths) {\n const { avdHome, sdkHome } = avdResourcePaths\n this.avdHome = avdHome || defaultAvdHome\n this.sdkHome = sdkHome || defaultSDKHome\n }\n\n createVelaAvd(avdParams: IAvdParams) {\n const { avdName, avdArch, avdWidth, avdHeight, avdSkin, avdImagePath = defaultImageHome } = avdParams\n const avdDir = path.resolve(this.avdHome, `${avdName}.avd`)\n const avdIni = path.resolve(this.avdHome, `${avdName}.ini`)\n const avdConfigIni = path.resolve(avdDir, 'config.ini')\n const nuttxAvdIniContent = `path=${avdDir}\\npath.rel=avd${path.sep}${avdName}.avd`\n const abiType = EAvdParamsToIni[avdArch]['abiType']\n const configIniJson: any = JSON.parse(fs.readFileSync(path.join(__dirname, '../static/avdConfigIni.json'), 'utf-8'))\n configIniJson['AvdId'] = avdName\n configIniJson['abi.type'] = abiType\n configIniJson['avd.ini.displayname'] = avdName\n configIniJson['hw.cpu.arch'] = avdArch\n if (avdSkin) {\n delete configIniJson['hw.lcd.height']\n delete configIniJson['hw.lcd.width']\n configIniJson['skin.dynamic'] = 'yes'\n configIniJson['skin.name'] = avdSkin\n configIniJson['skin.path'] = path.resolve(this.sdkHome, 'skins', avdSkin)\n } else {\n configIniJson['hw.lcd.height'] = avdHeight\n configIniJson['hw.lcd.width'] = avdWidth\n configIniJson['skin.dynamic'] = 'no'\n delete configIniJson['skin.name']\n delete configIniJson['skin.path']\n }\n configIniJson['image.sysdir.1'] = avdImagePath\n try {\n fs.mkdirSync(avdDir, { recursive: true })\n // 写入Vela_Virtual_Device.ini文件\n fs.writeFileSync(avdIni, nuttxAvdIniContent)\n // 写入Vela_Virtual_Device.avd/config.ini文件\n const fWrite = fs.createWriteStream(avdConfigIni)\n for (const item in configIniJson) {\n const line = `${item} = ${configIniJson[item]}\\n`\n fWrite.write(line);\n }\n fWrite.close();\n return true\n } catch (e) {\n return false\n }\n }\n\n getVelaAvdInfo(avdName: string) {\n const avdInfo: IAvdParams = {\n avdName,\n avdArch: IAvdArchType.arm,\n avdHeight: '',\n avdWidth: '',\n avdSkin: '',\n avdImagePath: ''\n }\n const currAvdDir = path.resolve(this.avdHome, `${avdName}.avd`)\n const configIni = path.resolve(currAvdDir, 'config.ini')\n const contents = fs.readFileSync(configIni, 'utf-8')\n // 这里需要使用惰性匹配\n const archRegex = /hw.cpu.arch = ([\\d\\D]+?)\\n/\n const archMatcher = contents.match(archRegex)\n const heightRegex = /hw.lcd.height = ([\\d\\D]+?)\\n/\n const heightMatcher = contents.match(heightRegex)\n const widthRegex = /hw.lcd.width = ([\\d\\D]+?)\\n/\n const widthMatcher = contents.match(widthRegex)\n const skinRegex = /skin.name = ([\\d\\D]+?)\\n/\n const skinMatcher = contents.match(skinRegex)\n const imagePathRegex = /image.sysdir.1 = ([\\d\\D]+?)\\n/\n const imagePathMather = contents.match(imagePathRegex)\n archMatcher && (avdInfo.avdArch = (archMatcher[1] as IAvdArchType))\n heightMatcher && (avdInfo.avdHeight = heightMatcher[1])\n widthMatcher && (avdInfo.avdWidth = widthMatcher[1])\n skinMatcher && (avdInfo.avdSkin = skinMatcher[1])\n imagePathMather && (avdInfo.avdImagePath = imagePathMather[1])\n return avdInfo\n }\n\n deleteVelaAvd(avdName: string) {\n const avdDir = path.resolve(this.avdHome, `${avdName}.avd`)\n const avdIni = path.resolve(this.avdHome, `${avdName}.ini`);\n try {\n fs.rmSync(avdDir, { recursive: true, force: true });\n fs.rmSync(avdIni, { force: true })\n return true\n } catch (e) {\n return false\n }\n }\n\n getVelaAvdList() {\n try {\n const avdList: IAvdParams[] = [];\n const files = fs.readdirSync(defaultAvdHome);\n const regex = /^(Vela[\\d\\D]*)\\.avd$/;\n for (const fileName of files) {\n const matcher = fileName.match(regex);\n if (matcher) {\n const avdName = matcher[1];\n const avdInfo = this.getVelaAvdInfo(avdName);\n avdList.push(avdInfo);\n }\n }\n return avdList;\n } catch (err) {\n return [];\n }\n }\n\n getVelaSkinList() {\n try {\n const skinList = []\n const skinHome = path.resolve(this.sdkHome, 'skins')\n let files = fs.readdirSync(skinHome)\n for (const fileName of files) {\n !fileName.startsWith('.') && skinList.push(fileName)\n }\n return skinList\n } catch (e) {\n return []\n }\n }\n}\n\nexport default VelaAvdCls\n"],"sourceRoot":"../../src"}
package/lib/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,gDAA8C;AAM1B,2FANA,aAAU,OAMA;AAL9B,mEAAkE;AAKhE,iGALkB,kBAAgB,OAKlB;AAJlB,+CAA6B;AAC7B,oDAAkC","file":"index.js","sourcesContent":["import { default as VelaAvdCls } from './avd';\nimport { default as GoldfishInstance } from './instance/goldfish';\nexport * from './typing/Avd';\nexport * from './typing/Instance';\n\nexport {\n GoldfishInstance, VelaAvdCls\n};\n\n"],"sourceRoot":"../src"}