@aiot-toolkit/emulator 2.0.2-beta.10 → 2.0.2-beta.12

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,5 +20,9 @@ declare class VelaAvdCls {
20
20
  getVelaAvdList(): IAvdParams[];
21
21
  /** 获取模拟器皮肤列表 */
22
22
  getVelaSkinList(): string[];
23
+ /** 自定义模拟器的镜像目录 */
24
+ customImageDir(avdName: string, target: string): void;
25
+ /** 重置自定义的镜像目录 */
26
+ resetImageDir(avdName: string): void;
23
27
  }
24
28
  export default VelaAvdCls;
package/lib/avd/index.js CHANGED
@@ -3,18 +3,19 @@ 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
- const ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
6
+ const shared_utils_1 = require("@aiot-toolkit/shared-utils");
7
7
  const fs_1 = __importDefault(require("fs"));
8
+ const os_1 = __importDefault(require("os"));
8
9
  const path_1 = __importDefault(require("path"));
10
+ const ini_1 = require("ini");
9
11
  const constants_1 = require("../static/constants");
10
12
  const Avd_1 = require("../typing/Avd");
11
- const os_1 = __importDefault(require("os"));
12
13
  const EAvdParamsToIni = {
13
- 'arm': {
14
- abiType: 'armeabi-v7a',
14
+ arm: {
15
+ abiType: 'armeabi-v7a'
15
16
  },
16
- 'arm64': {
17
- abiType: 'arm64-v8a',
17
+ arm64: {
18
+ abiType: 'arm64-v8a'
18
19
  }
19
20
  };
20
21
  class VelaAvdCls {
@@ -72,16 +73,11 @@ class VelaAvdCls {
72
73
  // 写入Vela_Virtual_Device.ini文件
73
74
  fs_1.default.writeFileSync(avdIni, nuttxAvdIniContent);
74
75
  // 写入Vela_Virtual_Device.avd/config.ini文件
75
- const fWrite = fs_1.default.createWriteStream(avdConfigIni);
76
- for (const item in configIniJson) {
77
- const line = `${item} = ${configIniJson[item]}\n`;
78
- fWrite.write(line);
79
- }
80
- fWrite.close();
76
+ fs_1.default.writeFileSync(avdConfigIni, (0, ini_1.stringify)(configIniJson));
81
77
  return true;
82
78
  }
83
79
  catch (e) {
84
- throw (`createVelaAvd: ${e.message}`);
80
+ throw `createVelaAvd: ${e.message}`;
85
81
  }
86
82
  }
87
83
  /** 根据AVD名字获取模拟器的详细信息 */
@@ -98,26 +94,17 @@ class VelaAvdCls {
98
94
  const configIni = path_1.default.resolve(currAvdDir, 'config.ini');
99
95
  try {
100
96
  const contents = fs_1.default.readFileSync(configIni, 'utf-8');
101
- // 这里需要使用惰性匹配
102
- const archRegex = /hw.cpu.arch = ([\d\D]+?)\n/;
103
- const archMatcher = contents.match(archRegex);
104
- const heightRegex = /hw.lcd.height = ([\d\D]+?)\n/;
105
- const heightMatcher = contents.match(heightRegex);
106
- const widthRegex = /hw.lcd.width = ([\d\D]+?)\n/;
107
- const widthMatcher = contents.match(widthRegex);
108
- const skinRegex = /skin.name = ([\d\D]+?)\n/;
109
- const skinMatcher = contents.match(skinRegex);
110
- const imagePathRegex = /image.sysdir.1 = ([\d\D]+?)\n/;
111
- const imagePathMather = contents.match(imagePathRegex);
112
- archMatcher && (avdInfo.avdArch = archMatcher[1]);
113
- heightMatcher && (avdInfo.avdHeight = heightMatcher[1]);
114
- widthMatcher && (avdInfo.avdWidth = widthMatcher[1]);
115
- skinMatcher && (avdInfo.avdSkin = skinMatcher[1]);
116
- imagePathMather && (avdInfo.avdImagePath = imagePathMather[1]);
97
+ const config = (0, ini_1.parse)(contents);
98
+ avdInfo.avdArch = config['hw.cpu.arch'];
99
+ avdInfo.avdHeight = config['hw.lcd.height'];
100
+ avdInfo.avdWidth = config['hw.lcd.width'];
101
+ avdInfo.avdSkin = config['skin.name'];
102
+ avdInfo.avdImagePath = config['image.sysdir.1'];
103
+ avdInfo.customImagePath = config['image.sysdir.2'];
117
104
  return avdInfo;
118
105
  }
119
106
  catch (err) {
120
- ColorConsole_1.default.log(`getVelaAvdInfo: ${err.message}`);
107
+ shared_utils_1.ColorConsole.log(`getVelaAvdInfo: ${err.message}`);
121
108
  return avdInfo;
122
109
  }
123
110
  }
@@ -164,5 +151,23 @@ class VelaAvdCls {
164
151
  return [];
165
152
  }
166
153
  }
154
+ /** 自定义模拟器的镜像目录 */
155
+ customImageDir(avdName, target) {
156
+ const currAvdDir = path_1.default.resolve(this.avdHome, `${avdName}.avd`);
157
+ const configIni = path_1.default.resolve(currAvdDir, 'config.ini');
158
+ const contents = fs_1.default.readFileSync(configIni, 'utf-8');
159
+ const config = (0, ini_1.parse)(contents);
160
+ config['image.sysdir.2'] = target;
161
+ fs_1.default.writeFileSync(configIni, (0, ini_1.stringify)(config));
162
+ }
163
+ /** 重置自定义的镜像目录 */
164
+ resetImageDir(avdName) {
165
+ const currAvdDir = path_1.default.resolve(this.avdHome, `${avdName}.avd`);
166
+ const configIni = path_1.default.resolve(currAvdDir, 'config.ini');
167
+ const contents = fs_1.default.readFileSync(configIni, 'utf-8');
168
+ const config = (0, ini_1.parse)(contents);
169
+ delete config['image.sysdir.2'];
170
+ fs_1.default.writeFileSync(configIni, (0, ini_1.stringify)(config));
171
+ }
167
172
  }
