@aiot-toolkit/emulator 2.0.5-alpha.1 → 2.0.5-beta.2

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.
@@ -20,6 +20,7 @@ export declare const systemImageBaseUrl = "https://vela-ide.cnbj3-fusion.mi-fds.
20
20
  */
21
21
  export declare const VelaImageVersionList: {
22
22
  label: string;
23
+ description: string;
23
24
  value: VelaImageType;
24
25
  time: string;
25
26
  hide: boolean;
@@ -41,5 +42,4 @@ export declare function getImageDownloadUrl(): Record<VelaImageType, string>;
41
42
  * {@link getImageDownloadUrl}
42
43
  */
43
44
  export declare function getSDKPartDownloadUrl(type: SDKParts): string;
44
- export declare function getDefaultImage(): VelaImageType;
45
- export declare function isVelaImageType(value: any): value is VelaImageType;
45
+ export { isVelaImageType, isMiwearImageType, getDefaultImage } from '../shared';
@@ -4,15 +4,32 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.emulatorBaseUrl = exports.defaultVvdHome = exports.defaultVncPort = exports.defaultToolsHome = exports.defaultSkinHome = exports.defaultSDKHome = exports.defaultQuickappHome = exports.defaultImageHome = exports.defaultEmulatorHome = exports.defaultDebugPort = exports.defaultAdbPort = exports.baseUrl = exports.VelaImageVersionList = exports.EmulatorEnvVersion = void 0;
7
- exports.getDefaultImage = getDefaultImage;
7
+ Object.defineProperty(exports, "getDefaultImage", {
8
+ enumerable: true,
9
+ get: function () {
10
+ return _shared.getDefaultImage;
11
+ }
12
+ });
8
13
  exports.getImageDownloadUrl = getImageDownloadUrl;
9
14
  exports.getSDKPartDownloadUrl = getSDKPartDownloadUrl;
10
- exports.isVelaImageType = isVelaImageType;
15
+ Object.defineProperty(exports, "isMiwearImageType", {
16
+ enumerable: true,
17
+ get: function () {
18
+ return _shared.isMiwearImageType;
19
+ }
20
+ });
21
+ Object.defineProperty(exports, "isVelaImageType", {
22
+ enumerable: true,
23
+ get: function () {
24
+ return _shared.isVelaImageType;
25
+ }
26
+ });
11
27
  exports.versionUrl = exports.systemImageBaseUrl = void 0;
12
28
  var _os = _interopRequireDefault(require("os"));
13
29
  var _path = _interopRequireDefault(require("path"));
14
30
  var _Vvd = require("../typing/Vvd");
15
31
  var _utils = require("../utils");
32
+ var _shared = require("../shared");
16
33
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
17
34
  const defaultSDKHome = exports.defaultSDKHome = _path.default.resolve(_os.default.homedir(), _Vvd.VELAHOME.SDK);
18
35
  const defaultVvdHome = exports.defaultVvdHome = _path.default.resolve(_os.default.homedir(), _Vvd.VELAHOME.VVD);
@@ -37,35 +54,37 @@ const systemImageBaseUrl = exports.systemImageBaseUrl = 'https://vela-ide.cnbj3-
37
54
  * vela-dev-0.0.4 : vela 4.0 dev 分支
38
55
  */
39
56
  const VelaImageVersionList = exports.VelaImageVersionList = [{
40
- label: 'vela-4.0-正式版',
41
- value: _Vvd.VelaImageType.REL,
42
- time: '20241205',
57
+ label: 'vela-miwear-watch-5.0',
58
+ description: '适用于手表/手环的,带表盘的 vela 5.0 镜像,不可自定义模拟器尺寸',
59
+ value: _Vvd.VelaImageType.VELA_MIWEAR_WATCH_5,
60
+ time: '20250225',
43
61
  hide: false,
44
62
  icon: ''
45
63
  }, {
46
- label: 'vela-4.0-测试版',
47
- value: _Vvd.VelaImageType.PRE,
48
- time: '20241205',
64
+ label: 'vela-watch-5.0',
65
+ description: '适用于手表/手环的,不带表盘的 vela 5.0 镜像,可自定义模拟器尺寸',
66
+ value: _Vvd.VelaImageType.VELA_WATCH_5,
67
+ time: '20250225',
49
68
  hide: false,
50
69
  icon: ''
51
70
  }, {
52
- label: 'vela-5.0-测试版',
53
- value: _Vvd.VelaImageType.VELA_PRE_5,
54
- time: '20241107',
55
- hide: true,
71
+ label: 'vela-miwear-watch-4.0',
72
+ description: '原 vela-release-4.0 版本,适用于手表/手环的,带表盘的 vela 4.0 镜像,不可自定义模拟器尺寸',
73
+ value: _Vvd.VelaImageType.REL,
74
+ time: '20250225',
75
+ hide: false,
56
76
  icon: ''
57
- }
58
- // {
59
- // label: 'vela-dev-开发版',
60
- // value: VelaImageType.DEV,
61
- // time: '20240712',
62
- // hide: true,
63
- // icon: ''
64
- // }
65
- ];
77
+ }, {
78
+ label: 'vela-watch-4.0',
79
+ description: 'vela-pre-4.0 版本,适用于手表/手环的,不带表盘的 vela 4.0 镜像,可自定义模拟器尺寸',
80
+ value: _Vvd.VelaImageType.PRE,
81
+ time: '20250225',
82
+ hide: false,
83
+ icon: ''
84
+ }];
66
85
  const EmulatorEnvVersion = exports.EmulatorEnvVersion = {
67
86
  name: '模拟器资源版本管理',
68
- [_Vvd.SDKParts.EMULATOR]: '0.0.9',
87
+ [_Vvd.SDKParts.EMULATOR]: '0.1.0',
69
88
  [_Vvd.SDKParts.QA]: '0.0.1',
70
89
  [_Vvd.SDKParts.SKINS]: '0.0.9',
71
90
  [_Vvd.SDKParts.SYSTEM_IMAGES]: VelaImageVersionList[0].time,
@@ -93,16 +112,10 @@ function getSDKPartDownloadUrl(type) {
93
112
  let hostOs = systemOs === 'win32' ? 'windows' : systemOs;
94
113
  return `${emulatorBaseUrl}/v${EmulatorEnvVersion.emulator}/${hostOs}-${hostArch}.zip`;
95
114
  case _Vvd.SDKParts.SYSTEM_IMAGES:
96
- return getImageDownloadUrl()[_Vvd.VelaImageType.REL];
115
+ return getImageDownloadUrl()[(0, _shared.getDefaultImage)()];
97
116
  case _Vvd.SDKParts.QA:
98
117
  case _Vvd.SDKParts.MODEM_SIMULATOR:
99
118
  case _Vvd.SDKParts.SKINS:
100
119
  return `${baseUrl}/${type}/v${EmulatorEnvVersion[type]}/${type}.zip`;
101
120
  }
102
- }
103
- function getDefaultImage() {
104
- return _Vvd.VelaImageType.REL;
105
- }
106
- function isVelaImageType(value) {
107
- return Object.values(_Vvd.VelaImageType).includes(value);
108
121
  }
