@aiot-toolkit/emulator 2.0.6-beta.2 → 2.0.6-beta.21
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/emulatorutil/constants.d.ts +12 -6
- package/lib/emulatorutil/constants.js +50 -19
- package/lib/emulatorutil/running.js +1 -1
- package/lib/index.d.ts +4 -1
- package/lib/index.js +47 -7
- package/lib/instance/common.d.ts +4 -2
- package/lib/instance/common.js +17 -3
- package/lib/instance/index.d.ts +2 -1
- package/lib/instance/index.js +4 -2
- package/lib/instance/minisound.d.ts +1 -1
- package/lib/instance/minisound.js +15 -7
- package/lib/instance/miwear.d.ts +1 -1
- package/lib/instance/miwear.js +12 -4
- package/lib/instance/openSmartspeaker5.d.ts +19 -0
- package/lib/instance/openSmartspeaker5.js +70 -0
- package/lib/instance/pre.d.ts +1 -1
- package/lib/instance/pre.js +3 -1
- package/lib/instance/vela5.d.ts +1 -1
- package/lib/instance/vela5.js +12 -10
- package/lib/static/avdConfigIni.json +1 -1
- package/lib/static/proto/emulator_controller.proto +181 -26
- package/lib/static/proto/ui_controller_service.proto +147 -0
- package/lib/typing/Vvd.d.ts +7 -3
- package/lib/typing/Vvd.js +3 -0
- package/lib/vvd/grpc/index.d.ts +17 -8
- package/lib/vvd/grpc/index.js +126 -29
- package/lib/vvd/grpc/types/GrpcClient.d.ts +43 -2
- package/lib/vvd/grpc/types/UiControllerClient.d.ts +23 -0
- package/lib/vvd/grpc/types/index.d.ts +3 -0
- package/lib/vvd/grpc/types/index.js +38 -0
- package/lib/vvd/grpc/types/proto-types.d.ts +178 -0
- package/lib/vvd/grpc/types/proto-types.js +50 -0
- package/lib/vvd/index.d.ts +15 -8
- package/lib/vvd/index.js +183 -91
- package/package.json +5 -8
- package/lib/vvd/grpc/types/KeyEvent.d.ts +0 -19
- package/lib/vvd/grpc/types/KeyEvent.js +0 -20
- package/lib/vvd/grpc/types/MouseEvent.d.ts +0 -30
- /package/lib/vvd/grpc/types/{MouseEvent.js → UiControllerClient.js} +0 -0
package/lib/vvd/index.js
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.isHeadlessEnvironment = exports.VvdManager = void 0;
|
|
7
|
+
require("core-js/actual/promise/with-resolvers");
|
|
7
8
|
var _ColorConsole = _interopRequireDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
|
|
8
9
|
var _promises = _interopRequireDefault(require("fs/promises"));
|
|
9
10
|
var _fs = _interopRequireDefault(require("fs"));
|
|
@@ -62,12 +63,13 @@ exports.isHeadlessEnvironment = isHeadlessEnvironment;
|
|
|
62
63
|
class VvdManager {
|
|
63
64
|
// 需要复制的文件
|
|
64
65
|
binFiles = ['system.img', 'data.img', 'coredump.core', 'vela_data.bin', 'vela_resource.bin', 'vela_system.bin'];
|
|
65
|
-
constructor(
|
|
66
|
+
constructor() {
|
|
67
|
+
let vvdResourcePaths = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
66
68
|
const {
|
|
67
|
-
vvdHome
|
|
69
|
+
vvdHome,
|
|
68
70
|
sdkHome
|
|
69
71
|
} = vvdResourcePaths;
|
|
70
|
-
this.vvdHome =
|
|
72
|
+
this.vvdHome = vvdHome || _constants.defaultVvdHome;
|
|
71
73
|
this.sdkHome = sdkHome || _constants.defaultSDKHome;
|
|
72
74
|
if (!_fs.default.existsSync(this.vvdHome)) {
|
|
73
75
|
_fs.default.mkdirSync(this.vvdHome, {
|
|
@@ -99,7 +101,8 @@ class VvdManager {
|
|
|
99
101
|
density,
|
|
100
102
|
imageDir: imagePath = _constants.defaultImageHome,
|
|
101
103
|
customLcdRadius,
|
|
102
|
-
imageType
|
|
104
|
+
imageType,
|
|
105
|
+
marketName
|
|
103
106
|
} = vvdParams;
|
|
104
107
|
const vvdDir = _path.default.resolve(this.vvdHome, `${vvdName}.vvd`);
|
|
105
108
|
const vvdIni = _path.default.resolve(this.vvdHome, `${vvdName}.ini`);
|
|
@@ -111,11 +114,11 @@ class VvdManager {
|
|
|
111
114
|
configIniJson['abi.type'] = abiType;
|
|
112
115
|
configIniJson['avd.ini.displayname'] = vvdName;
|
|
113
116
|
configIniJson['hw.cpu.arch'] = arch;
|
|
114
|
-
configIniJson['hw.lcd.shape'] = shape;
|
|
115
|
-
configIniJson['hw.device.flavor'] = flavor;
|
|
116
|
-
configIniJson['hw.lcd.density'] = density;
|
|
117
|
-
configIniJson['ide.lcd.radius'] = customLcdRadius;
|
|
118
|
-
configIniJson['ide.image.type'] = imageType;
|
|
117
|
+
if (shape) configIniJson['hw.lcd.shape'] = shape;
|
|
118
|
+
if (flavor) configIniJson['hw.device.flavor'] = flavor;
|
|
119
|
+
if (density) configIniJson['hw.lcd.density'] = density;
|
|
120
|
+
if (customLcdRadius) configIniJson['ide.lcd.radius'] = customLcdRadius;
|
|
121
|
+
if (imageType) configIniJson['ide.image.type'] = imageType;
|
|
119
122
|
if (skin) {
|
|
120
123
|
delete configIniJson['hw.lcd.height'];
|
|
121
124
|
delete configIniJson['hw.lcd.width'];
|
|
@@ -129,9 +132,10 @@ class VvdManager {
|
|
|
129
132
|
delete configIniJson['skin.name'];
|
|
130
133
|
delete configIniJson['skin.path'];
|
|
131
134
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
+
if (marketName) {
|
|
136
|
+
configIniJson['product.marketname'] = marketName;
|
|
137
|
+
}
|
|
138
|
+
configIniJson['image.sysdir.1'] = imagePath;
|
|
135
139
|
try {
|
|
136
140
|
_fs.default.mkdirSync(vvdDir, {
|
|
137
141
|
recursive: true
|
|
@@ -180,8 +184,7 @@ class VvdManager {
|
|
|
180
184
|
width: '',
|
|
181
185
|
skin: '',
|
|
182
186
|
imageDir: '',
|
|
183
|
-
customLcdRadius: ''
|
|
184
|
-
imageType: _Vvd.VelaImageType.REL
|
|
187
|
+
customLcdRadius: ''
|
|
185
188
|
};
|
|
186
189
|
let currVvdDir = this.getVvdDir(vvdName);
|
|
187
190
|
const configIni = _path.default.resolve(currVvdDir, 'config.ini');
|
|
@@ -193,10 +196,10 @@ class VvdManager {
|
|
|
193
196
|
vvdInfo.width = config['hw.lcd.width'];
|
|
194
197
|
vvdInfo.shape = config['hw.lcd.shape'];
|
|
195
198
|
vvdInfo.skin = config['skin.name'];
|
|
196
|
-
vvdInfo.imageDir = config['image.sysdir.
|
|
197
|
-
vvdInfo.customImagePath = config['image.sysdir
|
|
199
|
+
vvdInfo.imageDir = config['image.sysdir.1'];
|
|
200
|
+
vvdInfo.customImagePath = config['ide.image.reset.sysdir'];
|
|
198
201
|
vvdInfo.customLcdRadius = config['ide.lcd.radius'];
|
|
199
|
-
vvdInfo.imageType = config['ide.image.type'];
|
|
202
|
+
if (config['ide.image.type']) vvdInfo.imageType = config['ide.image.type'];
|
|
200
203
|
if (vvdInfo.skin) {
|
|
201
204
|
try {
|
|
202
205
|
vvdInfo.skinInfo = this.getSkinInfo(vvdInfo.skin, config['skin.path']);
|
|
@@ -238,7 +241,12 @@ class VvdManager {
|
|
|
238
241
|
const matcher = fileName.match(regex);
|
|
239
242
|
if (matcher) {
|
|
240
243
|
const avdName = matcher[1];
|
|
241
|
-
|
|
244
|
+
let avdInfo;
|
|
245
|
+
try {
|
|
246
|
+
avdInfo = this.getVvdInfo(avdName);
|
|
247
|
+
} catch (error) {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
242
250
|
avdList.push(avdInfo);
|
|
243
251
|
}
|
|
244
252
|
}
|
|
@@ -313,6 +321,7 @@ class VvdManager {
|
|
|
313
321
|
const configIni = _path.default.resolve(currVvdDir, 'config.ini');
|
|
314
322
|
const contents = _fs.default.readFileSync(configIni, 'utf-8');
|
|
315
323
|
const config = (0, _ini.parse)(contents);
|
|
324
|
+
config['ide.image.reset.sysdir'] = config['image.sysdir.1'];
|
|
316
325
|
config['image.sysdir.1'] = target;
|
|
317
326
|
await _fs.default.promises.writeFile(configIni, (0, _ini.stringify)(config));
|
|
318
327
|
const defaultImageHome = config['image.sysdir.1'];
|
|
@@ -342,8 +351,7 @@ class VvdManager {
|
|
|
342
351
|
const config = (0, _ini.parse)(contents);
|
|
343
352
|
const home = this.getSDKPart(_Vvd.SDKParts.SYSTEM_IMAGES);
|
|
344
353
|
let imageDir = _path.default.resolve(home, config['ide.image.type']);
|
|
345
|
-
config['image.sysdir.
|
|
346
|
-
delete config['image.sysdir.1'];
|
|
354
|
+
config['image.sysdir.1'] = imageDir;
|
|
347
355
|
_fs.default.writeFileSync(configIni, (0, _ini.stringify)(config));
|
|
348
356
|
}
|
|
349
357
|
getEmulatorBinPath(sdkHome) {
|
|
@@ -362,13 +370,17 @@ class VvdManager {
|
|
|
362
370
|
let needUpdate = false;
|
|
363
371
|
|
|
364
372
|
// 检查 ramsize 调整为 1024
|
|
365
|
-
if (config['hw.ramSize'] < 1024) {
|
|
373
|
+
if (config['hw.ramSize'] && typeof config['hw.ramSize'] === 'number' && config['hw.ramSize'] < 1024) {
|
|
366
374
|
needUpdate = true;
|
|
367
375
|
config['hw.ramSize'] = 1024;
|
|
368
376
|
}
|
|
377
|
+
// 统一路径分隔符为 /
|
|
378
|
+
const normalizePath = p => p.replace(/\\/g, '/');
|
|
379
|
+
|
|
369
380
|
// 检查皮肤路径
|
|
370
|
-
|
|
371
|
-
|
|
381
|
+
const skinPath = config['skin.path'];
|
|
382
|
+
if (skinPath && normalizePath(skinPath.toString())?.includes('.export_dev/skins')) {
|
|
383
|
+
if (normalizePath(skinPath.toString())?.includes('.export_dev/skins/user')) {
|
|
372
384
|
// 自定义的皮肤,将自定义皮肤迁移到新的 sdk 目录中
|
|
373
385
|
const oldUserSkinDir = _path.default.join(_os.default.homedir(), '.export_dev/skins/user');
|
|
374
386
|
const newUserSkinDir = _path.default.join(this.sdkHome, 'skins', 'user');
|
|
@@ -388,13 +400,38 @@ class VvdManager {
|
|
|
388
400
|
}
|
|
389
401
|
}
|
|
390
402
|
needUpdate = true;
|
|
391
|
-
config['skin.path'] =
|
|
403
|
+
config['skin.path'] = normalizePath(skinPath.toString()).replace('.export_dev/skins', '.vela/sdk/skins');
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// 迁移 原来 user 目录中的 xiaomi_band_10
|
|
407
|
+
if (skinPath && normalizePath(skinPath.toString())?.endsWith('/user/xiaomi_band_10')) {
|
|
408
|
+
_ColorConsole.default.log('migrate user/xiaomi_band_10 to builtin/xiaomi_band_10');
|
|
409
|
+
config['skin.path'] = normalizePath(skinPath.toString()).replace('/user/xiaomi_band_10', '/builtin/xiaomi_band_10');
|
|
410
|
+
needUpdate = true;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// 检查 hw.cpu.ncore
|
|
414
|
+
if (config['hw.cpu.ncore'] && typeof config['hw.cpu.ncore'] === 'number' && config['hw.cpu.ncore'] > 2) {
|
|
415
|
+
needUpdate = true;
|
|
416
|
+
config['hw.cpu.ncore'] = 2;
|
|
392
417
|
}
|
|
393
418
|
|
|
394
419
|
// 检查镜像路径
|
|
395
|
-
if (config['image.sysdir.2']?.includes('.export_dev/system-images')) {
|
|
420
|
+
if (config['image.sysdir.2'] && normalizePath(config['image.sysdir.2'].toString())?.includes('.export_dev/system-images')) {
|
|
396
421
|
needUpdate = true;
|
|
397
|
-
config['image.sysdir.2'] = config['image.sysdir.2'].replace('.export_dev/system-images', '.vela/sdk/system-images');
|
|
422
|
+
config['image.sysdir.2'] = normalizePath(config['image.sysdir.2'].toString()).replace('.export_dev/system-images', '.vela/sdk/system-images');
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// 不在使用 'image.sysdir.2' 字段,统一使用 'ide.image.reset.sysdir'
|
|
426
|
+
if (config['image.sysdir.2']) {
|
|
427
|
+
needUpdate = true;
|
|
428
|
+
const oldVal = config['image.sysdir.2'];
|
|
429
|
+
// TODO delete 会造成 image.sysdir.2= 留下一个空值
|
|
430
|
+
delete config['image.sysdir.2'];
|
|
431
|
+
if (config['image.sysdir.1']) {
|
|
432
|
+
config['ide.image.reset.sysdir'] = config['image.sysdir.1'];
|
|
433
|
+
}
|
|
434
|
+
config['image.sysdir.1'] = oldVal;
|
|
398
435
|
}
|
|
399
436
|
if (needUpdate) {
|
|
400
437
|
await _promises.default.writeFile(configIni, (0, _ini.stringify)(config));
|
|
@@ -430,7 +467,7 @@ class VvdManager {
|
|
|
430
467
|
// -fsdev local,security_model=none,id=fsdev0,path=${HOST_9PFS_DIR} \
|
|
431
468
|
// -device virtio-9p-device,id=fs0,fsdev=fsdev0,mount_tag=host `
|
|
432
469
|
|
|
433
|
-
|
|
470
|
+
let qemuOption = `-device virtio-snd,bus=virtio-mmio-bus.2 -allow-host-audio -semihosting -smp 2`;
|
|
434
471
|
|
|
435
472
|
// qt windows 配置
|
|
436
473
|
// 在 docker,wls,等无界面平台上用 -no-window ,否则用 -qt-hide-window
|
|
@@ -449,10 +486,15 @@ class VvdManager {
|
|
|
449
486
|
}
|
|
450
487
|
const verboseOption = options.verbose ? `-verbose` : ``;
|
|
451
488
|
// 启动模拟器的命令和参数
|
|
452
|
-
|
|
453
|
-
const vvdInfo = this.getVvdInfo(vvdName);
|
|
489
|
+
|
|
454
490
|
await this.oldEmulatorMigrate(vvdName);
|
|
455
|
-
|
|
491
|
+
const vvdInfo = this.getVvdInfo(vvdName);
|
|
492
|
+
if (vvdInfo.imageType === _Vvd.VelaImageType.OPENVELA_SMARTSPEAKER_5) {
|
|
493
|
+
qemuOption = `-device virtio-snd,bus=virtio-mmio-bus.2 -allow-host-audio -semihosting -smp 4 -device virtio-gpu-device,xres=480,yres=800,bus=virtio-mmio-bus.5`;
|
|
494
|
+
}
|
|
495
|
+
const cmd = `${emulatorBin} -vela -avd ${options.vvdName} ${serialStr} -show-kernel ${portMappingStr} ${windowOption} ${grpcStr} ${verboseOption} -qemu ${qemuOption}`;
|
|
496
|
+
const imageDir = vvdInfo.customImagePath || vvdInfo.imageDir;
|
|
497
|
+
if (!imageDir) {
|
|
456
498
|
const errMsg = `${vvdName} is not supported`;
|
|
457
499
|
_ColorConsole.default.throw(errMsg);
|
|
458
500
|
throw new Error(errMsg);
|
|
@@ -506,13 +548,36 @@ class VvdManager {
|
|
|
506
548
|
const onErrout = options.stderrCallback || console.log;
|
|
507
549
|
const e = runningVvds.find(e => e['avd.name'] === vvdName);
|
|
508
550
|
const vvdInfo = this.getVvdInfo(vvdName);
|
|
551
|
+
const getImageType = async serial => {
|
|
552
|
+
if (vvdInfo.imageType) return vvdInfo.imageType;
|
|
553
|
+
// 如果不是通过 IDE 创建的模拟器,没有 imageType 字段,需要智能嗅探镜像类型
|
|
554
|
+
try {
|
|
555
|
+
const res = await (0, _adb.execAdbCmdAsync)(`adb -s emulator-${serial} shell uname -a`, {
|
|
556
|
+
timeout: 3000,
|
|
557
|
+
encoding: 'utf-8'
|
|
558
|
+
});
|
|
559
|
+
if (res.includes('miim-arm64')) {
|
|
560
|
+
return _Vvd.VelaImageType.OPENVELA_SMARTSPEAKER_5;
|
|
561
|
+
}
|
|
562
|
+
if (res.includes('miwear')) {
|
|
563
|
+
return _Vvd.VelaImageType.VELA_MIWEAR_WATCH_5;
|
|
564
|
+
}
|
|
565
|
+
if (res.includes('smartspeaker')) {
|
|
566
|
+
return _Vvd.VelaImageType.VELA_MIWEAR_MINISOUND_5;
|
|
567
|
+
}
|
|
568
|
+
} catch (error) {
|
|
569
|
+
return _Vvd.VelaImageType.VELA_WATCH_5;
|
|
570
|
+
}
|
|
571
|
+
return _Vvd.VelaImageType.VELA_WATCH_5;
|
|
572
|
+
};
|
|
509
573
|
|
|
510
574
|
// 该模拟器已经启动,则创建一个日志流返回
|
|
511
575
|
if (e) {
|
|
512
576
|
// 找出来它原来使用的 debugPort
|
|
513
577
|
const regex = /hostfwd=tcp:(.*?):(\d+)-10\.0\.2\.15:101/;
|
|
514
578
|
const debugPort = e.cmdline?.match(regex)?.[2];
|
|
515
|
-
const
|
|
579
|
+
const imageType = await getImageType(e['port.serial']);
|
|
580
|
+
const emulatorInstance = (0, _instance.findInstance)(imageType, {
|
|
516
581
|
serialPort: e['port.serial'],
|
|
517
582
|
vvdName: vvdName,
|
|
518
583
|
onStdout,
|
|
@@ -520,11 +585,16 @@ class VvdManager {
|
|
|
520
585
|
debugPort,
|
|
521
586
|
customLogger: options.customLogger
|
|
522
587
|
});
|
|
588
|
+
const velaAgent = (0, _grpc.createGrpcClient)(e);
|
|
589
|
+
await velaAgent.waitForReady();
|
|
590
|
+
emulatorInstance.xmsStatus.resolve();
|
|
523
591
|
return {
|
|
524
592
|
coldBoot: false,
|
|
525
593
|
emulatorInstance,
|
|
526
594
|
getAgent: () => (0, _grpc.createGrpcClient)(e),
|
|
527
|
-
grpcConfig: e
|
|
595
|
+
grpcConfig: e,
|
|
596
|
+
velaAgent,
|
|
597
|
+
imageType
|
|
528
598
|
};
|
|
529
599
|
}
|
|
530
600
|
|
|
@@ -533,65 +603,84 @@ class VvdManager {
|
|
|
533
603
|
const spawnArgs = cmd.split(' ');
|
|
534
604
|
const spawnBin = spawnArgs.shift();
|
|
535
605
|
logger(`Start CMD: ${cmd}`);
|
|
536
|
-
const
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
606
|
+
const {
|
|
607
|
+
resolve,
|
|
608
|
+
reject,
|
|
609
|
+
promise
|
|
610
|
+
} = Promise.withResolvers();
|
|
611
|
+
const emulatorProcess = (0, _child_process.spawn)(spawnBin, spawnArgs, {
|
|
612
|
+
stdio: 'pipe',
|
|
613
|
+
shell: true,
|
|
614
|
+
cwd: this.sdkHome
|
|
615
|
+
});
|
|
616
|
+
if (options.origin === _Instance.IStartOrigin.Terminal) {
|
|
617
|
+
process.stdin.pipe(emulatorProcess.stdin);
|
|
618
|
+
}
|
|
619
|
+
// 利用 readline 接口可解决子进程日志换行的问题
|
|
620
|
+
const readlines = (0, _logcat.attachReadline)(emulatorProcess, onStdout, onErrout);
|
|
621
|
+
const emulatorStartedHandler = async msg => {
|
|
622
|
+
if (msg.includes('INFO | Boot completed') || msg.includes('[AMS]')) {
|
|
623
|
+
const e = (0, _emulatorutil.getRunningAvdConfigByName)(vvdName);
|
|
624
|
+
if (e) {
|
|
625
|
+
const imageType = await getImageType(e['port.serial']);
|
|
626
|
+
const emulatorInstance = (0, _instance.findInstance)(imageType, {
|
|
627
|
+
serialPort: e['port.serial'],
|
|
628
|
+
vvdName: vvdName,
|
|
629
|
+
logcatProcess: emulatorProcess,
|
|
630
|
+
...readlines,
|
|
631
|
+
onStdout,
|
|
632
|
+
onErrout,
|
|
633
|
+
debugPort: options.debugPort,
|
|
634
|
+
customLogger: options.customLogger
|
|
635
|
+
});
|
|
636
|
+
readlines.stdoutReadline.off('line', emulatorStartedHandler);
|
|
637
|
+
const velaAgent = (0, _grpc.createGrpcClient)(e);
|
|
638
|
+
await velaAgent.waitForReady();
|
|
639
|
+
if ([_Vvd.VelaImageType.VELA_MIWEAR_WATCH_5, _Vvd.VelaImageType.REL].includes(imageType)) {
|
|
640
|
+
// 这个时候系统启动成功了,但是 rpk 安装程序还没准备好
|
|
641
|
+
const miwearXmsReadyHander = msg => {
|
|
642
|
+
const startedFunc = emulatorInstance.isXmsInited.bind(emulatorInstance);
|
|
643
|
+
if (startedFunc(msg)) {
|
|
644
|
+
readlines.stdoutReadline.off('line', miwearXmsReadyHander);
|
|
645
|
+
emulatorInstance.xmsStatus.resolve();
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
readlines.stdoutReadline.on('line', miwearXmsReadyHander);
|
|
572
649
|
} else {
|
|
573
|
-
|
|
650
|
+
emulatorInstance.xmsStatus.resolve();
|
|
574
651
|
}
|
|
652
|
+
logger(`${options.vvdName} started successfully`);
|
|
653
|
+
resolve({
|
|
654
|
+
coldBoot: true,
|
|
655
|
+
emulatorInstance,
|
|
656
|
+
getAgent: () => (0, _grpc.createGrpcClient)(e),
|
|
657
|
+
grpcConfig: e,
|
|
658
|
+
velaAgent,
|
|
659
|
+
imageType
|
|
660
|
+
});
|
|
661
|
+
} else {
|
|
662
|
+
reject('get emulator running config failed');
|
|
575
663
|
}
|
|
576
|
-
}
|
|
577
|
-
|
|
664
|
+
}
|
|
665
|
+
};
|
|
666
|
+
readlines.stdoutReadline.on('line', emulatorStartedHandler);
|
|
578
667
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
668
|
+
// 监听模拟器的退出事件
|
|
669
|
+
emulatorProcess.on('exit', code => {
|
|
670
|
+
logger(`${options.vvdName} emulator exited with code ${code}`);
|
|
671
|
+
if (options.exitCallback) {
|
|
672
|
+
options.exitCallback(code);
|
|
673
|
+
}
|
|
674
|
+
readlines.dispose();
|
|
675
|
+
reject();
|
|
676
|
+
});
|
|
588
677
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
});
|
|
678
|
+
// 监听模拟器的错误事件
|
|
679
|
+
emulatorProcess.on('error', err => {
|
|
680
|
+
readlines.dispose();
|
|
681
|
+
reject(err);
|
|
594
682
|
});
|
|
683
|
+
return promise;
|
|
595
684
|
}
|
|
596
685
|
stopVvd(name) {
|
|
597
686
|
let timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10 * 1000;
|
|
@@ -767,14 +856,17 @@ class VvdManager {
|
|
|
767
856
|
*/
|
|
768
857
|
async downloadSDK(opt) {
|
|
769
858
|
const updateList = opt.force ? Object.values(_Vvd.SDKParts) : await this.hasSDKPartUpdate();
|
|
770
|
-
let urls =
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
859
|
+
let urls = [];
|
|
860
|
+
for (const t of updateList) {
|
|
861
|
+
urls.push({
|
|
862
|
+
name: t,
|
|
863
|
+
url: await (0, _constants.getSDKPartDownloadUrl)(t)
|
|
864
|
+
});
|
|
865
|
+
}
|
|
774
866
|
if (opt.imageTypeArr) {
|
|
775
867
|
for (const imgType of opt.imageTypeArr) {
|
|
776
868
|
const needsUpdate = await this.isLocalImageNeedUpdate(imgType);
|
|
777
|
-
const downloadUrl = (0, _constants.getImageDownloadUrl)()[imgType];
|
|
869
|
+
const downloadUrl = (await (0, _constants.getImageDownloadUrl)())[imgType];
|
|
778
870
|
// 需要更新并且urls中不存在则添加
|
|
779
871
|
if (needsUpdate && urls.findIndex(u => u.url === downloadUrl) < 0) {
|
|
780
872
|
urls.push({
|
|
@@ -836,7 +928,7 @@ class VvdManager {
|
|
|
836
928
|
|
|
837
929
|
/** 下载vela系统镜像 */
|
|
838
930
|
async downloadImage(imageId, opt) {
|
|
839
|
-
const downloadUrls = (0, _constants.getImageDownloadUrl)();
|
|
931
|
+
const downloadUrls = await (0, _constants.getImageDownloadUrl)();
|
|
840
932
|
const u = downloadUrls[imageId];
|
|
841
933
|
const downloader = await (await ipull).downloadFile({
|
|
842
934
|
url: u,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiot-toolkit/emulator",
|
|
3
|
-
"version": "2.0.6-beta.
|
|
3
|
+
"version": "2.0.6-beta.21",
|
|
4
4
|
"description": "vela emulator tool.",
|
|
5
5
|
"homepage": "",
|
|
6
6
|
"license": "ISC",
|
|
@@ -23,10 +23,6 @@
|
|
|
23
23
|
"type": "git",
|
|
24
24
|
"url": ""
|
|
25
25
|
},
|
|
26
|
-
"author": {
|
|
27
|
-
"name": "juancao816",
|
|
28
|
-
"email": "caojuan2019@163.com"
|
|
29
|
-
},
|
|
30
26
|
"engines": {
|
|
31
27
|
"node": ">=12.0"
|
|
32
28
|
},
|
|
@@ -36,11 +32,12 @@
|
|
|
36
32
|
"emulator"
|
|
37
33
|
],
|
|
38
34
|
"dependencies": {
|
|
39
|
-
"@aiot-toolkit/shared-utils": "2.0.6-beta.
|
|
35
|
+
"@aiot-toolkit/shared-utils": "2.0.6-beta.21",
|
|
40
36
|
"@grpc/grpc-js": "^1.13.3",
|
|
41
37
|
"@grpc/proto-loader": "^0.7.13",
|
|
42
|
-
"@miwt/adb": "0.10.
|
|
38
|
+
"@miwt/adb": "0.10.5",
|
|
43
39
|
"adm-zip": "^0.5.16",
|
|
40
|
+
"core-js": "^3.48.0",
|
|
44
41
|
"dayjs": "^1.11.12",
|
|
45
42
|
"find-process": "^1.4.7",
|
|
46
43
|
"get-port": "^7.1.0",
|
|
@@ -53,5 +50,5 @@
|
|
|
53
50
|
"@types/adm-zip": "^0.5.5",
|
|
54
51
|
"@types/ini": "^4.1.1"
|
|
55
52
|
},
|
|
56
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "9294502171d727985c7a28a4a6f0c4a291623309"
|
|
57
54
|
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export declare enum KeyEventType {
|
|
2
|
-
KEYDOWN = 0,
|
|
3
|
-
KEYUP = 1,
|
|
4
|
-
KEYPRESS = 2
|
|
5
|
-
}
|
|
6
|
-
export declare enum KeyCodeType {
|
|
7
|
-
USB = 0,
|
|
8
|
-
EVDEV = 1,
|
|
9
|
-
XKB = 2,
|
|
10
|
-
WIN = 3,
|
|
11
|
-
MAC = 4
|
|
12
|
-
}
|
|
13
|
-
export interface GrpcKeyboardEvent {
|
|
14
|
-
codeType?: KeyCodeType;
|
|
15
|
-
eventType?: KeyEventType;
|
|
16
|
-
keyCode?: number | string;
|
|
17
|
-
key?: string;
|
|
18
|
-
text?: string;
|
|
19
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.KeyEventType = exports.KeyCodeType = void 0;
|
|
7
|
-
let KeyEventType = exports.KeyEventType = /*#__PURE__*/function (KeyEventType) {
|
|
8
|
-
KeyEventType[KeyEventType["KEYDOWN"] = 0] = "KEYDOWN";
|
|
9
|
-
KeyEventType[KeyEventType["KEYUP"] = 1] = "KEYUP";
|
|
10
|
-
KeyEventType[KeyEventType["KEYPRESS"] = 2] = "KEYPRESS";
|
|
11
|
-
return KeyEventType;
|
|
12
|
-
}({});
|
|
13
|
-
let KeyCodeType = exports.KeyCodeType = /*#__PURE__*/function (KeyCodeType) {
|
|
14
|
-
KeyCodeType[KeyCodeType["USB"] = 0] = "USB";
|
|
15
|
-
KeyCodeType[KeyCodeType["EVDEV"] = 1] = "EVDEV";
|
|
16
|
-
KeyCodeType[KeyCodeType["XKB"] = 2] = "XKB";
|
|
17
|
-
KeyCodeType[KeyCodeType["WIN"] = 3] = "WIN";
|
|
18
|
-
KeyCodeType[KeyCodeType["MAC"] = 4] = "MAC";
|
|
19
|
-
return KeyCodeType;
|
|
20
|
-
}({});
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export interface MouseEvent {
|
|
2
|
-
/**
|
|
3
|
-
* The horizontal coordinate. This is the physical location on the
|
|
4
|
-
* screen For example 0 indicates the leftmost coordinate.
|
|
5
|
-
*/
|
|
6
|
-
x?: number;
|
|
7
|
-
/**
|
|
8
|
-
* The vertical coordinate. This is the physical location on the screen
|
|
9
|
-
* For example 0 indicates the top left coordinate.
|
|
10
|
-
*/
|
|
11
|
-
y?: number;
|
|
12
|
-
/**
|
|
13
|
-
* Indicates which buttons are pressed.
|
|
14
|
-
* 0: No button was pressed
|
|
15
|
-
* 1: Primary button (left)
|
|
16
|
-
* 2: Secondary button (right)
|
|
17
|
-
*/
|
|
18
|
-
buttons?: number;
|
|
19
|
-
/**
|
|
20
|
-
* The display device where the mouse event occurred.
|
|
21
|
-
* Omitting or using the value 0 indicates the main display.
|
|
22
|
-
*/
|
|
23
|
-
display?: number;
|
|
24
|
-
}
|
|
25
|
-
export interface MouseEventOutput {
|
|
26
|
-
x: number;
|
|
27
|
-
y: number;
|
|
28
|
-
buttons: number;
|
|
29
|
-
display: number;
|
|
30
|
-
}
|
|
File without changes
|