168
173
  exports.default = VelaAvdCls;
package/lib/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { default as VelaAvdCls } from './avd';
2
+ import { getSystemArch } from './utils';
2
3
  export * from './instance';
3
4
  export * from './typing/Avd';
4
5
  export * from './typing/Instance';
5
- export { VelaAvdCls };
6
+ export * from './static/constants';
7
+ export { VelaAvdCls, getSystemArch };
package/lib/index.js CHANGED
@@ -17,9 +17,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.VelaAvdCls = void 0;
20
+ exports.getSystemArch = exports.VelaAvdCls = void 0;
21
21
  const avd_1 = __importDefault(require("./avd"));
22
22
  Object.defineProperty(exports, "VelaAvdCls", { enumerable: true, get: function () { return avd_1.default; } });
23
+ const utils_1 = require("./utils");
24
+ Object.defineProperty(exports, "getSystemArch", { enumerable: true, get: function () { return utils_1.getSystemArch; } });
23
25
  __exportStar(require("./instance"), exports);
24
26
  __exportStar(require("./typing/Avd"), exports);
25
27
  __exportStar(require("./typing/Instance"), exports);
28
+ __exportStar(require("./static/constants"), exports);
@@ -7,6 +7,7 @@ import { INewGoldfishInstanceParams, IStartOptions } from '../typing/Instance';
7
7
  * CommonInstance
8
8
  */
