@aiot-toolkit/emulator 2.0.5-beta.8 → 2.0.5-widget-provider-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.
@@ -0,0 +1,117 @@
1
+ // Copyright (C) 2018 The Android Open Source Project
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ // Note that if you add/remove methods in this file you must update
16
+ // the metrics sql as well by running ./android/scripts/gen-grpc-sql.py
17
+ //
18
+ // Please group deleted methods in a block including the date (MM/DD/YY)
19
+ // it was removed. This enables us to easily keep metrics around after removal
20
+ //
21
+ // List of deleted methods
22
+ // rpc iWasDeleted (03/12/12)
23
+ // ...
24
+ syntax = "proto3";
25
+
26
+ option java_multiple_files = true;
27
+ option java_package = "com.android.emulator.control";
28
+ option objc_class_prefix = "AEC";
29
+
30
+ package android.emulation.control;
31
+ import "google/protobuf/empty.proto";
32
+
33
+ // An RTC service lets you interact with the emulator through WebRTC
34
+ // Note that this is currently an experimental feature, and that the
35
+ // service definition might change without notice. Use at your own risk!
36
+ //
37
+ // The following endpoints are needed to establish the webrtc protocol
38
+ // Due to limitiations in Javascript we cannot make use of bidirectional
39
+ // endpoints See this [blog](https://grpc.io/blog/state-of-grpc-web) for
40
+ // details.
41
+ service Rtc {
42
+ // This function will generate a new identifier that the client
43
+ // should use for further interaction. It will initiate the
44
+ // JSEP protocol on the server side.
45
+ rpc requestRtcStream(google.protobuf.Empty) returns (RtcId) {}
46
+
47
+ // Sends the given JsepMsg to the server. The RtcId in the
48
+ // message should point to an active stream negotiation in
49
+ // progress, otherwise the message will be ignored.
50
+ rpc sendJsepMessage(JsepMsg) returns (google.protobuf.Empty) {}
51
+
52
+ // Reads an available jsep messages for the given client id,
53
+ // blocking until one becomes available. Do not use the polling version
54
+ // above if you opt for this one.
55
+ //
56
+ // The ice candidates for example will trickle in on this callback,
57
+ // as will the SDP negotation.
58
+ rpc receiveJsepMessages(RtcId) returns (stream JsepMsg) {}
59
+
60
+
61
+ // [DEPRECATED] This is only here as the go grpc webproxy used
62
+ // by fuchsia does not support server side streaming. This method
63
+ // will be removed in the future and should not be relied upon.
64
+ //
65
+ // Reads an available jsep messages for the given client id,
66
+ // blocking until one becomes available. Do not use the polling version
67
+ // above if you opt for this one.
68
+ //
69
+ // The ice candidates for example will trickle in on this callback,
70
+ // as will the SDP negotation.
71
+ rpc receiveJsepMessage(RtcId) returns (JsepMsg) {}
72
+ }
73
+
74
+ message RtcId {
75
+ // The unique identifier of this connection. You will have to use the
76
+ // same identifier when sending/receiving messages. The server will
77
+ // generate a guid when receiving the start message.
78
+ string guid = 1;
79
+ }
80
+
81
+ message JsepMsg {
82
+ // The unique identifier of this connection. You will have to use the
83
+ // same identifier when sending/receiving messages. The server will
84
+ // generate a guid when receiving the start message.
85
+ RtcId id = 1;
86
+ // The JSON payload. This usually can be directly handled by the
87
+ // Javascript library.
88
+ //
89
+ // The dictionary can contain the following properties
90
+ //
91
+ // - bye:
92
+ // You can hang up now. No new message expected for you.
93
+ // The server has stopped the RTC stream.
94
+ //
95
+ // - start:
96
+ // An RTCConfiguration dictionary providing options to
97
+ // configure the new connection. This can include the
98
+ // turn configuration the serve is using. This dictionary can be
99
+ // passed in directly to the
100
+ // [RTCPeerConnection](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection)
101
+ // object.
102
+ //
103
+ // - candidate:
104
+ // The WebRTC API's RTCIceCandidateInit dictionary, which
105
+ // contains the information needed to fundamentally describe an
106
+ // RTCIceCandidate. See
107
+ // [RTCIceCandidate](https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidate)
108
+ // and [Session
109
+ // Lifetime](https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Session_lifetime)
110
+ // for more details.
111
+ //
112
+ // - sdp:
113
+ // RTCSessionDescriptionInit dictionary containing the values
114
+ // to that can be assigned to a
115
+ // [RTCSessionDescription](https://developer.mozilla.org/en-US/docs/Web/API/RTCSessionDescription)
116
+ string message = 2;
117
+ }
@@ -4,9 +4,9 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.IStartOrigin = void 0;
7
- /**
8
- * 如果指定了 serialPort 则必须同时指定 grpcPort
9
- * 否则
7
+ /**
8
+ * 如果指定了 serialPort 则必须同时指定 grpcPort
9
+ * 否则
10
10
  */