@@ -2,13 +2,15 @@ import readline from 'readline';
2
2
  import { IEmulatorInstanceParams } from '../typing/Instance';
3
3
  import { VelaImageType } from '../typing/Vvd';
4
4
  import { ChildProcessWithoutNullStreams } from 'child_process';
5
- declare class CommonEmulatorInstance {
5
+ declare abstract class CommonEmulatorInstance {
6
6
  imageType: VelaImageType;
7
7
  appDir: string;
8
8
  static emulatorStartedFlag: RegExp;
9
9
  static appInstalledFlag: RegExp;
10
+ static appUninstalledFlag: RegExp;
10
11
  static appStartedFlag: RegExp;
11
12
  static isAppInstalled(log: string): boolean;
13
+ static isAppUninstalled(log: string, packageName: string): boolean;
12
14
  static isEmulatorStarted(log: string): boolean;
13
15
  sn: string;
14
16
  vvdName: string;
@@ -21,6 +23,16 @@ declare class CommonEmulatorInstance {
21
23
  logcatProcess: ChildProcessWithoutNullStreams;
22
24
  logger: (log: string) => void;
23
25
  constructor(params: IEmulatorInstanceParams);
26
+ /** 安装应用,留给子类实现 */
27
+ abstract install(rpkPath: string, packageName: string): Promise<void>;
28
+ /** 卸载应用,留给子类实现 */
29
+ abstract uninstall(packageName: string): Promise<void>;
30
+ /** 重启应用 */
31
+ abstract reloadApp(appName: string, debug?: boolean): Promise<void>;
32
+ /** 关闭应用 */
33
+ abstract closeApp(appName: string): Promise<void>;
34
+ /** 启动应用,留给子类实现 */
35
+ abstract startApp(packageName: string, debug: boolean): Promise<void>;
24
36
  /** 推送指定文件 */
25
37
  push(sourcePath: string, targetPath: string): Promise<string>;
26
38
  unzip(zipPath: string, targetPath: string): Promise<void>;
@@ -30,17 +42,7 @@ declare class CommonEmulatorInstance {
30
42
  * 判断模拟器是否 ready
31
43
  */
32
44
  isConnected(): Promise<boolean>;
33
- /** 安装应用,留给子类实现 */
34
- install(rpkPath: string, packageName: string): Promise<void>;
35
- /** 卸载应用,留给子类实现 */
36
- uninstall(packageName: string): Promise<void>;
37
- /** 启动应用,留给子类实现 */
38
- startApp(packageName: string, debug?: boolean): Promise<void>;
39
45
  pushAndInstall(rpkPath: string, appName: string): Promise<void>;
40
- /** 重启应用 */
41
- reloadApp(appName: string, debug?: boolean): Promise<void>;
42
- /** 关闭应用 */
43
- closeApp(appName: string): Promise<void>;
44
46
  /** 关闭模拟器 */
45
47
  poweroff(timeout?: number): Promise<void>;
46
48
  systemed(): Promise<string>;
@@ -18,10 +18,14 @@ class CommonEmulatorInstance {
18
18
  appDir = '/data/quickapp/app';
19
19
  static emulatorStartedFlag = /quickapp_rpk_installer_init|rpk installer init done|booting completed/;
20
20
  static appInstalledFlag = /InstallState_Finished|install finished/;
21
+ static appUninstalledFlag = /uninstalled app/;
21
22
  static appStartedFlag = /Start App loop/;
22
23
  static isAppInstalled(log) {
23
24
  return this.appInstalledFlag.test(log);
24
25
  }
26
+ static isAppUninstalled(log, packageName) {
27
+ return new RegExp(this.appUninstalledFlag + ':\\s+' + packageName).test(log);
28
+ }
25
29
  static isEmulatorStarted(log) {
26
30
  return this.emulatorStartedFlag.test(log);
27
31
  }
@@ -62,6 +66,16 @@ class CommonEmulatorInstance {
62
66
  }
63
67
  }
64
68
 
69
+ /** 安装应用,留给子类实现 */
70
+
71
+ /** 卸载应用,留给子类实现 */
72
+
73
+ /** 重启应用 */
74
+
75
+ /** 关闭应用 */
76
+
77
+ /** 启动应用,留给子类实现 */
78
+
65
79
  /** 推送指定文件 */
66
80
  async push(sourcePath, targetPath) {
67
81
  // 1. adb push应用的rpk
@@ -100,30 +114,11 @@ class CommonEmulatorInstance {
100
114
  return curDev?.status === 'device';
101
115
  }, 10, 500);
102
116
  }
103
-
104
- /** 安装应用,留给子类实现 */
105
- async install(rpkPath, packageName) {}
106
-
107
- /** 卸载应用,留给子类实现 */
108
- async uninstall(packageName) {}
109
-
110
- /** 启动应用,留给子类实现 */
111
- async startApp(packageName) {
112
- let debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
113
- }
114
117
  async pushAndInstall(rpkPath, appName) {
115
118
  const targetPath = await this.pushRpk(rpkPath, appName);
116
119
  await this.install(targetPath, appName);
117
120
  }
118
121
 
119
- /** 重启应用 */
120
- async reloadApp(appName) {
121
- let debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
122
- }
123
-
124
- /** 关闭应用 */
125
- async closeApp(appName) {}
126
-
127
122
  /** 关闭模拟器 */
128
123
  poweroff() {
129
124
  let timeout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10 * 1000;
@@ -1,6 +1,11 @@
1
1
  import CommonEmulatorInstance from './common';
2
2
  import { VelaImageType } from '../typing/Vvd';
3
+ /**
4
+ * @deprecated 不在使用
5
+ */
3
6
  declare class GoldfishInstance extends CommonEmulatorInstance {
7
+ uninstall(): Promise<void>;
8
+ closeApp(): Promise<void>;
4
9
  imageType: VelaImageType;
5
10
  static appDir: string;
6
11
  static emulatorStartedFlag: RegExp;
@@ -10,7 +10,16 @@ var _Vvd = require("../typing/Vvd");
10
10
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
11
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
12
12
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
13
+ /**
14
+ * @deprecated 不在使用
15
+ */
13
16
  class GoldfishInstance extends _common.default {
17
+ uninstall() {
18
+ throw new Error('Method not implemented.');
19
+ }
20
+ closeApp() {
21
+ throw new Error('Method not implemented.');
22
+ }
14
23
  imageType = (() => _Vvd.VelaImageType.DEV)();
15
24
  static appDir = '/data/app';
16
25
  static emulatorStartedFlag = /(NSH)/;
@@ -4,8 +4,9 @@ import MiwearInstance from './miwear';
4
4
  import PreInstance from './pre';
5
5
  import { VelaImageType } from '../typing/Vvd';
6
6
  import { IEmulatorInstanceParams } from '../typing/Instance';
7
- import { VelaPre5Instance } from './pre5';
8
- declare function getInstanceClass(imageType: VelaImageType): typeof GoldfishInstance | typeof MiwearInstance | typeof PreInstance | typeof VelaPre5Instance;
7
+ import { Vela5Instance } from './vela5';
8
+ import { VelaMiwear5 } from './miwear5';
9
+ declare function getInstanceClass(imageType: VelaImageType): typeof GoldfishInstance | typeof MiwearInstance | typeof PreInstance | typeof Vela5Instance | typeof VelaMiwear5;
9
10
  /**
10
11
  * 根据镜像决定使用哪个instance
11
12
  * Vela正式版(4.0) -> MiwearInstance
@@ -14,4 +15,4 @@ declare function getInstanceClass(imageType: VelaImageType): typeof GoldfishInst
14
15
  * Vela开发版(dev),除0.0.2的其他版本 -> GoldfishInstance
15
16
  */
16
17
  declare function findInstance(imageType: VelaImageType, params: IEmulatorInstanceParams): CommonEmulatorInstance;
17
- export { CommonEmulatorInstance as CommonInstance, GoldfishInstance, MiwearInstance, VelaPre5Instance, PreInstance, findInstance, getInstanceClass };
18
+ export { CommonEmulatorInstance as CommonInstance, GoldfishInstance, MiwearInstance, Vela5Instance, PreInstance, findInstance, getInstanceClass };
@@ -27,10 +27,10 @@ Object.defineProperty(exports, "PreInstance", {
27
27
  return _pre.default;
28
28
  }
29
29
  });
30
- Object.defineProperty(exports, "VelaPre5Instance", {
30
+ Object.defineProperty(exports, "Vela5Instance", {
31
31
  enumerable: true,
32
32
  get: function () {
33
- return _pre2.VelaPre5Instance;
33
+ return _vela.Vela5Instance;
34
34
  }
35
35
  });
36
36
  exports.findInstance = findInstance;
@@ -40,14 +40,16 @@ var _dev = _interopRequireDefault(require("./dev"));
40
40
  var _miwear = _interopRequireDefault(require("./miwear"));
41
41
  var _pre = _interopRequireDefault(require("./pre"));
42
42
  var _Vvd = require("../typing/Vvd");
43
- var _pre2 = require("./pre5");
43
+ var _vela = require("./vela5");
44
+ var _miwear2 = require("./miwear5");
44
45
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
45
46
  function getInstanceClass(imageType) {
46
47
  const map = {
47
48
  [_Vvd.VelaImageType.PRE]: _pre.default,
48
49
  [_Vvd.VelaImageType.REL]: _miwear.default,
49
50
  [_Vvd.VelaImageType.DEV]: _dev.default,
50
- [_Vvd.VelaImageType.VELA_PRE_5]: _pre2.VelaPre5Instance
51
+ [_Vvd.VelaImageType.VELA_WATCH_5]: _vela.Vela5Instance,
52
+ [_Vvd.VelaImageType.VELA_MIWEAR_WATCH_5]: _miwear2.VelaMiwear5
51
53
  };
52
54
  return map[imageType] || _dev.default;
53
55
  }
@@ -13,10 +13,15 @@ declare class MiwearInstance extends CommonEmulatorInstance {
13
13
  * @param targeRpk 快应用的rpk文件路径
14
14
  */
15
15
  install(targeRpk: string): Promise<void>;
16
+ /**
17
+ * 使用 pm 卸载快应用
18
+ * @param packageName 快应用的包名
19
+ */
20
+ uninstall(packageName: string): Promise<void>;
16
21
  /** 使用 am start 启动快应用 */
17
22
  startApp(packageName: string, debug?: boolean): Promise<void>;
18
23
  closeApp(appName: string): Promise<void>;
19
24
  reboot(): Promise<void>;
20
- reloadApp(appPackageName: string, _debug?: boolean): Promise<void>;
25
+ reloadApp(appPackageName: string): Promise<void>;
21
26
  }
22
27
  export default MiwearInstance;
@@ -44,6 +44,29 @@ class MiwearInstance extends _common.default {
44
44
  });
45
45
  }
46
46
 
47
+ /**
48
+ * 使用 pm 卸载快应用
49
+ * @param packageName 快应用的包名
50
+ */
51
+ uninstall(packageName) {
52
+ adbMiwt.execAdbCmd(`adb -s ${this.sn} shell pm uninstall ${packageName}`);
53
+ return new Promise((resolve, reject) => {
54
+ const func = msg => {
55
+ if (MiwearInstance.isAppUninstalled(msg, packageName)) {
56
+ clearTimeout(timer);
57
+ this.logger(`${this.vvdName} uninstalled ${packageName} successfully`);
58
+ resolve();
59
+ }
60
+ };
61
+ let timer = setTimeout(() => {
62
+ this.stdoutReadline.off('line', func);
63
+ this.logger(`unnstall ${this.vvdName} ${packageName} timeout`);
64
+ reject('Uninstall timeout');
65
+ }, 2 * 60 * 1000);
66
+ this.stdoutReadline.on('line', func);
67
+ });
68
+ }
69
+
47
70
  /** 使用 am start 启动快应用 */
48
71
  async startApp(packageName) {
49
72
  let debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@@ -82,7 +105,6 @@ class MiwearInstance extends _common.default {
82
105
  });
83
106
  }
84
107
  async reloadApp(appPackageName) {
85
- let _debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
86
108
  try {
87
109
  // 2. 执行am stop和am start命令
88
110
  const stopCmd = `adb -s ${this.sn} shell am stop ${appPackageName}`;
@@ -0,0 +1,4 @@
1
+ import MiwearInstance from './miwear';
2
+ export declare class VelaMiwear5 extends MiwearInstance {
3
+ appDir: string;
4
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.VelaMiwear5 = void 0;
7
+ var _miwear = _interopRequireDefault(require("./miwear"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ class VelaMiwear5 extends _miwear.default {
10
+ appDir = '/data/app';
11
+ }
12
+ exports.VelaMiwear5 = VelaMiwear5;
@@ -1,19 +1,21 @@
1
- import GoldfishInstance from './dev';
2
1
  import { VelaImageType } from '../typing/Vvd';
2
+ import CommonEmulatorInstance from './common';
3
3
  /**
4
4
  * 不带 miwear 的 4.0 镜像
5
5
  */
6
- declare class PreInstance extends GoldfishInstance {
6
+ declare class PreInstance extends CommonEmulatorInstance {
7
7
  imageType: VelaImageType;
8
8
  appDir: string;
9
+ static emulatorStartedFlag: RegExp;
9
10
  install(rpkPath: string, appPackageName?: string): Promise<void>;
11
+ uninstall(packageName: string): Promise<void>;
10
12
  /**
11
13
  * 在模拟器中启动快应用
12
14
  * 通过vapp命令启动,调试时需额外配置--jsdebugger参数
13
15
  * @param options
14
16
  */
15
17
  startApp(packageName: string, debug?: boolean): Promise<void>;
16
- closeApp(_appName: string): Promise<void>;
18
+ closeApp(): Promise<void>;
17
19
  reloadApp(appName: string, debug?: boolean): Promise<void>;
18
20
  }
19
21
  export default PreInstance;
@@ -4,18 +4,19 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _dev = _interopRequireDefault(require("./dev"));
8
7
  var adbMiwt = _interopRequireWildcard(require("@miwt/adb"));
9
8
  var _Vvd = require("../typing/Vvd");
9
+ var _common = _interopRequireDefault(require("./common"));
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
11
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
11
12
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
13
  /**
14
14
  * 不带 miwear 的 4.0 镜像
15
15
  */
16
- class PreInstance extends _dev.default {
16
+ class PreInstance extends _common.default {
17
17
  imageType = (() => _Vvd.VelaImageType.PRE)();
18
18
  appDir = '/data/quickapp/app';
19
+ static emulatorStartedFlag = /(NSH)/;
19
20
  async install(rpkPath, appPackageName) {
20
21
  // 基于 vapp 启动的应用只需要将 rpk 解压到指定的目录下
21
22
  rpkPath = rpkPath || `${this.appDir}/${appPackageName}.rpk`;
@@ -27,6 +28,13 @@ class PreInstance extends _dev.default {
27
28
  this.logger(`Excuting: ${unzipCmd}`);
28
29
  await adbMiwt.execAdbCmdAsync(unzipCmd);
29
30
  }
31
+ async uninstall(packageName) {
32
+ // 基于 vapp 启动的应用只需要将指定的目录下的文件删除即可
33
+ const targetPath = `${this.appDir}/${packageName}`;
34
+ const mkdirCmd = `adb -s ${this.sn} shell rm -r ${targetPath}`;
35
+ this.logger(`Excuting: ${mkdirCmd}`);
36
+ await adbMiwt.execAdbCmdAsync(mkdirCmd);
37
+ }
30
38
 
31
39
  /**
32
40
  * 在模拟器中启动快应用
@@ -49,7 +57,7 @@ class PreInstance extends _dev.default {
49
57
  this.logger(`Failed to startup app for ${this.vvdName}: ${e.message}`);
50
58
  }
51
59
  }
52
- async closeApp(_appName) {
60
+ async closeApp() {
53
61
  await this.reboot();
54
62
  }
55
63
  async reloadApp(appName) {
@@ -1,6 +1,8 @@
1
1
  import { VelaImageType } from '../typing/Vvd';
2
2
  import MiwearInstance from './miwear';
3
- export declare class VelaPre5Instance extends MiwearInstance {
3
+ export declare class Vela5Instance extends MiwearInstance {
4
+ static emulatorStartedFlag: RegExp;
5
+ static appStartedFlag: RegExp;
4
6
  imageType: VelaImageType;
5
7
  appDir: string;
6
8
  /**
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.VelaPre5Instance = void 0;
6
+ exports.Vela5Instance = void 0;
7
7
  var _Vvd = require("../typing/Vvd");
8
8
  var _miwear = _interopRequireDefault(require("./miwear"));
9
9
  var adbMiwt = _interopRequireWildcard(require("@miwt/adb"));
@@ -11,8 +11,10 @@ var _util = require("util");
11
11
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
12
12
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
13
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
- class VelaPre5Instance extends _miwear.default {
15
- imageType = (() => _Vvd.VelaImageType.VELA_PRE_5)();
14
+ class Vela5Instance extends _miwear.default {
15
+ static emulatorStartedFlag = /Boot completed/;
16
+ static appStartedFlag = /Start main loop/;
17
+ imageType = (() => _Vvd.VelaImageType.VELA_WATCH_5)();
16
18
  appDir = '/data/app';
17
19
 
18
20
  /**
@@ -34,4 +36,4 @@ class VelaPre5Instance extends _miwear.default {
34
36
  }
35
37
  }
36
38
  }
37
- exports.VelaPre5Instance = VelaPre5Instance;
39
+ exports.Vela5Instance = Vela5Instance;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 本文件用于导出一些同构内容,请勿引用非同构内容,例如 nodejs 特性内容,或者 browser 特性内容
3
+ * @TODO 项目转为 ESM 模块后,可以删除
4
+ * */
5
+ import { VelaImageType } from '../typing/Vvd';
6
+ export declare function isVelaImageType(value: any): value is VelaImageType;
7
+ export declare function isMiwearImageType(val: VelaImageType): boolean;
8
+ export declare function getDefaultImage(): VelaImageType;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getDefaultImage = getDefaultImage;
7
+ exports.isMiwearImageType = isMiwearImageType;
8
+ exports.isVelaImageType = isVelaImageType;
9
+ var _Vvd = require("../typing/Vvd");
10
+ /**
11
+ * 本文件用于导出一些同构内容,请勿引用非同构内容,例如 nodejs 特性内容,或者 browser 特性内容
12
+ * @TODO 项目转为 ESM 模块后,可以删除
13
+ * */
14
+
15
+ function isVelaImageType(value) {
16
+ return Object.values(_Vvd.VelaImageType).includes(value);
17
+ }
18
+ function isMiwearImageType(val) {
19
+ return [_Vvd.VelaImageType.REL, _Vvd.VelaImageType.VELA_MIWEAR_WATCH_5].includes(val);
20
+ }
21
+ function getDefaultImage() {
22
+ return _Vvd.VelaImageType.VELA_MIWEAR_WATCH_5;
23
+ }
@@ -8,7 +8,8 @@ export declare enum IVvdArchType {
8
8
  arm64 = "arm64"
9
9
  }
10
10
  export declare enum VelaImageType {
11
- VELA_PRE_5 = "vela-pre-5.0",
11
+ VELA_MIWEAR_WATCH_5 = "vela-miwear-watch-5.0",
12
+ VELA_WATCH_5 = "vela-watch-5.0",
12
13
  REL = "vela-release-4.0",
13
14
  PRE = "vela-pre-4.0",
14
15
  DEV = "vela-dev-0.0.4"
@@ -86,6 +87,7 @@ export interface DownloadItem {
86
87
  url: string;
87
88
  }
88
89
  export interface EmulatorSkin {
90
+ path: string;
89
91
  name: string;
90
92
  info: SkinInfo;
91
93
  backgroundImage: string;
package/lib/typing/Vvd.js CHANGED
@@ -10,7 +10,8 @@ let IVvdArchType = exports.IVvdArchType = /*#__PURE__*/function (IVvdArchType) {
10
10
  return IVvdArchType;
11
11
  }({});
12
12
  let VelaImageType = exports.VelaImageType = /*#__PURE__*/function (VelaImageType) {
13
- VelaImageType["VELA_PRE_5"] = "vela-pre-5.0";
13
+ VelaImageType["VELA_MIWEAR_WATCH_5"] = "vela-miwear-watch-5.0";
14
+ VelaImageType["VELA_WATCH_5"] = "vela-watch-5.0";
14
15
  VelaImageType["REL"] = "vela-release-4.0";
15
16
  VelaImageType["PRE"] = "vela-pre-4.0";
16
17
  VelaImageType["DEV"] = "vela-dev-0.0.4";
@@ -5,7 +5,9 @@ import type { DownloadFileOptions } from 'ipull';
5
5
  export declare class VvdManager {
6
6
  private vvdHome;
7
7
  private sdkHome;
8
+ binFiles: string[];
8
9
  constructor(vvdResourcePaths: IVvdResourcePaths);
10
+ static getDebuggerCfgFile(): string;
9
11
  /**
10
12
  * 创建Vela端的 VVD ,统一保存在 .vela/vvd 目录下
11
13
  * 1. 创建.vela/advancedFeatures.ini文件
@@ -42,7 +44,7 @@ export declare class VvdManager {
42
44
  defaultLayout: import("../typing/Vvd").EmulatorLayout;
43
45
  }[]>;
44
46
  /** 自定义模拟器的镜像目录 */
45
- customImageDir(vvdName: string, target: string): void;
47
+ customImageDir(vvdName: string, target: string): Promise<void>;
46
48
  /** 重置自定义的镜像目录 */
47
49
  resetImageDir(vvdName: string): void;
48
50
  getEmulatorBinPath(sdkHome: string): string;
package/lib/vvd/index.js CHANGED
@@ -42,6 +42,8 @@ const EAvdParamsToIni = {
42
42
  }
43
43
  };
44
44
  class VvdManager {
45
+ // 需要复制的文件
46
+ binFiles = ['system.img', 'data.img', 'coredump.core', 'vela_data.bin', 'vela_resource.bin', 'vela_system.bin'];
45
47
  constructor(vvdResourcePaths) {
46
48
  const {
47
49
  vvdHome: avdHome,
@@ -55,6 +57,9 @@ class VvdManager {
55
57
  });
56
58
  }
57
59
  }
60
+ static getDebuggerCfgFile() {
61
+ return _path.default.resolve(__dirname, '../static/debugger_ip.cfg');
62
+ }
58
63
 
59
64
  /**
60
65
  * 创建Vela端的 VVD ,统一保存在 .vela/vvd 目录下
@@ -282,13 +287,30 @@ class VvdManager {
282
287
  }
283
288
 
284
289
  /** 自定义模拟器的镜像目录 */
285
- customImageDir(vvdName, target) {
290
+ async customImageDir(vvdName, target) {
286
291
  const currVvdDir = this.getVvdDir(vvdName);
287
292
  const configIni = _path.default.resolve(currVvdDir, 'config.ini');
288
293
  const contents = _fs.default.readFileSync(configIni, 'utf-8');
289
294
  const config = (0, _ini.parse)(contents);
290
- config['image.sysdir.2'] = target;
291
- _fs.default.writeFileSync(configIni, (0, _ini.stringify)(config));
295
+ config['image.sysdir.1'] = target;
296
+ await _fs.default.promises.writeFile(configIni, (0, _ini.stringify)(config));
297
+ const defaultImageHome = config['image.sysdir.1'];
298
+ if (!defaultImageHome) {
299
+ _ColorConsole.default.warn(`defaultImageHome: ${vvdName} image dir is empty`);
300
+ return;
301
+ }
302
+ // 如果自定义的目录缺少 binFile 则从默认目录复制
303
+ for (const file of this.binFiles) {
304
+ const targetFile = _path.default.join(target, file);
305
+ const originFile = _path.default.join(defaultImageHome, file);
306
+ if (!_fs.default.existsSync(originFile)) continue;
307
+ if (!_fs.default.existsSync(targetFile)) {
308
+ // 文件不存在则直接复制
309
+ _fs.default.copyFileSync(originFile, targetFile);
310
+ } else {
311
+ _ColorConsole.default.warn(`${targetFile} is out-dated,if you want upadte it, please delete it,and use customImageDir again`);
312
+ }
313
+ }
292
314
  }
293
315
 
294
316
  /** 重置自定义的镜像目录 */
@@ -297,7 +319,10 @@ class VvdManager {
297
319
  const configIni = _path.default.resolve(currVvdDir, 'config.ini');
298
320
  const contents = _fs.default.readFileSync(configIni, 'utf-8');
299
321
  const config = (0, _ini.parse)(contents);
300
- delete config['image.sysdir.2'];
322
+ const home = this.getSDKPart(_Vvd.SDKParts.SYSTEM_IMAGES);
323
+ let imageDir = _path.default.resolve(home, config['ide.image.type']);
324
+ config['image.sysdir.2'] = imageDir;
325
+ delete config['image.sysdir.1'];
301
326
  _fs.default.writeFileSync(configIni, (0, _ini.stringify)(config));
302
327
  }
303
328
  getEmulatorBinPath(sdkHome) {
@@ -312,6 +337,7 @@ class VvdManager {
312
337
 
313
338
  // 获取emulator bin的绝对路径
314
339
  const emulatorBin = this.getEmulatorBinPath(this.sdkHome);
340
+ const vvdDir = this.getVvdDir(vvdName);
315
341
 
316
342
  // 端口映射
317
343
  const degbugProt = options.debugPort || (await (await getPort)({
@@ -322,6 +348,19 @@ class VvdManager {
322
348
  let portMappingStr = `-network-user-mode-options hostfwd=tcp:127.0.0.1:${degbugProt}-10.0.2.15:101`;
323
349
 
324
350
  // qemu 配置
351
+ const HOST_9PFS_DIR = _path.default.join(vvdDir, 'share');
352
+ if (!_fs.default.existsSync(HOST_9PFS_DIR)) {
353
+ await _fs.default.promises.mkdir(HOST_9PFS_DIR, {
354
+ recursive: true
355
+ });
356
+ }
357
+ // 9pfs device
358
+ // const qemuOption9p = `-netdev user,id=network,net=10.0.2.0/24,dhcpstart=10.0.2.16 \
359
+ // -device virtio-net-device,netdev=network,bus=virtio-mmio-bus.4 \
360
+ // -device virtio-snd,bus=virtio-mmio-bus.2 -allow-host-audio -semihosting \
361
+ // -fsdev local,security_model=none,id=fsdev0,path=${HOST_9PFS_DIR} \
362
+ // -device virtio-9p-device,id=fs0,fsdev=fsdev0,mount_tag=host `
363
+
325
364
  const qemuOption = `-device virtio-snd,bus=virtio-mmio-bus.2 -allow-host-audio -semihosting`;
326
365
 
327
366
  // qt windows 配置
@@ -344,12 +383,8 @@ class VvdManager {
344
383
  _ColorConsole.default.throw(errMsg);
345
384
  throw new Error(errMsg);
346
385
  }
347
-
348
- // 需要复制的文件
349
- const files = ['system.img', 'data.img', 'coredump.core', 'vela_data.bin', 'vela_resource.bin', 'vela_system.bin'];
350
- const vvdDir = this.getVvdDir(vvdName);
351
- const imageDir = _path.default.resolve(vvdInfo.imageDir);
352
- for (const file of files) {
386
+ const imageDir = _path.default.resolve(vvdInfo.customImagePath || vvdInfo.imageDir);
387
+ for (const file of this.binFiles) {
353
388
  const pOfVvd = _path.default.join(vvdDir, file);
354
389
  const pOfImageDir = _path.default.join(imageDir, file);
355
390
  if (!_fs.default.existsSync(pOfImageDir)) continue;
@@ -601,7 +636,8 @@ class VvdManager {
601
636
  continue;
602
637
  }
603
638
  if (resouces === _Vvd.SDKParts.SYSTEM_IMAGES) {
604
- if (await this.isLocalImageNeedUpdate((0, _constants.getDefaultImage)())) res.push(resouces);
639
+ const defaultImage = (0, _constants.getDefaultImage)();
640
+ if (await this.isLocalImageNeedUpdate(defaultImage)) res.push(resouces);
605
641
  continue;
606
642
  }
607
643
  if ((0, _semver.lt)(localVersion[resouces], _constants.EmulatorEnvVersion[resouces])) {
@@ -648,21 +684,17 @@ class VvdManager {
648
684
  url: (0, _constants.getSDKPartDownloadUrl)(t)
649
685
  }));
650
686
  if (opt.imageTypeArr) {
651
- // 首先过滤掉 REL 类型
652
- const filteredTypes = opt.imageTypeArr.filter(type => type !== _Vvd.VelaImageType.REL);
653
-
654
- // 异步检查每个类型是否需要更新
655
- const updateChecks = await Promise.all(filteredTypes.map(async type => ({
656
- type,
657
- needsUpdate: await this.isLocalImageNeedUpdate(type)
658
- })));
659
-
660
- // 过滤和映射
661
- const newUrls = updateChecks.filter(item => item.needsUpdate).map(item => ({
662
- name: item.type,
663
- url: (0, _constants.getImageDownloadUrl)()[item.type]
664
- }));
665
- urls = urls.concat(newUrls);
687
+ for (const imgType of opt.imageTypeArr) {
688
+ const needsUpdate = await this.isLocalImageNeedUpdate(imgType);
689
+ const downloadUrl = (0, _constants.getImageDownloadUrl)()[imgType];
690
+ // 需要更新并且urls中不存在则添加
691
+ if (needsUpdate && urls.findIndex(u => u.url === downloadUrl) < 0) {
692
+ urls.push({
693
+ name: imgType,
694
+ url: downloadUrl
695
+ });
696
+ }
697
+ }
666
698
  }
667
699
  const downloads = urls.map(async u => {
668
700
  const d = await (await ipull).downloadFile({
@@ -681,10 +713,16 @@ class VvdManager {
681
713
  return;
682
714
  }
683
715
  _ColorConsole.default.warn('All file resources have been successfully downloaded and are being decompressed.');
684
- for (const u of urls) {
716
+ for (let u of urls) {
717
+ // 如果是镜像则来自默认镜像
718
+ if (u.name === _Vvd.SDKParts.SYSTEM_IMAGES) u.name = (0, _constants.getDefaultImage)();
685
719
  // 解压
686
720
  const targetDirName = (0, _constants.isVelaImageType)(u.name) ? _Vvd.SDKParts.SYSTEM_IMAGES : u.name;
687
- const targetDir = u.name === _Vvd.SDKParts.SYSTEM_IMAGES || (0, _constants.isVelaImageType)(u.name) ? _path.default.resolve(this.sdkHome, targetDirName, _path.default.basename(u.url).replace('.zip', '')) : _path.default.resolve(this.sdkHome, targetDirName);
721
+ const targetDir = u.name === _Vvd.SDKParts.SYSTEM_IMAGES || (0, _constants.isVelaImageType)(u.name) ?
722
+ // 镜像解压的目录位于 sdkHome/system_images/imageId
723
+ _path.default.resolve(this.sdkHome, targetDirName, u.name) :
724
+ // 其他资源解压的目录位于 sdkHome/resource
725
+ _path.default.resolve(this.sdkHome, targetDirName);
688
726
  const targetDirExist = _fs.default.existsSync(targetDir);
689
727
  if (!targetDirExist) await _fs.default.promises.mkdir(targetDir, {
690
728
  recursive: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiot-toolkit/emulator",
3
- "version": "2.0.5-alpha.1",
3
+ "version": "2.0.5-beta.2",
4
4
  "description": "vela emulator tool.",
5
5
  "homepage": "",
6
6
  "license": "ISC",
@@ -36,7 +36,7 @@
36
36
  "emulator"
37
37
  ],
38
38
  "dependencies": {
39
- "@aiot-toolkit/shared-utils": "2.0.5-alpha.1",
39
+ "@aiot-toolkit/shared-utils": "2.0.5-beta.2",
40
40
  "@miwt/adb": "^0.9.0",
41
41
  "adm-zip": "^0.5.16",
42
42
  "dayjs": "^1.11.12",
@@ -51,5 +51,5 @@
51
51
  "@types/adm-zip": "^0.5.5",
52
52
  "@types/ini": "^4.1.1"
53
53
  },
54
- "gitHead": "8c8033a7a52e7cdb83606298ed8c4d6a585ba3ec"
54
+ "gitHead": "90f28324bb8bded7f04e1074dbf5ddc9a31f86f6"
55
55
  }