9
9
  declare class CommonInstance {
10
+ quickappStartedFlag: RegExp;
10
11
  projectPath: string;
11
12
  sdkHome: string;
12
13
  avdHome: string;
@@ -23,6 +24,10 @@ declare class CommonInstance {
23
24
  getEmulatorBinPath(): string;
24
25
  /** 在goldfish模拟器中运行快应用 */
25
26
  start(options: IStartOptions): Promise<void>;
27
+ /**
28
+ * 判断模拟器是否 ready
29
+ */
30
+ isConnected(): Promise<boolean>;
26
31
  /**
27
32
  * 通过adb连接模拟器。
28
33
  * 时间限制为 @param timeout 秒,超时则表示连接失败
@@ -36,21 +36,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  };
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
38
  const UxFileUtils_1 = __importDefault(require("@aiot-toolkit/aiotpack/lib/utils/ux/UxFileUtils"));
39
- const ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
39
+ const shared_utils_1 = require("@aiot-toolkit/shared-utils");
40
40
  const adbMiwt = __importStar(require("@miwt/adb"));
41
41
  const child_process_1 = require("child_process");
42
+ const fs_extra_1 = __importDefault(require("fs-extra"));
42
43
  const os_1 = __importDefault(require("os"));
43
44
  const path_1 = __importDefault(require("path"));
44
45
  const ws_1 = require("ws");
45
46
  const avd_1 = __importDefault(require("../avd"));
46
47
  const constants_1 = require("../static/constants");
47
48
  const utils_1 = require("../utils");
48
- const fs_extra_1 = __importDefault(require("fs-extra"));
49
49
  /**
50
50
  * CommonInstance
51
51
  */
52
52
  class CommonInstance {
53
53
  constructor(params) {
54
+ this.quickappStartedFlag = /__loadChunks/;
54
55
  this.isFirstStart = true;
55
56
  this.isDistributedApp = false;
56
57
  this.projectPath = params.projectPath;
@@ -81,6 +82,19 @@ class CommonInstance {
81
82
  start(options) {
82
83
  return __awaiter(this, void 0, void 0, function* () { });
83
84
  }
85
+ /**
86
+ * 判断模拟器是否 ready
87
+ */
88
+ isConnected() {
89
+ return __awaiter(this, void 0, void 0, function* () {
90
+ return (0, utils_1.tryRun)(() => __awaiter(this, void 0, void 0, function* () {
91
+ const devices = yield adbMiwt.getAdbDevices();
92
+ shared_utils_1.ColorConsole.log(`### Emulator ### adb devices: ${JSON.stringify(devices)}`);
93
+ const curDev = devices.find((t) => t.sn === this.sn);
94
+ return (curDev === null || curDev === void 0 ? void 0 : curDev.status) === 'device';
95
+ }), 10, 500);
96
+ });
97
+ }
84
98
  /**
85
99
  * 通过adb连接模拟器。
86
100
  * 时间限制为 @param timeout 秒,超时则表示连接失败
@@ -95,14 +109,14 @@ class CommonInstance {
95
109
  while (enableLoop && !adbConnected) {
96
110
  if (needKill) {
97
111
  const adbKillCmd = `adb kill-server`;
98
- ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${adbKillCmd}`);
112
+ shared_utils_1.ColorConsole.log(`### Emulator ### Excuting adb cmd: ${adbKillCmd}`);
99
113
  yield adbMiwt.execAdbCmdAsync(adbKillCmd);
100
114
  }
101
115
  const str = yield this.connectDevice();
102
- ColorConsole_1.default.log(`### Emulator ### ${str}`);
116
+ shared_utils_1.ColorConsole.log(`### Emulator ### ${str}`);
103
117
  // 查询模拟器的状态是否为“device”
104
118
  const devices = yield adbMiwt.getAdbDevices();
105
- ColorConsole_1.default.log(`### Emulator ### adb devices: ${JSON.stringify(devices)}`);
119
+ shared_utils_1.ColorConsole.log(`### Emulator ### adb devices: ${JSON.stringify(devices)}`);
106
120
  const curDev = devices.find((t) => t.sn === this.sn);
107
121
  if ((curDev === null || curDev === void 0 ? void 0 : curDev.status) === 'offline')
108
122
  needKill = true;
@@ -141,7 +155,7 @@ class CommonInstance {
141
155
  }
142
156
  }
143
157
  catch (err) {
144
- ColorConsole_1.default.log(`### Emulator ### kill process get error :\n${err.stack}`);
158
+ shared_utils_1.ColorConsole.log(`### Emulator ### kill process get error :\n${err.stack}`);
145
159
  }
146
160
  }
147
161
  }
@@ -179,13 +193,13 @@ class CommonInstance {
179
193
  port: (_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.serverPort
180
194
  });
181
195
  wsServer.on('connection', (socket) => {
182
- ColorConsole_1.default.success(`### App Socket server ### Websocket connects to websocket server`);
196
+ shared_utils_1.ColorConsole.success(`### App Socket server ### Websocket connects to websocket server`);
183
197
  socket.on('error', (err) => {
184
- ColorConsole_1.default.error(`### App Socket server ### Websocket server error: ${err.message}`);
198
+ shared_utils_1.ColorConsole.error(`### App Socket server ### Websocket server error: ${err.message}`);
185
199
  });
186
200
  socket.on('message', (data) => {
187
201
  const message = JSON.parse(data.toString());
188
- ColorConsole_1.default.log(`### App Socket server ### Websocket server get data: ${data}`);
202
+ shared_utils_1.ColorConsole.log(`### App Socket server ### Websocket server get data: ${data}`);
189
203
  if (message.type === 'restart') {
190
204
  this.restart();
191
205
  }
@@ -199,7 +213,7 @@ class CommonInstance {
199
213
  connectDevice() {
200
214
  return __awaiter(this, void 0, void 0, function* () {
201
215
  const adbConnectCmd = `adb connect ${this.sn}`;
202
- ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${adbConnectCmd}`);
216
+ shared_utils_1.ColorConsole.log(`### Emulator ### Excuting adb cmd: ${adbConnectCmd}`);
203
217
  let pending = true;
204
218
  const p1 = adbMiwt.execAdbCmdAsync(adbConnectCmd);
205
219
  let timer;
@@ -209,7 +223,7 @@ class CommonInstance {
209
223
  timer = setTimeout(() => __awaiter(this, void 0, void 0, function* () {
210
224
  if (pending) {
211
225
  const adbKillCmd = `adb kill-server`;
212
- ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${adbKillCmd}`);
226
+ shared_utils_1.ColorConsole.log(`### Emulator ### Excuting adb cmd: ${adbKillCmd}`);
213
227
  yield adbMiwt.execAdbCmdAsync(adbKillCmd);
214
228
  }
215
229
  resolve();
@@ -1,7 +1,8 @@
1
1
  import { INewGoldfishInstanceParams, IStartOptions } from '../typing/Instance';
2
2
  import CommonInstance from './common';
3
3
  declare class GoldfishInstance extends CommonInstance {
4
- private appRunDir;
4
+ appRunDir: string;
5
+ emulatorStartedFlag: string;
5
6
  constructor(params: INewGoldfishInstanceParams);
6
7
  /**
7
8
  * 1. 启动模拟器
@@ -31,5 +32,14 @@ declare class GoldfishInstance extends CommonInstance {
31
32
  * @param sourceRoot
32
33
  */
33
34
  pushRpk(sourceRoot: string): Promise<void>;
35
+ /**
36
+ * 重新推送,然后重启应用
37
+ */
38
+ pushAndReloadApp(): Promise<void>;
39
+ /**
40
+ * 重启应用
41
+ */
42
+ reloadApp(): Promise<void>;
43
+ reboot(): Promise<boolean>;
34
44
  }
35
45
  export default GoldfishInstance;
@@ -35,19 +35,19 @@ 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 ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
38
+ const shared_utils_1 = require("@aiot-toolkit/shared-utils");
39
39
  const adbMiwt = __importStar(require("@miwt/adb"));
40
40
  const child_process_1 = require("child_process");
41
- const path_1 = require("path");
42
- const constants_1 = require("../static/constants");
43
- const common_1 = __importDefault(require("./common"));
44
- const os_1 = __importDefault(require("os"));
45
- const fs_1 = __importDefault(require("fs"));
46
41
  const dayjs_1 = __importDefault(require("dayjs"));
42
+ const fs_1 = __importDefault(require("fs"));
43
+ const os_1 = __importDefault(require("os"));
44
+ const path_1 = __importDefault(require("path"));
45
+ const common_1 = __importDefault(require("./common"));
47
46
  class GoldfishInstance extends common_1.default {
48
47
  constructor(params) {
49
48
  super(params);
50
49
  this.appRunDir = '/data/app';
50
+ this.emulatorStartedFlag = '(NSH)';
51
51
  }
52
52
  /**
53
53
  * 1. 启动模拟器
@@ -57,12 +57,12 @@ class GoldfishInstance extends common_1.default {
57
57
  start(options) {
58
58
  return __awaiter(this, void 0, void 0, function* () {
59
59
  this.startOptions = options;
60
- this.sn = `127.0.0.1:${this.startOptions.adbPort}`;
60
+ this.sn = `emulator-${this.startOptions.adbPort}`;
61
61
  // 启动模拟器
62
62
  yield this.startGoldfish(options);
63
- const connected = yield this.connectGoldfish(120);
63
+ const connected = yield this.isConnected();
64
64
  if (connected) {
65
- ColorConsole_1.default.log('### Emulator ### Goldfish emulator connected successfully');
65
+ shared_utils_1.ColorConsole.log('### Emulator ### Goldfish emulator connected successfully');
66
66
  if (this.isFirstStart && this.startOptions.serverPort) {
67
67
  yield this.createWebsockeServer();
68
68
  }
@@ -72,8 +72,8 @@ class GoldfishInstance extends common_1.default {
72
72
  ? this.projectPath
73
73
  : this.isDistributedApp
74
74
  ? options.dist ||
75
- path_1.posix.resolve(this.projectPath, './build', `${this.projectInfo.package}.watch`)
76
- : path_1.posix.resolve(this.projectPath, './build');
75
+ path_1.default.join(this.projectPath, './build', `${this.projectInfo.package}.watch`)
76
+ : path_1.default.join(this.projectPath, './build');
77
77
  yield this.pushRpk(buildedFilesPath);
78
78
  // 在模拟器中启动快应用
79
79
  this.startupQuickApp(options);
@@ -81,7 +81,7 @@ class GoldfishInstance extends common_1.default {
81
81
  }
82
82
  else {
83
83
  const msg = '### Emulator ### Failed to connect emulator, please check whether the adb is normal';
84
- ColorConsole_1.default.throw(msg);
84
+ shared_utils_1.ColorConsole.throw(msg);
85
85
  throw new Error(msg);
86
86
  }
87
87
  });
@@ -95,16 +95,16 @@ class GoldfishInstance extends common_1.default {
95
95
  return __awaiter(this, void 0, void 0, function* () {
96
96
  try {
97
97
  const { package: packageName } = this.projectInfo;
98
- let vappCmd = `adb -s 127.0.0.1:${options.adbPort} shell vapp app/${packageName} &`;
98
+ let vappCmd = `adb -s ${this.sn} shell vapp app/${packageName} &`;
99
99
  if (options.devtool) {
100
- vappCmd = `adb -s 127.0.0.1:${options.adbPort} shell vapp --jsdebugger=10.0.2.15:101 app/${packageName} &`;
100
+ vappCmd = `adb -s ${this.sn} shell vapp --jsdebugger=10.0.2.15:101 app/${packageName} &`;
101
101
  }
102
- ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${vappCmd}`);
102
+ shared_utils_1.ColorConsole.log(`### Emulator ### Excuting adb cmd: ${vappCmd}`);
103
103
  // vapp进程会一直pending,不会退出。这里必须加stdio: 'ignore',否则快应用无法运行成功
104
104
  adbMiwt.execAdbCmdAsync(vappCmd, { stdio: 'ignore', encoding: 'utf-8' });
105
105
  }
106
106
  catch (e) {
107
- ColorConsole_1.default.error(`### Emulator ### Failed to startup quickapp: ${e.message}`);
107
+ shared_utils_1.ColorConsole.error(`### Emulator ### Failed to startup quickapp: ${e.message}`);
108
108
  }
109
109
  });
110
110
  }
@@ -123,25 +123,25 @@ class GoldfishInstance extends common_1.default {
123
123
  return __awaiter(this, void 0, void 0, function* () {
124
124
  const { avdName, devtool, origin = 'terminal' } = options;
125
125
  const emulatorBin = this.getEmulatorBinPath();
126
- ColorConsole_1.default.log(`### Emulator ### emulator path: ${emulatorBin}`);
126
+ shared_utils_1.ColorConsole.log(`### Emulator ### emulator path: ${emulatorBin}`);
127
127
  const avdInfo = this.velaAvdCls.getVelaAvdInfo(avdName);
128
- const { avdArch, avdImagePath } = avdInfo;
129
- ColorConsole_1.default.log(`### Emulator ### adb port: ${options.adbPort}`);
128
+ const { avdArch, avdImagePath, customImagePath } = avdInfo;
129
+ shared_utils_1.ColorConsole.log(`### Emulator ### adb port: ${options.adbPort}`);
130
130
  if (!avdImagePath) {
131
- return ColorConsole_1.default.throw(`### Emulator ### Unable to find vela image via avd`);
131
+ return shared_utils_1.ColorConsole.throw(`### Emulator ### Unable to find vela image via avd`);
132
132
  }
133
- const nuttxBinPath = path_1.posix.resolve(avdImagePath, 'nuttx');
134
- ColorConsole_1.default.log(`### Emulator ### nuttx path: ${nuttxBinPath}`);
133
+ const nuttxBinPath = path_1.default.resolve(customImagePath || avdImagePath, 'nuttx');
134
+ shared_utils_1.ColorConsole.log(`### Emulator ### nuttx path: ${nuttxBinPath}`);
135
135
  // 端口映射
136
- let portMappingStr = `-network-user-mode-options hostfwd=tcp:127.0.0.1:${options.adbPort}-10.0.2.15:5555`;
136
+ let portMappingStr = ``;
137
137
  if (devtool) {
138
- portMappingStr += `,hostfwd=tcp:127.0.0.1:${options.debugPort}-10.0.2.15:101`;
138
+ portMappingStr += `-network-user-mode-options hostfwd=tcp:127.0.0.1:${options.debugPort}-10.0.2.15:101`;
139
139
  }
140
140
  // 文件系统配置,第一次使用fatfs镜像挂载,后续使用adb push更新应用
141
- const systemImageBin = path_1.posix.resolve(avdImagePath, 'system.img');
142
- const dataImageBin = path_1.posix.resolve(avdImagePath, 'data.img');
141
+ const systemImageBin = path_1.default.join(avdImagePath, 'system.img');
142
+ const dataImageBin = path_1.default.join(avdImagePath, 'data.img');
143
143
  // 复制可写文件到AVD目录下(多模拟器实例时需要)
144
- const dataImageBinInAvd = path_1.posix.join(this.avdHome, `${avdName}.avd`, 'data.img');
144
+ const dataImageBinInAvd = path_1.default.join(this.avdHome, `${avdName}.avd`, 'data.img');
145
145
  if (!fs_1.default.existsSync(dataImageBinInAvd)) {
146
146
  // data.img不存在时直接copy
147
147
  fs_1.default.copyFileSync(dataImageBin, dataImageBinInAvd);
@@ -155,7 +155,7 @@ class GoldfishInstance extends common_1.default {
155
155
  }
156
156
  }
157
157
  // 复制可写文件到AVD目录下(多模拟器实例时需要)
158
- const systemImageBinInAvd = path_1.posix.join(this.avdHome, `${avdName}.avd`, 'system.img');
158
+ const systemImageBinInAvd = path_1.default.join(this.avdHome, `${avdName}.avd`, 'system.img');
159
159
  if (!fs_1.default.existsSync(systemImageBinInAvd)) {
160
160
  // data.img不存在时直接copy
161
161
  fs_1.default.copyFileSync(systemImageBin, systemImageBinInAvd);
@@ -186,19 +186,18 @@ class GoldfishInstance extends common_1.default {
186
186
  -drive index=1,id=userdata,if=none,format=raw,file=${dataImageBinInAvd} \
187
187
  -device virtio-blk-device,bus=virtio-mmio-bus.1,drive=userdata \
188
188
  -device virtio-snd,bus=virtio-mmio-bus.2 -allow-host-audio -semihosting`;
189
- // vnc配置
189
+ // grpc配置
190
190
  let windowStr = '';
191
- let vncStr = '';
192
- if ((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.vncPort) {
193
- windowStr = '-no-window';
194
- const portSuffix = this.startOptions.vncPort - constants_1.defaultVncPort;
195
- vncStr = `-vnc :${portSuffix}`;
191
+ let grpcStr = '';
192
+ if ((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.grpcPort) {
193
+ windowStr = '-qt-hide-window';
194
+ grpcStr = ` -idle-grpc-timeout 300 -grpc ${this.startOptions.grpcPort}`;
196
195
  }
197
- // 启动goldfish的命令和参数
198
- const cmd = `${emulatorBin} -nuttx -avd ${avdName} -avd-arch ${avdArch} -show-kernel -kernel ${nuttxBinPath} ${portMappingStr} ${windowStr} -qemu ${vncStr} ${imageMountStr}`;
196
+ // 启动模拟器的命令和参数
197
+ const cmd = `${emulatorBin} -nuttx -avd ${avdName} -port ${options.adbPort} -avd-arch ${avdArch} -show-kernel -kernel ${nuttxBinPath} ${portMappingStr} ${windowStr} ${grpcStr} -qemu ${imageMountStr}`;
199
198
  const spawnArgs = cmd.split(' ');
200
199
  const spawnBin = spawnArgs.shift();
201
- ColorConsole_1.default.log(`### Emulator ### Start CMD: ${cmd}`);
200
+ shared_utils_1.ColorConsole.log(`### Emulator ### Start CMD: ${cmd}`);
202
201
  return new Promise((resolve) => {
203
202
  var _a, _b, _c;
204
203
  this.goldfishProcess = (0, child_process_1.spawn)(spawnBin, spawnArgs, { stdio: 'pipe', shell: true });
@@ -211,7 +210,7 @@ class GoldfishInstance extends common_1.default {
211
210
  (_b = this.goldfishProcess.stdout) === null || _b === void 0 ? void 0 : _b.pipe(process.stdout);
212
211
  }
213
212
  this.goldfishProcess.on('exit', (code) => {
214
- ColorConsole_1.default.error(`### Emulator ### Goldfish emulator exited with code ${code}`);
213
+ shared_utils_1.ColorConsole.error(`### Emulator ### Goldfish emulator exited with code ${code}`);
215
214
  if (options.exitCallback) {
216
215
  options.exitCallback(code);
217
216
  }
@@ -222,8 +221,8 @@ class GoldfishInstance extends common_1.default {
222
221
  const stdoutCb = options.stdoutCallback || console.log;
223
222
  stdoutCb(msg);
224
223
  }
225
- if (msg.includes('(NSH)')) {
226
- ColorConsole_1.default.log(`### Emulator ### Goldfish emulator starts successfully`);
224
+ if (msg.includes(this.emulatorStartedFlag)) {
225
+ shared_utils_1.ColorConsole.log(`### Emulator ### Goldfish emulator starts successfully`);
227
226
  resolve();
228
227
  }
229
228
  });
@@ -236,10 +235,10 @@ class GoldfishInstance extends common_1.default {
236
235
  */
237
236
  pushRpk(sourceRoot) {
238
237
  return __awaiter(this, void 0, void 0, function* () {
239
- const sn = `127.0.0.1:${this.startOptions.adbPort}`;
238
+ const sn = this.sn;
240
239
  const { package: appPackageName } = this.projectInfo;
241
240
  // 获取最后一层目录,比如build
242
- const basename = path_1.posix.basename(sourceRoot);
241
+ const basename = path_1.default.basename(sourceRoot);
243
242
  if (os_1.default.platform() === 'win32' || this.projectPath.indexOf(' ') > 0) {
244
243
  // windows系统或者项目路径有空格:1. adb push目录;2. 在模拟器中使用mv命令重命名
245
244
  yield adbMiwt.execAdbCmdAsync(`adb -s ${sn} push ${sourceRoot} ${this.appRunDir}`);
@@ -247,11 +246,57 @@ class GoldfishInstance extends common_1.default {
247
246
  }
248
247
  else {
249
248
  // 支持通配符处理: 1. 模拟器中mkdir创建目录 2. adb push ./XXXXX/* /XXX
250
- const sourcePath = path_1.posix.resolve(sourceRoot, './*');
251
- yield adbMiwt.execAdbCmdAsync(`adb -s ${sn} shell mkdir ${this.appRunDir}/${appPackageName}`);
252
- yield adbMiwt.execAdbCmdAsync(`adb -s ${sn} push ${sourcePath} ${this.appRunDir}/${appPackageName}`);
249
+ const sourcePath = path_1.default.join(sourceRoot, './*');
250
+ const mkdirCmd = `adb -s ${sn} shell mkdir ${this.appRunDir}/${appPackageName}`;
251
+ shared_utils_1.ColorConsole.log(`### Emulator ### mkdir CMD: ${mkdirCmd}`);
252
+ yield adbMiwt.execAdbCmdAsync(mkdirCmd);
253
+ const pushCmd = `adb -s ${sn} push ${sourcePath} ${this.appRunDir}/${appPackageName}`;
254
+ shared_utils_1.ColorConsole.log(`### Emulator ### pushCmd CMD: ${pushCmd}`);
255
+ yield adbMiwt.execAdbCmdAsync(pushCmd);
253
256
  }
254
- ColorConsole_1.default.info(`### Emulator push to ${this.appRunDir}/${appPackageName} successfully`);
257
+ shared_utils_1.ColorConsole.info(`### Emulator push to ${this.appRunDir}/${appPackageName} successfully`);
258
+ });
259
+ }
260
+ /**
261
+ * 重新推送,然后重启应用
262
+ */
263
+ pushAndReloadApp() {
264
+ var _a;
265
+ return __awaiter(this, void 0, void 0, function* () {
266
+ try {
267
+ // 1. 将整包重新推到miwear中(TODO:增量更新)
268
+ // adb push快应用到模拟器的/data/app目录
269
+ // aspect应用后续要考虑各种形状表盘的推包
270
+ const buildedFilesPath = this.isRpk
271
+ ? this.projectPath
272
+ : this.isDistributedApp
273
+ ? ((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.dist) ||
274
+ path_1.default.join(this.projectPath, './build', `${this.projectInfo.package}.watch`)
275
+ : path_1.default.join(this.projectPath, './build');
276
+ yield this.pushRpk(buildedFilesPath);
277
+ this.reloadApp();
278
+ }
279
+ catch (e) {
280
+ shared_utils_1.ColorConsole.error(`${e}`);
281
+ }
282
+ });
283
+ }
284
+ /**
285
+ * 重启应用
286
+ */
287
+ reloadApp() {
288
+ return __awaiter(this, void 0, void 0, function* () {
289
+ const { package: appPackageName } = this.projectInfo;
290
+ this.startupQuickApp(this.startOptions);
291
+ shared_utils_1.ColorConsole.info(`### Emulator start ${appPackageName} successfully`);
292
+ });
293
+ }
294
+ reboot() {
295
+ return __awaiter(this, void 0, void 0, function* () {
296
+ const rebootCmd = `adb -s ${this.sn} shell reboot`;
297
+ shared_utils_1.ColorConsole.log(`### Emulator ### Excuting adb cmd: ${rebootCmd}`);
298
+ yield adbMiwt.execAdbCmdAsync(rebootCmd);
299
+ return this.isConnected();
255
300
  });
256
301
  }
257
302
  }
@@ -1,13 +1,15 @@
1
1
  import { INewGoldfishInstanceParams } from '../typing/Instance';
2
2
  import CommonInstance from './common';
3
3
  import GoldfishInstance from './dev';
4
- import MiwearInstance from "./miwear";
4
+ import MiwearInstance from './miwear';
5
5
  import OldGoldfishInstance from './preDev';
6
+ import PreInstance from './pre';
6
7
  /**
7
8
  * 根据镜像决定使用哪个instance
8
9
  * Vela正式版(4.0) -> MiwearInstance
10
+ * Vela正式版(不带 miwear 版本) -> PreInstance
9
11
  * Vela开发版(dev, 0.0.2) -> OldGoldfishInstance
10
12
  * Vela开发版(dev),除0.0.2的其他版本 -> GoldfishInstance
11
13
  */
12
14
  declare function findInstance(avdName: string, params: INewGoldfishInstanceParams): GoldfishInstance | MiwearInstance | OldGoldfishInstance | undefined;
13
- export { CommonInstance, GoldfishInstance, MiwearInstance, OldGoldfishInstance, findInstance };
15
+ export { CommonInstance, GoldfishInstance, MiwearInstance, OldGoldfishInstance, PreInstance, findInstance };
@@ -3,8 +3,8 @@ 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.findInstance = exports.OldGoldfishInstance = exports.MiwearInstance = exports.GoldfishInstance = exports.CommonInstance = void 0;
7
- const ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
6
+ exports.findInstance = exports.PreInstance = exports.OldGoldfishInstance = exports.MiwearInstance = exports.GoldfishInstance = exports.CommonInstance = void 0;
7
+ const shared_utils_1 = require("@aiot-toolkit/shared-utils");
8
8
  const avd_1 = __importDefault(require("../avd"));
9
9
  const common_1 = __importDefault(require("./common"));
10
10
  exports.CommonInstance = common_1.default;
@@ -14,9 +14,12 @@ const miwear_1 = __importDefault(require("./miwear"));
14
14
  exports.MiwearInstance = miwear_1.default;
15
15
  const preDev_1 = __importDefault(require("./preDev"));
16
16
  exports.OldGoldfishInstance = preDev_1.default;
17
+ const pre_1 = __importDefault(require("./pre"));
18
+ exports.PreInstance = pre_1.default;
17
19
  /**
18
20
  * 根据镜像决定使用哪个instance
19
21
  * Vela正式版(4.0) -> MiwearInstance
22
+ * Vela正式版(不带 miwear 版本) -> PreInstance
20
23
  * Vela开发版(dev, 0.0.2) -> OldGoldfishInstance
21
24
  * Vela开发版(dev),除0.0.2的其他版本 -> GoldfishInstance
22
25
  */
@@ -24,9 +27,12 @@ function findInstance(avdName, params) {
24
27
  const { sdkHome, avdHome } = params;
25
28
  const { avdImagePath } = new avd_1.default({ sdkHome, avdHome }).getVelaAvdInfo(avdName);
26
29
  if (!avdImagePath) {
27
- ColorConsole_1.default.throw(`### Emulator ### Unable to find vela image via avd`);
30
+ shared_utils_1.ColorConsole.throw(`### Emulator ### Unable to find vela image via avd`);
28
31
  return;
29
32
  }
33
+ if (avdImagePath.includes('vela-pre-4.0')) {
34
+ return new pre_1.default(params);
35
+ }
30
36
  if (avdImagePath.includes('release')) {
31
37
  return new miwear_1.default(params);
32
38
  }
@@ -6,9 +6,11 @@ import CommonInstance from './common';
6
6
  */
7
7
  declare class MiwearInstance extends CommonInstance {
8
8
  private params;
9
+ quickappStartedFlag: RegExp;
9
10
  private appPathInEmulator;
10
11
  private debugSocket?;
11
12
  private reconnectCount;
13
+ emulatorStartedFlag: RegExp;
12
14
  constructor(params: INewGoldfishInstanceParams);
13
15
  /**
14
16
  * 1. 启动模拟器
@@ -65,6 +67,7 @@ declare class MiwearInstance extends CommonInstance {
65
67
  * 2. nsh中执行am stop命令退出快应用
66
68
  * 3. nsh中执行am start命令启动快应用
67
69
  */
70
+ pushAndReloadApp(): Promise<void>;
68
71
  reloadApp(): Promise<void>;
69
72
  /**
70
73
  * 创建server端,监听打包过程中client端发来的消息