11
11
  let IStartOrigin = exports.IStartOrigin = /*#__PURE__*/function (IStartOrigin) {
12
12
  IStartOrigin["Terminal"] = "terminal";
@@ -24,9 +24,9 @@ const cpuArch = {
24
24
  x86_64: 'x86_64'
25
25
  };
26
26
 
27
- /** 获取mac电脑的CPU架构
28
- * node 15.0.0之后,m1芯片的mac的os.arch()才是arm64,在这之前都是x86
29
- * 所以15.0.0之前无法通过os.arch()区分,也无法通过execSync('uname -m')区分
27
+ /** 获取mac电脑的CPU架构
28
+ * node 15.0.0之后,m1芯片的mac的os.arch()才是arm64,在这之前都是x86
29
+ * 所以15.0.0之前无法通过os.arch()区分,也无法通过execSync('uname -m')区分
30
30
  */
31
31
  function getSystemArch() {
32
32
  const platform = _os.default.platform();
@@ -56,8 +56,8 @@ function killProcessByPid(pid) {
56
56
  }
57
57
  }
58
58
 
59
- /**
60
- * 根据命令杀死进程
59
+ /**
60
+ * 根据命令杀死进程
61
61
  */
62
62
  async function killProcessByCmd(cmd) {
63
63
  if (!cmd) return;
@@ -76,11 +76,11 @@ async function sleep(time) {
76
76
  return new Promise(resolve => setTimeout(resolve, time));
77
77
  }
78
78
 
79
- /**
80
- * 重复执行某个任务直到成功,或者超过最大次数
81
- * @param task 任务,需要返回 bool 值表示是否执行成功
82
- * @param {Number=} maxCount 最大重试次数
83
- * @param {number=} duration 每次重试的间隔
79
+ /**
80
+ * 重复执行某个任务直到成功,或者超过最大次数
81
+ * @param task 任务,需要返回 bool 值表示是否执行成功
82
+ * @param {Number=} maxCount 最大重试次数
83
+ * @param {number=} duration 每次重试的间隔
84
84
  */
85
85
  async function tryRun(task) {
86
86
  let maxCount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 5;
@@ -90,11 +90,11 @@ async function tryRun(task) {
90
90
  return Boolean(await task()) || (await delayRun(() => tryRun(task, maxCount, duration, currentCount + 1), duration));
91
91
  }
92
92
 
93
- /**
94
- * 延迟执行某个任务
95
- * @param task
96
- * @param duration
97
- * @returns
93
+ /**
94
+ * 延迟执行某个任务
95
+ * @param task
96
+ * @param duration
97
+ * @returns
98
98
  */
99
99
  async function delayRun(task) {
100
100
  let duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000;
@@ -105,10 +105,10 @@ async function delayRun(task) {
105
105
  });
106
106
  }
107
107
 
108
- /**
109
- * 为avdPort寻找一个不被占用的端口
110
- * 端口号必须是偶数且在5555和5585之间
111
- * @returns {number}
108
+ /**
109
+ * 为avdPort寻找一个不被占用的端口
110
+ * 端口号必须是偶数且在5555和5585之间
111
+ * @returns {number}
112
112
  */
113
113
  async function getEvenPort() {
114
114
  const startPort = 5556;
@@ -0,0 +1 @@
1
+ export declare function handleGrpcErrorMsg(err: Error | string): void;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.handleGrpcErrorMsg = handleGrpcErrorMsg;
7
+ function handleGrpcErrorMsg(err) {
8
+ if (typeof err === 'string') err = new Error(err);
9
+ console.error(err);
10
+ }
@@ -0,0 +1,27 @@
1
+ import { Readable } from 'stream';
2
+ import { MouseEvent } from './types/MouseEvent';
3
+ import { GrpcKeyboardEvent } from './types/KeyEvent';
4
+ import { GrpcClient } from './types/GrpcClient';
5
+ import { EmulatorConfig } from '../../emulatorutil/running';
6
+ import { Metadata } from '@grpc/grpc-js';
7
+ export default class GrpcEmulator {
8
+ eConf: EmulatorConfig;
9
+ protoPath: string;
10
+ client: GrpcClient;
11
+ connected: boolean;
12
+ token: string;
13
+ authMate: Metadata;
14
+ deadline: Date;
15
+ controller: any;
16
+ screenshotStream?: Readable;
17
+ constructor(eConf: EmulatorConfig, protoPath: string);
18
+ close(): void;
19
+ getAuthMeta(): Metadata;
20
+ waitForReady(): Promise<boolean>;
21
+ startStream(onStreamScreenshot: (buffer: Buffer) => void): Promise<void>;
22
+ getScreenshot(): Promise<Buffer>;
23
+ getStatus(): Promise<unknown>;
24
+ sendMouse(message: MouseEvent): void;
25
+ sendKey(data: GrpcKeyboardEvent): void;
26
+ }
27
+ export declare function createGrpcClient(eConf: EmulatorConfig): GrpcEmulator;
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createGrpcClient = createGrpcClient;
7
+ exports.default = void 0;
8
+ var _path = _interopRequireDefault(require("path"));
9
+ var _protoLoader = require("@grpc/proto-loader");
10
+ var _grpcError = require("./grpcError");
11
+ var _grpcJs = require("@grpc/grpc-js");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ class GrpcEmulator {
14
+ connected = false;
15
+ constructor(eConf, protoPath) {
16
+ this.eConf = eConf;
17
+ this.protoPath = protoPath;
18
+ this.token = eConf['grpc.token'];
19
+ const packageDefinition = (0, _protoLoader.loadSync)(this.protoPath, {
20
+ keepCase: true,
21
+ longs: String,
22
+ enums: String,
23
+ defaults: true,
24
+ oneofs: true
25
+ });
26
+ this.deadline = new Date();
27
+ this.deadline.setMinutes(this.deadline.getMinutes() + 2);
28
+ this.controller = (0, _grpcJs.loadPackageDefinition)(packageDefinition).android.emulation.control;
29
+ const mateInfo = new _grpcJs.Metadata();
30
+ mateInfo.set('Authorization', `Bearer ${this.token}`);
31
+ this.authMate = mateInfo;
32
+ this.client = new this.controller.EmulatorController(`127.0.0.1:${eConf['grpc.port']}`, _grpcJs.credentials.createInsecure());
33
+ }
34
+ close() {
35
+ this.client.close();
36
+ }
37
+ getAuthMeta() {
38
+ const token = this.eConf['grpc.token'];
39
+ const mateInfo = new _grpcJs.Metadata();
40
+ mateInfo.set('Authorization', `Bearer ${token}`);
41
+ return mateInfo;
42
+ }
43
+ waitForReady() {
44
+ if (this.connected) {
45
+ return Promise.resolve(true);
46
+ }
47
+ return new Promise((resolve, reject) => {
48
+ this.client.waitForReady(this.deadline, err => {
49
+ if (err) {
50
+ this.connected = false;
51
+ console.error(err);
52
+ return reject(err);
53
+ }
54
+ this.connected = true;
55
+ resolve(true);
56
+ });
57
+ });
58
+ }
59
+ async startStream(onStreamScreenshot) {
60
+ await this.waitForReady();
61
+ if (this.screenshotStream) {
62
+ this.screenshotStream.destroy();
63
+ }
64
+ this.screenshotStream = this.client.streamScreenshot(this.controller.Image, this.authMate);
65
+ this.screenshotStream.on('data', response => {
66
+ onStreamScreenshot(response.image);
67
+ });
68
+ this.screenshotStream.on('error', err => {
69
+ console.error(err.message);
70
+ });
71
+ }
72
+ getScreenshot() {
73
+ return new Promise((resolve, reject) => {
74
+ this.client.getScreenshot(this.controller.Image, this.authMate, (err, response) => {
75
+ if (err) {
76
+ reject(err);
77
+ }
78
+ resolve(response.image);
79
+ });
80
+ });
81
+ }
82
+ getStatus() {
83
+ return new Promise((resolve, reject) => {
84
+ this.client.getStatus(this.controller.EmulatorStatus, this.authMate, (err, response) => {
85
+ if (err) {
86
+ console.error(err);
87
+ (0, _grpcError.handleGrpcErrorMsg)(err);
88
+ return reject(err);
89
+ }
90
+ response.hardwareConfig = Object.fromEntries(response.hardwareConfig.entry.map(t => [t.key, t.value]));
91
+ return resolve(response);
92
+ });
93
+ });
94
+ }
95
+ sendMouse(message) {
96
+ if (!this.connected) return;
97
+ const e = {
98
+ x: message.x,
99
+ y: message.y,
100
+ buttons: message.buttons
101
+ };
102
+ this.client.sendMouse(e, this.authMate, err => {
103
+ if (err) console.error(err);
104
+ });
105
+ }
106
+ sendKey(data) {
107
+ if (!this.connected) return;
108
+ this.client.sendKey(data, this.authMate, err => {
109
+ if (err) console.error(err);
110
+ });
111
+ }
112
+ }
113
+ exports.default = GrpcEmulator;
114
+ function createGrpcClient(eConf) {
115
+ const protoPath = _path.default.join(__dirname, '../../static/proto/emulator_controller.proto');
116
+ return new GrpcEmulator(eConf, protoPath);
117
+ }
@@ -0,0 +1,4 @@
1
+ import { Client } from '@grpc/grpc-js';
2
+ export interface GrpcClient extends Client {
3
+ [i: string]: any;
4
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -0,0 +1,19 @@
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
+ }
@@ -0,0 +1,20 @@
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
+ }({});
@@ -0,0 +1,30 @@
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
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -2,6 +2,7 @@ import { IVvdParams, IVvdResourcePaths, SDKParts, SDKDownloadOpt, SkinInfo, Vela
2
2
  import { IStartOptions, IStartWithSerialPort } from '../typing/Instance';
3
3
  import { findInstance } from '../instance';
4
4
  import type { DownloadFileOptions } from 'ipull';
5
+ import GrpcEmulator from './grpc';
5
6
  export declare class VvdManager {
6
7
  private vvdHome;
7
8
  private sdkHome;
@@ -52,6 +53,7 @@ export declare class VvdManager {
52
53
  startVvd(options: IStartOptions | IStartWithSerialPort): Promise<{
53
54
  coldBoot: boolean;
54
55
  emulatorInstance: ReturnType<typeof findInstance>;
56
+ getAgent: () => GrpcEmulator;
55
57
  }>;
56
58
  stopVvd(name: string, timeout?: number): Promise<void>;
57
59
  /** 获取模拟器平台的名称,darwin-aarch64 linux-aarch64 windows-x86_64等 */
package/lib/vvd/index.js CHANGED
@@ -25,6 +25,7 @@ var _instance = require("../instance");
25
25
  var _logcat = require("./logcat");
26
26
  var _sharedUtils = require("@aiot-toolkit/shared-utils");
27
27
  var _ILog = require("@aiot-toolkit/shared-utils/lib/interface/ILog");
28
+ var _grpc = require("./grpc");
28
29
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
29
30
  // TODO: 升级构建工具支持 esm @xujunjie
30
31
  const getPort = (async () => {
@@ -61,13 +62,13 @@ class VvdManager {
61
62
  return _path.default.resolve(__dirname, '../static/debugger_ip.cfg');
62
63
  }
63
64
 
64
- /**
65
- * 创建Vela端的 VVD ,统一保存在 .vela/vvd 目录下
66
- * 1. 创建.vela/advancedFeatures.ini文件
67
- * 2. 创建.vela/vvd/${avdName}.ini文件
68
- * 3. 创建.vela/vvd/${avdName}.vvd/config.ini文件
69
- * @param vvdParams VVD参数,宽高、绑定的镜像路径等
70
- * @returns
65
+ /**
66
+ * 创建Vela端的 VVD ,统一保存在 .vela/vvd 目录下
67
+ * 1. 创建.vela/advancedFeatures.ini文件
68
+ * 2. 创建.vela/vvd/${avdName}.ini文件
69
+ * 3. 创建.vela/vvd/${avdName}.vvd/config.ini文件
70
+ * @param vvdParams VVD参数,宽高、绑定的镜像路径等
71
+ * @returns
71
72
  */
72
73
  createVvd(vvdParams) {
73
74
  const {
@@ -364,7 +365,7 @@ class VvdManager {
364
365
  const qemuOption = `-device virtio-snd,bus=virtio-mmio-bus.2 -allow-host-audio -semihosting`;
365
366
 
366
367
  // qt windows 配置
367
- const windowOption = options.qtHideWindow ? `-qt-hide-window` : '';
368
+ const windowOption = options.qtHideWindow ? `-no-window` : '';
368
369
  let grpcStr = options.grpcPort ? `-grpc ${options.grpcPort}` : '';
369
370
  let serialStr = ``;
370
371
  if (options.serialPort) {
@@ -446,7 +447,8 @@ class VvdManager {
446
447
  });
447
448
  return {
448
449
  coldBoot: false,
449
- emulatorInstance
450
+ emulatorInstance,
451
+ getAgent: () => (0, _grpc.createGrpcClient)(e)
450
452
  };
451
453
  }
452
454
 
@@ -488,7 +490,8 @@ class VvdManager {
488
490
  readlines.stdoutReadline.off('line', emulatorStartedHandler);
489
491
  resolve({
490
492
  coldBoot: true,
491
- emulatorInstance
493
+ emulatorInstance,
494
+ getAgent: () => (0, _grpc.createGrpcClient)(e)
492
495
  });
493
496
  } else {
494
497
  reject('get emulator running config failed');
@@ -529,7 +532,11 @@ class VvdManager {
529
532
  (0, _adb.execAdbCmdAsync)(`adb -s emulator-${config['port.serial']} shell poweroff`).then(() => {
530
533
  clearTimeout(t);
531
534
  resolve();
532
- }).catch(() => {
535
+ }).catch(e => {
536
+ if (e?.message?.includes(`device 'emulator-${config['port.serial']}' not found`)) {
537
+ // 清理之前的文件
538
+ _fs.default.unlinkSync(config.path);
539
+ }
533
540
  (0, _utils.killProcessByCmd)(config['avd.name']).then(() => {
534
541
  clearTimeout(t);
535
542
  resolve();
@@ -656,31 +663,31 @@ class VvdManager {
656
663
  }
657
664
  }
658
665
 
659
- /**
660
- * 下载 SDK,默认只下载需要更新的部分
661
- * @param opt.force 强制下载所有部分
662
- *
663
- * @example
664
- * async function main() {
665
- * const sdkHome = path.resolve(os.homedir(), '.export_dev1')
666
- * const velaAvdCls = new VelaAvdCls({ sdkHome })
667
- *
668
- * const downloder = await velaAvdCls.downloadSDK({
669
- * force: true,
670
- * cliProgress: false,
671
- * parallelDownloads: 6
672
- * })
673
- *
674
- * downloder.on('progress', (progress) => {
675
- * console.log(
676
- * `progress: ${progress.formattedSpeed} ${progress.formattedPercentage} ${progress.formatTotal} ${progress.formatTimeLeft}`
677
- * )
678
- * })
679
- *
680
- * await downloder.downlodPromise
681
- *
682
- * console.log('download success')
683
- * }
666
+ /**
667
+ * 下载 SDK,默认只下载需要更新的部分
668
+ * @param opt.force 强制下载所有部分
669
+ *
670
+ * @example
671
+ * async function main() {
672
+ * const sdkHome = path.resolve(os.homedir(), '.export_dev1')
673
+ * const velaAvdCls = new VelaAvdCls({ sdkHome })
674
+ *
675
+ * const downloder = await velaAvdCls.downloadSDK({
676
+ * force: true,
677
+ * cliProgress: false,
678
+ * parallelDownloads: 6
679
+ * })
680
+ *
681
+ * downloder.on('progress', (progress) => {
682
+ * console.log(
683
+ * `progress: ${progress.formattedSpeed} ${progress.formattedPercentage} ${progress.formatTotal} ${progress.formatTimeLeft}`
684
+ * )
685
+ * })
686
+ *
687
+ * await downloder.downlodPromise
688
+ *
689
+ * console.log('download success')
690
+ * }
684
691
  */
685
692
  async downloadSDK(opt) {
686
693
  const updateList = opt.force ? Object.values(_Vvd.SDKParts) : await this.hasSDKPartUpdate();
package/lib/vvd/logcat.js CHANGED
@@ -51,6 +51,9 @@ function attachReadline(p, onStdout, onErrout) {
51
51
  });
52
52
  }
53
53
  function dispose() {
54
+ p?.removeAllListeners();
55
+ stdoutReadline?.removeAllListeners();
56
+ stderrReadline?.removeAllListeners();
54
57
  stdoutReadline?.close();
55
58
  stderrReadline?.close();
56
59
  stdoutReadline = undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiot-toolkit/emulator",
3
- "version": "2.0.5-beta.8",
3
+ "version": "2.0.5-widget-provider-beta.1",
4
4
  "description": "vela emulator tool.",
5
5
  "homepage": "",
6
6
  "license": "ISC",
@@ -36,8 +36,10 @@
36
36
  "emulator"
37
37
  ],
38
38
  "dependencies": {
39
- "@aiot-toolkit/shared-utils": "2.0.5-beta.8",
40
- "@miwt/adb": "^0.9.0",
39
+ "@aiot-toolkit/shared-utils": "2.0.5-widget-provider-beta.1",
40
+ "@grpc/grpc-js": "^1.13.3",
41
+ "@grpc/proto-loader": "^0.7.13",
42
+ "@miwt/adb": "0.10.1",
41
43
  "adm-zip": "^0.5.16",
42
44
  "dayjs": "^1.11.12",
43
45
  "find-process": "^1.4.7",
@@ -51,5 +53,5 @@
51
53
  "@types/adm-zip": "^0.5.5",
52
54
  "@types/ini": "^4.1.1"
53
55
  },
54
- "gitHead": "4604e54b9b009689782201b828f39a067f5fb0d4"
56
+ "gitHead": "64842a2c374b8b3b344cef377d9c032eaf1a99a7"
55
57
  }