@aiot-toolkit/emulator 2.0.2-dev.3 → 2.0.2-dev.5
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/index.d.ts +2 -2
- package/lib/index.js +2 -3
- package/lib/instance/{goldfish.d.ts → common.d.ts} +17 -15
- package/lib/instance/{goldfish1.js → common.js} +34 -72
- package/lib/instance/dev.d.ts +15 -0
- package/lib/instance/dev.js +184 -0
- package/lib/instance/index.d.ts +7 -0
- package/lib/instance/index.js +32 -0
- package/lib/instance/miwear.d.ts +27 -0
- package/lib/instance/miwear.js +308 -0
- package/lib/instance/{goldfish1.d.ts → preDev.d.ts} +5 -23
- package/lib/instance/{goldfish.js → preDev.js} +36 -108
- package/lib/static/debugger_ip.cfg +1 -0
- package/lib/typing/Instance.d.ts +4 -0
- package/lib/utils/index.d.ts +7 -0
- package/lib/utils/index.js +49 -1
- package/package.json +4 -4
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { default as VelaAvdCls } from './avd';
|
|
2
|
-
|
|
2
|
+
export * from './instance';
|
|
3
3
|
export * from './typing/Avd';
|
|
4
4
|
export * from './typing/Instance';
|
|
5
|
-
export {
|
|
5
|
+
export { VelaAvdCls };
|
package/lib/index.js
CHANGED
|
@@ -17,10 +17,9 @@ 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 =
|
|
20
|
+
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
|
-
|
|
24
|
-
Object.defineProperty(exports, "GoldfishInstance", { enumerable: true, get: function () { return goldfish_1.default; } });
|
|
23
|
+
__exportStar(require("./instance"), exports);
|
|
25
24
|
__exportStar(require("./typing/Avd"), exports);
|
|
26
25
|
__exportStar(require("./typing/Instance"), exports);
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
import IManifest from '@aiot-toolkit/aiotpack/lib/compiler/javascript/vela/interface/IManifest';
|
|
2
3
|
import { ChildProcess } from 'child_process';
|
|
4
|
+
import VelaAvdCls from '../avd';
|
|
3
5
|
import { INewGoldfishInstanceParams, IStartOptions } from '../typing/Instance';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
/**
|
|
7
|
+
* CommonInstance
|
|
8
|
+
*/
|
|
9
|
+
declare class CommonInstance {
|
|
10
|
+
projectPath: string;
|
|
11
|
+
sdkHome: string;
|
|
12
|
+
avdHome: string;
|
|
13
|
+
adbPort: number;
|
|
9
14
|
debugPort: number;
|
|
10
|
-
|
|
11
|
-
private velaAvdCls;
|
|
12
|
-
private packageName;
|
|
15
|
+
velaAvdCls: VelaAvdCls;
|
|
13
16
|
goldfishProcess: ChildProcess | undefined;
|
|
14
|
-
v9fsProcess: ChildProcess | undefined;
|
|
15
17
|
isFirstStart: boolean;
|
|
16
|
-
|
|
18
|
+
startOptions: IStartOptions | undefined;
|
|
19
|
+
projectInfo: IManifest;
|
|
20
|
+
isRpk: boolean;
|
|
17
21
|
constructor(params: INewGoldfishInstanceParams);
|
|
18
22
|
/** 获取模拟器二进制文件所在位置 */
|
|
19
23
|
getEmulatorBinPath(): string;
|
|
@@ -21,21 +25,19 @@ declare class GoldfishInstance {
|
|
|
21
25
|
start(options: IStartOptions): Promise<void>;
|
|
22
26
|
/** 在goldfish中启动快应用 */
|
|
23
27
|
startupQuickApp(options: IStartOptions): void;
|
|
24
|
-
/** host启动9pServer */
|
|
25
|
-
ensure9pServerRunnning(): Promise<void>;
|
|
26
28
|
/** 启动goldfish模拟器 */
|
|
27
29
|
startGoldfish(options: IStartOptions): Promise<void>;
|
|
28
30
|
/** 通过adb连接模拟器 */
|
|
29
31
|
connectGoldfish(): Promise<boolean>;
|
|
30
32
|
/** 将打包后的文件推到挂载的快应用目录 */
|
|
31
|
-
pushRpk(): void
|
|
33
|
+
pushRpk(sourceRoot: string): Promise<void>;
|
|
32
34
|
/** 杀死进程 */
|
|
33
35
|
killProcess(currProcess?: ChildProcess): void;
|
|
34
36
|
/** 停止模拟器并释放相关资源 */
|
|
35
|
-
stop(): void
|
|
37
|
+
stop(): Promise<void>;
|
|
36
38
|
/** 重启模拟器 */
|
|
37
39
|
restart(): void;
|
|
38
40
|
/** 创建server */
|
|
39
41
|
createWebsockeServer(): Promise<void>;
|
|
40
42
|
}
|
|
41
|
-
export default
|
|
43
|
+
export default CommonInstance;
|
|
@@ -39,8 +39,6 @@ const UxFileUtils_1 = __importDefault(require("@aiot-toolkit/aiotpack/lib/utils/
|
|
|
39
39
|
const ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
|
|
40
40
|
const adbMiwt = __importStar(require("@miwt/adb"));
|
|
41
41
|
const child_process_1 = require("child_process");
|
|
42
|
-
const find_process_1 = __importDefault(require("find-process"));
|
|
43
|
-
const fs_1 = __importDefault(require("fs"));
|
|
44
42
|
const os_1 = __importDefault(require("os"));
|
|
45
43
|
const path_1 = __importDefault(require("path"));
|
|
46
44
|
const portfinder_1 = __importDefault(require("portfinder"));
|
|
@@ -48,21 +46,23 @@ const ws_1 = require("ws");
|
|
|
48
46
|
const avd_1 = __importDefault(require("../avd"));
|
|
49
47
|
const constants_1 = require("../static/constants");
|
|
50
48
|
const utils_1 = require("../utils");
|
|
51
|
-
|
|
49
|
+
/**
|
|
50
|
+
* CommonInstance
|
|
51
|
+
*/
|
|
52
|
+
class CommonInstance {
|
|
52
53
|
constructor(params) {
|
|
53
54
|
this.adbPort = 5555;
|
|
54
55
|
this.debugPort = 10055;
|
|
55
|
-
this.host9pPort = 7878;
|
|
56
56
|
this.isFirstStart = true;
|
|
57
57
|
this.projectPath = params.projectPath;
|
|
58
58
|
this.sdkHome = params.sdkHome || constants_1.defaultSDKHome;
|
|
59
59
|
this.avdHome = params.avdHome || constants_1.defaultAvdHome;
|
|
60
|
+
this.isRpk = params.sourceRoot === './';
|
|
60
61
|
this.velaAvdCls = new avd_1.default({
|
|
61
62
|
sdkHome: this.sdkHome,
|
|
62
63
|
avdHome: this.avdHome
|
|
63
64
|
});
|
|
64
|
-
|
|
65
|
-
this.packageName = appPackageName;
|
|
65
|
+
this.projectInfo = UxFileUtils_1.default.getMainfestInfo(this.projectPath, params.sourceRoot);
|
|
66
66
|
}
|
|
67
67
|
/** 获取模拟器二进制文件所在位置 */
|
|
68
68
|
getEmulatorBinPath() {
|
|
@@ -85,7 +85,8 @@ class GoldfishInstance {
|
|
|
85
85
|
yield this.createWebsockeServer();
|
|
86
86
|
}
|
|
87
87
|
// adb push快应用到模拟器的/data/app目录
|
|
88
|
-
this.
|
|
88
|
+
const buildedFilesPath = this.isRpk ? this.projectPath : path_1.default.resolve(this.projectPath, './build');
|
|
89
|
+
this.pushRpk(buildedFilesPath);
|
|
89
90
|
// 在模拟器中启动快应用
|
|
90
91
|
this.startupQuickApp(options);
|
|
91
92
|
this.isFirstStart = false;
|
|
@@ -98,9 +99,9 @@ class GoldfishInstance {
|
|
|
98
99
|
/** 在goldfish中启动快应用 */
|
|
99
100
|
startupQuickApp(options) {
|
|
100
101
|
try {
|
|
101
|
-
let vappCmd = `adb -s 127.0.0.1:${this.adbPort} shell vapp app/${this.
|
|
102
|
+
let vappCmd = `adb -s 127.0.0.1:${this.adbPort} shell vapp app/${this.projectInfo.package} &`;
|
|
102
103
|
if (options.devtool) {
|
|
103
|
-
vappCmd = `adb -s 127.0.0.1:${this.adbPort} shell vapp --jsdebugger=10.0.2.15:101 app/${this.
|
|
104
|
+
vappCmd = `adb -s 127.0.0.1:${this.adbPort} shell vapp --jsdebugger=10.0.2.15:101 app/${this.projectInfo.package} &`;
|
|
104
105
|
}
|
|
105
106
|
ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${vappCmd}`);
|
|
106
107
|
// vapp进程会一直pending,不会退出。这里必须加stdio: 'ignore',否则快应用无法运行成功
|
|
@@ -110,44 +111,6 @@ class GoldfishInstance {
|
|
|
110
111
|
ColorConsole_1.default.error(`### Emulator ### Failed to startup quickapp: ${e.message}`);
|
|
111
112
|
}
|
|
112
113
|
}
|
|
113
|
-
/** host启动9pServer */
|
|
114
|
-
ensure9pServerRunnning() {
|
|
115
|
-
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
116
|
-
var _a;
|
|
117
|
-
const yaFileName = os_1.default.platform() === 'win32' ? 'ya-vm-file-server.exe' : 'ya-vm-file-server';
|
|
118
|
-
const pidList = yield (0, find_process_1.default)('name', yaFileName);
|
|
119
|
-
if (pidList.length > 0) {
|
|
120
|
-
ColorConsole_1.default.log('### Emulator ### 9p server started in host');
|
|
121
|
-
return resolve();
|
|
122
|
-
}
|
|
123
|
-
ColorConsole_1.default.log('### Emulator ### Starting 9p server in host');
|
|
124
|
-
const quickappMountDir = path_1.default.resolve(this.sdkHome, 'qa');
|
|
125
|
-
const toolsHome = path_1.default.resolve(this.sdkHome, 'tools');
|
|
126
|
-
const serverBinPath = path_1.default.resolve(toolsHome, yaFileName);
|
|
127
|
-
fs_1.default.chmodSync(serverBinPath, 0o777);
|
|
128
|
-
this.host9pPort = yield portfinder_1.default.getPortPromise({ port: 7878 });
|
|
129
|
-
const address = `127.0.0.1:${this.host9pPort}`;
|
|
130
|
-
this.v9fsProcess = (0, child_process_1.spawn)(serverBinPath, [
|
|
131
|
-
'--mount-point',
|
|
132
|
-
quickappMountDir,
|
|
133
|
-
'--network-address',
|
|
134
|
-
address,
|
|
135
|
-
'--debug'
|
|
136
|
-
]);
|
|
137
|
-
(_a = this.v9fsProcess.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
138
|
-
const output = data.toString();
|
|
139
|
-
if (output.match(/Server started, listening on: 127.0.0.1:(\d+)/)) {
|
|
140
|
-
ColorConsole_1.default.log(output);
|
|
141
|
-
ColorConsole_1.default.log('### Emulator ### 9p server starts successfully');
|
|
142
|
-
return resolve();
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
this.v9fsProcess.on('exit', (code) => {
|
|
146
|
-
ColorConsole_1.default.error(`### Emulator ### ya-vm-file-server exited with code ${code}`);
|
|
147
|
-
return reject();
|
|
148
|
-
});
|
|
149
|
-
}));
|
|
150
|
-
}
|
|
151
114
|
/** 启动goldfish模拟器 */
|
|
152
115
|
startGoldfish(options) {
|
|
153
116
|
var _a;
|
|
@@ -250,14 +213,16 @@ class GoldfishInstance {
|
|
|
250
213
|
});
|
|
251
214
|
}
|
|
252
215
|
/** 将打包后的文件推到挂载的快应用目录 */
|
|
253
|
-
pushRpk() {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
216
|
+
pushRpk(sourceRoot) {
|
|
217
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
218
|
+
const sn = `127.0.0.1:${this.adbPort}`;
|
|
219
|
+
const { package: appPackageName } = UxFileUtils_1.default.getMainfestInfo(this.projectPath);
|
|
220
|
+
const appRunDir = '/data/app';
|
|
221
|
+
ColorConsole_1.default.log(`### Emulator ### Pushing ${appPackageName} to ${appRunDir}`);
|
|
222
|
+
(0, child_process_1.execSync)(`adb -s ${sn} shell mkdir ${appRunDir}/${appPackageName}`, { stdio: 'ignore' });
|
|
223
|
+
yield adbMiwt.execAdbCmdAsync(`adb -s ${sn} push ${sourceRoot}/* ${appRunDir}/${appPackageName}`);
|
|
224
|
+
ColorConsole_1.default.log(`### Emulator ### Push ${appPackageName} to ${appRunDir} successfully`);
|
|
225
|
+
});
|
|
261
226
|
}
|
|
262
227
|
/** 杀死进程 */
|
|
263
228
|
killProcess(currProcess) {
|
|
@@ -281,26 +246,23 @@ class GoldfishInstance {
|
|
|
281
246
|
}
|
|
282
247
|
/** 停止模拟器并释放相关资源 */
|
|
283
248
|
stop() {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
249
|
+
var _a;
|
|
250
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
251
|
+
if (this.goldfishProcess) {
|
|
252
|
+
// Linux删除goldfishProcess后,子进程仍存在,导致模拟器窗口未关闭
|
|
253
|
+
// 这里的作用是手动删除创建出来的子进程
|
|
254
|
+
// if (os.platform() === 'linux' && this.goldfishProcess.pid) {
|
|
255
|
+
// process.kill(this.goldfishProcess.pid + 1)
|
|
256
|
+
// }
|
|
257
|
+
this.killProcess(this.goldfishProcess);
|
|
258
|
+
yield (0, utils_1.killProcessByCmd)((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.avdName);
|
|
259
|
+
this.goldfishProcess = undefined;
|
|
289
260
|
}
|
|
290
|
-
|
|
291
|
-
this.goldfishProcess = undefined;
|
|
292
|
-
}
|
|
293
|
-
if (this.v9fsProcess) {
|
|
294
|
-
this.killProcess(this.v9fsProcess);
|
|
295
|
-
this.v9fsProcess = undefined;
|
|
296
|
-
}
|
|
261
|
+
});
|
|
297
262
|
}
|
|
298
263
|
/** 重启模拟器 */
|
|
299
264
|
restart() {
|
|
300
|
-
|
|
301
|
-
this.killProcess(this.goldfishProcess);
|
|
302
|
-
this.goldfishProcess = undefined;
|
|
303
|
-
}
|
|
265
|
+
this.stop();
|
|
304
266
|
this.start(this.startOptions);
|
|
305
267
|
}
|
|
306
268
|
/** 创建server */
|
|
@@ -329,4 +291,4 @@ class GoldfishInstance {
|
|
|
329
291
|
});
|
|
330
292
|
}
|
|
331
293
|
}
|
|
332
|
-
exports.default =
|
|
294
|
+
exports.default = CommonInstance;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { INewGoldfishInstanceParams, IStartOptions } from '../typing/Instance';
|
|
2
|
+
import CommonInstance from './common';
|
|
3
|
+
declare class GoldfishInstance extends CommonInstance {
|
|
4
|
+
private appRunDir;
|
|
5
|
+
constructor(params: INewGoldfishInstanceParams);
|
|
6
|
+
/** 在goldfish模拟器中运行快应用 */
|
|
7
|
+
start(options: IStartOptions): Promise<void>;
|
|
8
|
+
/** 在goldfish中启动快应用 */
|
|
9
|
+
startupQuickApp(options: IStartOptions): Promise<void>;
|
|
10
|
+
/** 启动goldfish模拟器 */
|
|
11
|
+
startGoldfish(options: IStartOptions): Promise<void>;
|
|
12
|
+
/** 将打包后的文件推到挂载的快应用目录 */
|
|
13
|
+
pushRpk(sourceRoot: string): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
export default GoldfishInstance;
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
+
};
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
const ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
|
|
39
|
+
const adbMiwt = __importStar(require("@miwt/adb"));
|
|
40
|
+
const child_process_1 = require("child_process");
|
|
41
|
+
const path_1 = __importDefault(require("path"));
|
|
42
|
+
const portfinder_1 = __importDefault(require("portfinder"));
|
|
43
|
+
const constants_1 = require("../static/constants");
|
|
44
|
+
const common_1 = __importDefault(require("./common"));
|
|
45
|
+
class GoldfishInstance extends common_1.default {
|
|
46
|
+
constructor(params) {
|
|
47
|
+
super(params);
|
|
48
|
+
this.appRunDir = '/data/app';
|
|
49
|
+
}
|
|
50
|
+
/** 在goldfish模拟器中运行快应用 */
|
|
51
|
+
start(options) {
|
|
52
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
+
this.startOptions = options;
|
|
54
|
+
// 启动模拟器
|
|
55
|
+
yield this.startGoldfish(options);
|
|
56
|
+
const connected = yield this.connectGoldfish();
|
|
57
|
+
if (connected) {
|
|
58
|
+
ColorConsole_1.default.log('### Emulator ### Goldfish emulator connected successfully');
|
|
59
|
+
if (this.isFirstStart && this.startOptions.serverPort) {
|
|
60
|
+
yield this.createWebsockeServer();
|
|
61
|
+
}
|
|
62
|
+
// adb push快应用到模拟器的/data/app目录
|
|
63
|
+
const buildedFilesPath = this.isRpk ? this.projectPath : path_1.default.resolve(this.projectPath, './build');
|
|
64
|
+
yield this.pushRpk(buildedFilesPath);
|
|
65
|
+
// 在模拟器中启动快应用
|
|
66
|
+
this.startupQuickApp(options);
|
|
67
|
+
this.isFirstStart = false;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
ColorConsole_1.default.throw('### Emulator ### Failed to connect emulator, please check whether the adb is normal');
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/** 在goldfish中启动快应用 */
|
|
75
|
+
startupQuickApp(options) {
|
|
76
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
77
|
+
try {
|
|
78
|
+
const { package: packageName } = this.projectInfo;
|
|
79
|
+
let vappCmd = `adb -s 127.0.0.1:${this.adbPort} shell vapp app/${packageName} &`;
|
|
80
|
+
if (options.devtool) {
|
|
81
|
+
vappCmd = `adb -s 127.0.0.1:${this.adbPort} shell vapp --jsdebugger=10.0.2.15:101 app/${packageName} &`;
|
|
82
|
+
}
|
|
83
|
+
ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${vappCmd}`);
|
|
84
|
+
// vapp进程会一直pending,不会退出。这里必须加stdio: 'ignore',否则快应用无法运行成功
|
|
85
|
+
adbMiwt.execAdbCmdAsync(vappCmd, { stdio: 'ignore', encoding: 'utf-8' });
|
|
86
|
+
}
|
|
87
|
+
catch (e) {
|
|
88
|
+
ColorConsole_1.default.error(`### Emulator ### Failed to startup quickapp: ${e.message}`);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/** 启动goldfish模拟器 */
|
|
93
|
+
startGoldfish(options) {
|
|
94
|
+
var _a;
|
|
95
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
96
|
+
const { avdName, devtool } = options;
|
|
97
|
+
const emulatorBin = this.getEmulatorBinPath();
|
|
98
|
+
ColorConsole_1.default.log(`### Emulator ### emulator path: ${emulatorBin}`);
|
|
99
|
+
const avdInfo = this.velaAvdCls.getVelaAvdInfo(avdName);
|
|
100
|
+
const { avdArch, avdImagePath } = avdInfo;
|
|
101
|
+
this.adbPort = yield portfinder_1.default.getPortPromise({ port: this.adbPort });
|
|
102
|
+
ColorConsole_1.default.log(`### Emulator ### adb port: ${this.adbPort}`);
|
|
103
|
+
if (!avdImagePath) {
|
|
104
|
+
return ColorConsole_1.default.throw(`### Emulator ### Unable to find vela image via avd`);
|
|
105
|
+
}
|
|
106
|
+
const nuttxBinPath = path_1.default.resolve(avdImagePath, 'nuttx');
|
|
107
|
+
ColorConsole_1.default.log(`### Emulator ### nuttx path: ${nuttxBinPath}`);
|
|
108
|
+
// 端口映射
|
|
109
|
+
let portMappingStr = `-network-user-mode-options hostfwd=tcp:127.0.0.1:${this.adbPort}-10.0.2.15:5555`;
|
|
110
|
+
if (devtool) {
|
|
111
|
+
portMappingStr += `,hostfwd=tcp:127.0.0.1:${this.debugPort}-10.0.2.15:101`;
|
|
112
|
+
}
|
|
113
|
+
// 文件系统配置,第一次使用fatfs镜像挂载,后续使用adb push更新应用
|
|
114
|
+
const systemImageBin = path_1.default.resolve(this.sdkHome, 'tools/image/system.img');
|
|
115
|
+
const dataImageBin = path_1.default.resolve(this.sdkHome, 'tools/image/data.img');
|
|
116
|
+
const imageMountStr = `-drive index=0,id=system,if=none,format=raw,file=${systemImageBin} \
|
|
117
|
+
-device virtio-blk-device,bus=virtio-mmio-bus.0,drive=system \
|
|
118
|
+
-drive index=1,id=userdata,if=none,format=raw,file=${dataImageBin} \
|
|
119
|
+
-device virtio-blk-device,bus=virtio-mmio-bus.1,drive=userdata \
|
|
120
|
+
-device virtio-snd,bus=virtio-mmio-bus.2 -allow-host-audio -semihosting`;
|
|
121
|
+
// vnc配置
|
|
122
|
+
let windowStr = '';
|
|
123
|
+
let vncStr = '';
|
|
124
|
+
if ((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.vncPort) {
|
|
125
|
+
windowStr = '-no-window';
|
|
126
|
+
const portSuffix = this.startOptions.vncPort - constants_1.defaultVncPort;
|
|
127
|
+
vncStr = `-vnc :${portSuffix}`;
|
|
128
|
+
}
|
|
129
|
+
const stdioType = options.disableNSH ? 'pipe' : 'inherit';
|
|
130
|
+
// 启动goldfish的命令和参数
|
|
131
|
+
const cmd = `${emulatorBin} -nuttx -avd ${avdName} -avd-arch ${avdArch} -show-kernel -kernel ${nuttxBinPath} ${portMappingStr} ${windowStr} -qemu ${vncStr} ${imageMountStr}`;
|
|
132
|
+
const spawnArgs = cmd.split(' ');
|
|
133
|
+
const spawnBin = spawnArgs.shift();
|
|
134
|
+
ColorConsole_1.default.log(`### Emulator ### Start CMD: ${cmd}`);
|
|
135
|
+
return new Promise((resolve) => {
|
|
136
|
+
var _a, _b;
|
|
137
|
+
this.goldfishProcess = (0, child_process_1.spawn)(spawnBin, spawnArgs, { stdio: stdioType, shell: true });
|
|
138
|
+
if (options.disableNSH) {
|
|
139
|
+
(_a = this.goldfishProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
140
|
+
if (options.stdoutCallback) {
|
|
141
|
+
options.stdoutCallback(data);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
console.log(data.toString());
|
|
145
|
+
}
|
|
146
|
+
if (data.toString().includes('(NSH)')) {
|
|
147
|
+
ColorConsole_1.default.log(`### Emulator ### Goldfish emulator starts successfully`);
|
|
148
|
+
resolve();
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
(_b = this.goldfishProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
|
|
152
|
+
const stderrCb = options.stderrCallback || console.log;
|
|
153
|
+
stderrCb(data.toString());
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
setTimeout(() => {
|
|
158
|
+
ColorConsole_1.default.log(`### Emulator ### Goldfish emulator starts successfully`);
|
|
159
|
+
resolve();
|
|
160
|
+
}, 2000);
|
|
161
|
+
}
|
|
162
|
+
this.goldfishProcess.on('exit', (code) => {
|
|
163
|
+
ColorConsole_1.default.error(`### Emulator ### Goldfish emulator exited with code ${code}`);
|
|
164
|
+
if (options.exitCallback) {
|
|
165
|
+
options.exitCallback(code);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
/** 将打包后的文件推到挂载的快应用目录 */
|
|
172
|
+
pushRpk(sourceRoot) {
|
|
173
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
174
|
+
const sn = `127.0.0.1:${this.adbPort}`;
|
|
175
|
+
const { package: appPackageName } = this.projectInfo;
|
|
176
|
+
const sourcePath = path_1.default.resolve(sourceRoot, './*');
|
|
177
|
+
ColorConsole_1.default.log(`### Emulator ### Pushing ${appPackageName} to ${this.appRunDir}`);
|
|
178
|
+
yield adbMiwt.execAdbCmdAsync(`adb -s ${sn} shell mkdir ${this.appRunDir}/${appPackageName}`);
|
|
179
|
+
yield adbMiwt.execAdbCmdAsync(`adb -s ${sn} push ${sourcePath} ${this.appRunDir}/${appPackageName}`);
|
|
180
|
+
ColorConsole_1.default.log(`### Emulator ### Push ${appPackageName} to ${this.appRunDir} successfully`);
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
exports.default = GoldfishInstance;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { INewGoldfishInstanceParams } from '../typing/Instance';
|
|
2
|
+
import CommonInstance from './common';
|
|
3
|
+
import GoldfishInstance from './dev';
|
|
4
|
+
import MiwearInstance from "./miwear";
|
|
5
|
+
import OldGoldfishInstance from './preDev';
|
|
6
|
+
declare function findInstance(avdName: string, params: INewGoldfishInstanceParams): GoldfishInstance | MiwearInstance | OldGoldfishInstance | undefined;
|
|
7
|
+
export { CommonInstance, GoldfishInstance, MiwearInstance, OldGoldfishInstance, findInstance };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
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"));
|
|
8
|
+
const avd_1 = __importDefault(require("../avd"));
|
|
9
|
+
const common_1 = __importDefault(require("./common"));
|
|
10
|
+
exports.CommonInstance = common_1.default;
|
|
11
|
+
const dev_1 = __importDefault(require("./dev"));
|
|
12
|
+
exports.GoldfishInstance = dev_1.default;
|
|
13
|
+
const miwear_1 = __importDefault(require("./miwear"));
|
|
14
|
+
exports.MiwearInstance = miwear_1.default;
|
|
15
|
+
const preDev_1 = __importDefault(require("./preDev"));
|
|
16
|
+
exports.OldGoldfishInstance = preDev_1.default;
|
|
17
|
+
function findInstance(avdName, params) {
|
|
18
|
+
const { sdkHome, avdHome } = params;
|
|
19
|
+
const { avdImagePath } = new avd_1.default({ sdkHome, avdHome }).getVelaAvdInfo(avdName);
|
|
20
|
+
if (!avdImagePath) {
|
|
21
|
+
ColorConsole_1.default.throw(`### Emulator ### Unable to find vela image via avd`);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (avdImagePath.includes('release')) {
|
|
25
|
+
return new miwear_1.default(params);
|
|
26
|
+
}
|
|
27
|
+
else if (avdImagePath.match(/0\.0\.2|0\.0\.1/)) {
|
|
28
|
+
return new preDev_1.default(params);
|
|
29
|
+
}
|
|
30
|
+
return new dev_1.default(params);
|
|
31
|
+
}
|
|
32
|
+
exports.findInstance = findInstance;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { INewGoldfishInstanceParams, IStartOptions } from '../typing/Instance';
|
|
2
|
+
import CommonInstance from './common';
|
|
3
|
+
/**
|
|
4
|
+
* MiwearInstance
|
|
5
|
+
* 针对 vela4.0 的镜像
|
|
6
|
+
*/
|
|
7
|
+
declare class MiwearInstance extends CommonInstance {
|
|
8
|
+
private appPathInEmulator;
|
|
9
|
+
private debugSocket?;
|
|
10
|
+
constructor(params: INewGoldfishInstanceParams);
|
|
11
|
+
/** 在goldfish模拟器中运行快应用 */
|
|
12
|
+
start(options: IStartOptions): Promise<void>;
|
|
13
|
+
/** 启动goldfish模拟器 */
|
|
14
|
+
startGoldfish(options: IStartOptions): Promise<void>;
|
|
15
|
+
/** 通过adb连接模拟器 */
|
|
16
|
+
connectGoldfish(): Promise<boolean>;
|
|
17
|
+
/** 在goldfish中启动快应用 */
|
|
18
|
+
startupQuickApp(options: IStartOptions): Promise<void>;
|
|
19
|
+
/** 将快应用安装到应用列表 */
|
|
20
|
+
installRpkToAppList(rpkPath: string, targetDir: string): Promise<void>;
|
|
21
|
+
initDebugSocket(): Promise<void> | undefined;
|
|
22
|
+
/** 通知模拟器更新 */
|
|
23
|
+
handleUpdate(): Promise<void>;
|
|
24
|
+
/** 创建server */
|
|
25
|
+
createWebsockeServer(): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
export default MiwearInstance;
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
+
};
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
const JavascriptDefaultCompileOption_1 = __importDefault(require("@aiot-toolkit/aiotpack/lib/compiler/javascript/JavascriptDefaultCompileOption"));
|
|
39
|
+
const ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
|
|
40
|
+
const adbMiwt = __importStar(require("@miwt/adb"));
|
|
41
|
+
const child_process_1 = require("child_process");
|
|
42
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
43
|
+
const path_1 = __importDefault(require("path"));
|
|
44
|
+
const portfinder_1 = __importDefault(require("portfinder"));
|
|
45
|
+
const ws_1 = __importStar(require("ws"));
|
|
46
|
+
const constants_1 = require("../static/constants");
|
|
47
|
+
const utils_1 = require("../utils");
|
|
48
|
+
const common_1 = __importDefault(require("./common"));
|
|
49
|
+
/**
|
|
50
|
+
* MiwearInstance
|
|
51
|
+
* 针对 vela4.0 的镜像
|
|
52
|
+
*/
|
|
53
|
+
class MiwearInstance extends common_1.default {
|
|
54
|
+
constructor(params) {
|
|
55
|
+
super(params);
|
|
56
|
+
this.appPathInEmulator = '/data/quickapp/app';
|
|
57
|
+
}
|
|
58
|
+
/** 在goldfish模拟器中运行快应用 */
|
|
59
|
+
start(options) {
|
|
60
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
61
|
+
this.startOptions = options;
|
|
62
|
+
// 启动模拟器
|
|
63
|
+
yield this.startGoldfish(options);
|
|
64
|
+
// adb连接模拟器
|
|
65
|
+
const connected = yield this.connectGoldfish();
|
|
66
|
+
if (connected) {
|
|
67
|
+
ColorConsole_1.default.info('### Emulator ### Goldfish emulator connected successfully');
|
|
68
|
+
if (this.isFirstStart && this.startOptions.serverPort) {
|
|
69
|
+
yield this.createWebsockeServer();
|
|
70
|
+
}
|
|
71
|
+
this.startupQuickApp(options);
|
|
72
|
+
this.isFirstStart = false;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
ColorConsole_1.default.throw('### Emulator ### Failed to connect emulator, please check whether the adb is normal');
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/** 启动goldfish模拟器 */
|
|
80
|
+
startGoldfish(options) {
|
|
81
|
+
var _a;
|
|
82
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
83
|
+
const { avdName, devtool } = options;
|
|
84
|
+
const emulatorBin = this.getEmulatorBinPath();
|
|
85
|
+
ColorConsole_1.default.log(`### Emulator ### emulator path: ${emulatorBin}`);
|
|
86
|
+
const avdInfo = this.velaAvdCls.getVelaAvdInfo(avdName);
|
|
87
|
+
const { avdArch, avdImagePath } = avdInfo;
|
|
88
|
+
this.adbPort = yield portfinder_1.default.getPortPromise({ port: this.adbPort });
|
|
89
|
+
ColorConsole_1.default.log(`### Emulator ### adb port: ${this.adbPort}`);
|
|
90
|
+
if (!avdImagePath) {
|
|
91
|
+
return ColorConsole_1.default.throw(`### Emulator ### Unable to find vela image via avd`);
|
|
92
|
+
}
|
|
93
|
+
const nuttxBinPath = path_1.default.resolve(avdImagePath, 'nuttx');
|
|
94
|
+
ColorConsole_1.default.log(`### Emulator ### nuttx path: ${nuttxBinPath}`);
|
|
95
|
+
// 端口映射
|
|
96
|
+
let portMappingStr = `-network-user-mode-options hostfwd=tcp:127.0.0.1:${this.adbPort}-10.0.2.15:5555`;
|
|
97
|
+
if (devtool) {
|
|
98
|
+
portMappingStr += `,hostfwd=tcp:127.0.0.1:${this.debugPort}-10.0.2.15:101`;
|
|
99
|
+
}
|
|
100
|
+
// 文件系统配置,第一次使用fatfs镜像挂载,后续使用adb push更新应用
|
|
101
|
+
const systemImageBin = path_1.default.resolve(avdImagePath, 'vela_resource.img');
|
|
102
|
+
const dataImageBin = path_1.default.resolve(avdImagePath, 'data.img');
|
|
103
|
+
const imageMountStr = `-drive index=0,id=system,if=none,format=raw,file=${systemImageBin} \
|
|
104
|
+
-device virtio-blk-device,bus=virtio-mmio-bus.0,drive=system \
|
|
105
|
+
-drive index=1,id=userdata,if=none,format=raw,file=${dataImageBin} \
|
|
106
|
+
-device virtio-blk-device,bus=virtio-mmio-bus.1,drive=userdata \
|
|
107
|
+
-device virtio-snd,bus=virtio-mmio-bus.2 -allow-host-audio -semihosting`;
|
|
108
|
+
// vnc配置
|
|
109
|
+
let windowStr = '';
|
|
110
|
+
let vncStr = '';
|
|
111
|
+
if ((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.vncPort) {
|
|
112
|
+
windowStr = '-no-window';
|
|
113
|
+
const portSuffix = this.startOptions.vncPort - constants_1.defaultVncPort;
|
|
114
|
+
vncStr = `-vnc :${portSuffix}`;
|
|
115
|
+
}
|
|
116
|
+
const stdioType = options.disableNSH ? 'pipe' : 'inherit';
|
|
117
|
+
// 启动goldfish的命令和参数
|
|
118
|
+
const cmd = `${emulatorBin} -nuttx -avd ${avdName} -avd-arch ${avdArch} -show-kernel -kernel ${nuttxBinPath} ${portMappingStr} ${windowStr} -qemu ${vncStr} ${imageMountStr}`;
|
|
119
|
+
const spawnArgs = cmd.split(' ');
|
|
120
|
+
const spawnBin = spawnArgs.shift();
|
|
121
|
+
ColorConsole_1.default.log(`### Emulator ### Start CMD: ${cmd}`);
|
|
122
|
+
return new Promise((resolve) => {
|
|
123
|
+
var _a, _b, _c;
|
|
124
|
+
this.goldfishProcess = (0, child_process_1.spawn)(spawnBin, spawnArgs, { stdio: stdioType, shell: true });
|
|
125
|
+
(_a = this.goldfishProcess.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
126
|
+
const stderrCb = options.stderrCallback || console.log;
|
|
127
|
+
stderrCb(data.toString());
|
|
128
|
+
});
|
|
129
|
+
this.goldfishProcess.on('exit', (code) => {
|
|
130
|
+
ColorConsole_1.default.error(`### Emulator ### Goldfish emulator exited with code ${code}`);
|
|
131
|
+
if (options.exitCallback) {
|
|
132
|
+
options.exitCallback(code);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
if (options.disableNSH) {
|
|
136
|
+
(_c = (_b = this.goldfishProcess) === null || _b === void 0 ? void 0 : _b.stdout) === null || _c === void 0 ? void 0 : _c.on('data', (data) => {
|
|
137
|
+
const msg = data.toString();
|
|
138
|
+
const stdoutCb = options.stdoutCallback || console.log;
|
|
139
|
+
stdoutCb(msg);
|
|
140
|
+
if (msg.match(/quickapp_rpk_installer_init | rpk installer init done/)) {
|
|
141
|
+
ColorConsole_1.default.info(`### Emulator ### Goldfish emulator starts successfully`);
|
|
142
|
+
resolve();
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
setTimeout(() => {
|
|
148
|
+
ColorConsole_1.default.info(`### Emulator ### Goldfish emulator starts successfully`);
|
|
149
|
+
resolve();
|
|
150
|
+
}, 8000);
|
|
151
|
+
ColorConsole_1.default.info(`### Emulator ### Goldfish emulator starts successfully`);
|
|
152
|
+
resolve();
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
/** 通过adb连接模拟器 */
|
|
158
|
+
connectGoldfish() {
|
|
159
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
160
|
+
let adbConnected = false;
|
|
161
|
+
const connectFn = () => __awaiter(this, void 0, void 0, function* () {
|
|
162
|
+
const sn = `127.0.0.1:${this.adbPort}`;
|
|
163
|
+
while (!adbConnected) {
|
|
164
|
+
const adbKillCmd = `adb kill-server`;
|
|
165
|
+
ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${adbKillCmd}`);
|
|
166
|
+
yield adbMiwt.execAdbCmdAsync(adbKillCmd);
|
|
167
|
+
const adbConnectCmd = `adb connect ${sn}`;
|
|
168
|
+
ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${adbConnectCmd}`);
|
|
169
|
+
const str = yield adbMiwt.execAdbCmdAsync(adbConnectCmd);
|
|
170
|
+
ColorConsole_1.default.log(`### Emulator ### ${str}`);
|
|
171
|
+
const devices = yield adbMiwt.getAdbDevices();
|
|
172
|
+
ColorConsole_1.default.log(`### Emulator ### adb devices: ${JSON.stringify(devices)}`);
|
|
173
|
+
adbConnected =
|
|
174
|
+
devices.filter((item) => item.sn === sn && item.status === 'device').length > 0;
|
|
175
|
+
}
|
|
176
|
+
Promise.resolve(adbConnected);
|
|
177
|
+
});
|
|
178
|
+
yield Promise.race([
|
|
179
|
+
connectFn(),
|
|
180
|
+
new Promise((resolve) => {
|
|
181
|
+
setTimeout(() => resolve(false), 600 * 1000);
|
|
182
|
+
})
|
|
183
|
+
]);
|
|
184
|
+
return adbConnected;
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
/** 在goldfish中启动快应用 */
|
|
188
|
+
startupQuickApp(options) {
|
|
189
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
190
|
+
const { package: appPackageName } = this.projectInfo;
|
|
191
|
+
const releaseDir = path_1.default.resolve(this.projectPath, JavascriptDefaultCompileOption_1.default.releasePath || 'dist');
|
|
192
|
+
const files = fs_extra_1.default
|
|
193
|
+
.readdirSync(releaseDir)
|
|
194
|
+
.filter(item => item.includes(appPackageName) && item.endsWith('.rpk'));
|
|
195
|
+
if (files.length < 0) {
|
|
196
|
+
ColorConsole_1.default.error(`### Emulator the rpk does not exist`);
|
|
197
|
+
}
|
|
198
|
+
const rpkPath = path_1.default.resolve(releaseDir, files[0]);
|
|
199
|
+
// 调试模式需要push一个文件至miwear中
|
|
200
|
+
const sn = `127.0.0.1:${this.adbPort}`;
|
|
201
|
+
if (options.devtool) {
|
|
202
|
+
const debuggerCfgFile = path_1.default.join(__dirname, '../static/debugger_ip.cfg');
|
|
203
|
+
yield adbMiwt.execAdbCmdAsync(`adb -s ${sn} push ${debuggerCfgFile} /data/debugger_ip.cfg`);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
adbMiwt.execAdbCmdAsync(`adb -s ${sn} shell rm /data/debugger_ip.cfg`);
|
|
207
|
+
}
|
|
208
|
+
this.installRpkToAppList(rpkPath, this.appPathInEmulator);
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
/** 将快应用安装到应用列表 */
|
|
212
|
+
installRpkToAppList(rpkPath, targetDir) {
|
|
213
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
214
|
+
try {
|
|
215
|
+
const sn = `127.0.0.1:${this.adbPort}`;
|
|
216
|
+
const { package: packageName } = this.projectInfo;
|
|
217
|
+
const rpkName = path_1.default.basename(rpkPath);
|
|
218
|
+
// 1. 查询应用是否已经安装,如果安装了,则先卸载
|
|
219
|
+
const lsCmd = `adb -s ${sn} shell ls ${this.appPathInEmulator}`;
|
|
220
|
+
const res = yield adbMiwt.execAdbCmdAsync(lsCmd);
|
|
221
|
+
if (res.includes(packageName)) {
|
|
222
|
+
const uninstallCmd = `adb -s ${sn} shell pm uninstall ${packageName}`;
|
|
223
|
+
ColorConsole_1.default.info(`### Emulator ### Excuting cmd: ${uninstallCmd}`);
|
|
224
|
+
adbMiwt.execAdbCmdAsync(uninstallCmd);
|
|
225
|
+
// 这里等待2s的作用是等qemu执行完uninstall操作的一系列工作
|
|
226
|
+
yield (0, utils_1.sleep)(2000);
|
|
227
|
+
}
|
|
228
|
+
// 2. adb push应用的rpk
|
|
229
|
+
const pushCmd = `adb -s ${sn} push ${rpkPath} ${targetDir}`;
|
|
230
|
+
ColorConsole_1.default.info(`### Emulator ### Excuting cmd: ${pushCmd}`);
|
|
231
|
+
yield adbMiwt.execAdbCmdAsync(pushCmd);
|
|
232
|
+
yield (0, utils_1.sleep)(100);
|
|
233
|
+
// 3. 安装应用
|
|
234
|
+
const targetPath = `${targetDir}/${rpkName}`;
|
|
235
|
+
const installCmd = `adb -s ${sn} shell pm install ${targetPath}`;
|
|
236
|
+
ColorConsole_1.default.info(`### Emulator ### Excuting cmd: ${installCmd}`);
|
|
237
|
+
adbMiwt.execAdbCmdAsync(installCmd);
|
|
238
|
+
}
|
|
239
|
+
catch (e) { }
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
initDebugSocket() {
|
|
243
|
+
if (this.debugSocket) {
|
|
244
|
+
return Promise.resolve();
|
|
245
|
+
}
|
|
246
|
+
this.debugSocket = new ws_1.default(`ws://localhost:${this.debugPort}`);
|
|
247
|
+
this.debugSocket.onopen = e => {
|
|
248
|
+
ColorConsole_1.default.info(`### debugSocket connect success`);
|
|
249
|
+
return Promise.resolve();
|
|
250
|
+
};
|
|
251
|
+
this.debugSocket.onerror = (e) => {
|
|
252
|
+
ColorConsole_1.default.error(`### Emulator ${e.data}`);
|
|
253
|
+
};
|
|
254
|
+
this.debugSocket.onclose = (e) => {
|
|
255
|
+
ColorConsole_1.default.error(`### Emulator debugSocket connect close: ${e.data}`);
|
|
256
|
+
this.debugSocket = undefined;
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
/** 通知模拟器更新 */
|
|
260
|
+
handleUpdate() {
|
|
261
|
+
var _a, _b;
|
|
262
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
263
|
+
yield this.initDebugSocket();
|
|
264
|
+
// 1. 将整包重新推到miwear中(TODO:增量更新)
|
|
265
|
+
const sn = `127.0.0.1:${this.adbPort}`;
|
|
266
|
+
const { package: appPackageName } = this.projectInfo;
|
|
267
|
+
const sourcePath = path_1.default.resolve(this.projectPath, './build/*');
|
|
268
|
+
yield adbMiwt.execAdbCmdAsync(`adb -s ${sn} push ${sourcePath} ${this.appPathInEmulator}/${appPackageName}`);
|
|
269
|
+
ColorConsole_1.default.info(`### Emulator push to ${this.appPathInEmulator}/${appPackageName} successfully`);
|
|
270
|
+
// 2. 下发CDP命令给调试服务告知刷新
|
|
271
|
+
if (((_a = this.debugSocket) === null || _a === void 0 ? void 0 : _a.readyState) === ws_1.default.OPEN) {
|
|
272
|
+
(_b = this.debugSocket) === null || _b === void 0 ? void 0 : _b.send(JSON.stringify({ id: 10000, method: 'Page.reload', params: {} }));
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
/** 创建server */
|
|
277
|
+
createWebsockeServer() {
|
|
278
|
+
var _a;
|
|
279
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
280
|
+
const wsServer = new ws_1.WebSocketServer({
|
|
281
|
+
port: (_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.serverPort,
|
|
282
|
+
});
|
|
283
|
+
wsServer.on('connection', socket => {
|
|
284
|
+
ColorConsole_1.default.success(`### App Socket server ### Websocket connects to websocket server`);
|
|
285
|
+
socket.on('error', err => {
|
|
286
|
+
ColorConsole_1.default.error(`### App Socket server ### Websocket server error: ${err.message}`);
|
|
287
|
+
});
|
|
288
|
+
socket.on('message', (data) => __awaiter(this, void 0, void 0, function* () {
|
|
289
|
+
var _a;
|
|
290
|
+
const message = JSON.parse(data.toString());
|
|
291
|
+
ColorConsole_1.default.log(`### App Socket server ### Websocket server get data: ${data}`);
|
|
292
|
+
if (message.type === 'restart') {
|
|
293
|
+
// 非调试模式下无法热更新
|
|
294
|
+
if (!((_a = this.startOptions) === null || _a === void 0 ? void 0 : _a.devtool)) {
|
|
295
|
+
this.restart();
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
this.handleUpdate();
|
|
299
|
+
}
|
|
300
|
+
else if (message.type === 'stop') {
|
|
301
|
+
this.stop();
|
|
302
|
+
}
|
|
303
|
+
}));
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
exports.default = MiwearInstance;
|
|
@@ -1,22 +1,11 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { ChildProcess } from 'child_process';
|
|
3
3
|
import { INewGoldfishInstanceParams, IStartOptions } from '../typing/Instance';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
private sdkHome;
|
|
7
|
-
private avdHome;
|
|
8
|
-
private adbPort;
|
|
9
|
-
debugPort: number;
|
|
4
|
+
import CommonInstance from './common';
|
|
5
|
+
declare class OldGoldfishInstance extends CommonInstance {
|
|
10
6
|
private host9pPort;
|
|
11
|
-
private velaAvdCls;
|
|
12
|
-
private packageName;
|
|
13
|
-
goldfishProcess: ChildProcess | undefined;
|
|
14
7
|
v9fsProcess: ChildProcess | undefined;
|
|
15
|
-
isFirstStart: boolean;
|
|
16
|
-
private startOptions;
|
|
17
8
|
constructor(params: INewGoldfishInstanceParams);
|
|
18
|
-
/** 获取模拟器二进制文件所在位置 */
|
|
19
|
-
getEmulatorBinPath(): string;
|
|
20
9
|
/** 在goldfish模拟器中运行快应用 */
|
|
21
10
|
start(options: IStartOptions): Promise<void>;
|
|
22
11
|
/** 在goldfish中启动快应用 */
|
|
@@ -27,15 +16,8 @@ declare class GoldfishInstance {
|
|
|
27
16
|
startGoldfish(options: IStartOptions): Promise<void>;
|
|
28
17
|
/** 通过adb连接模拟器 */
|
|
29
18
|
connectGoldfish(): Promise<boolean>;
|
|
30
|
-
|
|
31
|
-
pushRpk(): void;
|
|
32
|
-
/** 杀死进程 */
|
|
33
|
-
killProcess(currProcess?: ChildProcess): void;
|
|
19
|
+
pushRpk(sourceRoot: string): Promise<void>;
|
|
34
20
|
/** 停止模拟器并释放相关资源 */
|
|
35
|
-
stop(): void
|
|
36
|
-
/** 重启模拟器 */
|
|
37
|
-
restart(): void;
|
|
38
|
-
/** 创建server */
|
|
39
|
-
createWebsockeServer(): Promise<void>;
|
|
21
|
+
stop(): Promise<void>;
|
|
40
22
|
}
|
|
41
|
-
export default
|
|
23
|
+
export default OldGoldfishInstance;
|
|
@@ -35,7 +35,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
35
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
36
|
};
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
const UxFileUtils_1 = __importDefault(require("@aiot-toolkit/aiotpack/lib/utils/ux/UxFileUtils"));
|
|
39
38
|
const ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
|
|
40
39
|
const FileUtil_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/utils/FileUtil"));
|
|
41
40
|
const adbMiwt = __importStar(require("@miwt/adb"));
|
|
@@ -45,33 +44,12 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
45
44
|
const os_1 = __importDefault(require("os"));
|
|
46
45
|
const path_1 = __importDefault(require("path"));
|
|
47
46
|
const portfinder_1 = __importDefault(require("portfinder"));
|
|
48
|
-
const ws_1 = require("ws");
|
|
49
|
-
const avd_1 = __importDefault(require("../avd"));
|
|
50
47
|
const constants_1 = require("../static/constants");
|
|
51
|
-
const
|
|
52
|
-
class
|
|
48
|
+
const common_1 = __importDefault(require("./common"));
|
|
49
|
+
class OldGoldfishInstance extends common_1.default {
|
|
53
50
|
constructor(params) {
|
|
54
|
-
|
|
55
|
-
this.debugPort = 10055;
|
|
51
|
+
super(params);
|
|
56
52
|
this.host9pPort = 7878;
|
|
57
|
-
this.isFirstStart = true;
|
|
58
|
-
this.projectPath = params.projectPath;
|
|
59
|
-
this.sdkHome = params.sdkHome || constants_1.defaultSDKHome;
|
|
60
|
-
this.avdHome = params.avdHome || constants_1.defaultAvdHome;
|
|
61
|
-
this.velaAvdCls = new avd_1.default({
|
|
62
|
-
sdkHome: this.sdkHome,
|
|
63
|
-
avdHome: this.avdHome
|
|
64
|
-
});
|
|
65
|
-
const { package: appPackageName } = UxFileUtils_1.default.getMainfestInfo(this.projectPath, params.sourceRoot);
|
|
66
|
-
this.packageName = appPackageName;
|
|
67
|
-
}
|
|
68
|
-
/** 获取模拟器二进制文件所在位置 */
|
|
69
|
-
getEmulatorBinPath() {
|
|
70
|
-
const osPlatform = os_1.default.platform();
|
|
71
|
-
const arch = (0, utils_1.getSystemArch)();
|
|
72
|
-
const platform = osPlatform === 'win32' ? 'windows' : osPlatform;
|
|
73
|
-
const emulatorHome = path_1.default.resolve(this.sdkHome, 'emulator');
|
|
74
|
-
return path_1.default.resolve(emulatorHome, `${platform}-${arch}`, 'emulator');
|
|
75
53
|
}
|
|
76
54
|
/** 在goldfish模拟器中运行快应用 */
|
|
77
55
|
start(options) {
|
|
@@ -79,8 +57,9 @@ class GoldfishInstance {
|
|
|
79
57
|
// host启动9p server
|
|
80
58
|
yield this.ensure9pServerRunnning();
|
|
81
59
|
this.startOptions = options;
|
|
82
|
-
// 将rpk推到host
|
|
83
|
-
this.
|
|
60
|
+
// 将rpk推到host的./export/qa/app目录
|
|
61
|
+
const buildedFilesPath = this.isRpk ? this.projectPath : path_1.default.resolve(this.projectPath, './build');
|
|
62
|
+
this.pushRpk(buildedFilesPath);
|
|
84
63
|
// 启动模拟器
|
|
85
64
|
yield this.startGoldfish(options);
|
|
86
65
|
const connected = yield this.connectGoldfish();
|
|
@@ -101,13 +80,14 @@ class GoldfishInstance {
|
|
|
101
80
|
/** 在goldfish中启动快应用 */
|
|
102
81
|
startupQuickApp(options) {
|
|
103
82
|
try {
|
|
83
|
+
const { package: packageName } = this.projectInfo;
|
|
104
84
|
const appMountDir = path_1.default.resolve(this.sdkHome, 'qa');
|
|
105
85
|
const mountCmd = `adb -s 127.0.0.1:${this.adbPort} shell mount -t v9fs -o tag=10.0.2.2,port=${this.host9pPort},aname=${appMountDir} /data`;
|
|
106
86
|
ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${mountCmd}`);
|
|
107
87
|
adbMiwt.execAdbCmdSync(mountCmd);
|
|
108
|
-
let vappCmd = `adb -s 127.0.0.1:${this.adbPort} shell vapp app/${
|
|
88
|
+
let vappCmd = `adb -s 127.0.0.1:${this.adbPort} shell vapp app/${packageName} &`;
|
|
109
89
|
if (options.devtool) {
|
|
110
|
-
vappCmd = `adb -s 127.0.0.1:${this.adbPort} shell vapp --jsdebugger=10.0.2.15:101 app/${
|
|
90
|
+
vappCmd = `adb -s 127.0.0.1:${this.adbPort} shell vapp --jsdebugger=10.0.2.15:101 app/${packageName} &`;
|
|
111
91
|
}
|
|
112
92
|
ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${vappCmd}`);
|
|
113
93
|
// vapp进程会一直pending,不会退出。这里必须加stdio: 'ignore',否则快应用无法运行成功
|
|
@@ -157,7 +137,6 @@ class GoldfishInstance {
|
|
|
157
137
|
}
|
|
158
138
|
/** 启动goldfish模拟器 */
|
|
159
139
|
startGoldfish(options) {
|
|
160
|
-
var _a;
|
|
161
140
|
return __awaiter(this, void 0, void 0, function* () {
|
|
162
141
|
const { avdName, devtool } = options;
|
|
163
142
|
const emulatorBin = this.getEmulatorBinPath();
|
|
@@ -182,9 +161,9 @@ class GoldfishInstance {
|
|
|
182
161
|
// vnc配置
|
|
183
162
|
let noWindow = false;
|
|
184
163
|
let vncStr = '';
|
|
185
|
-
if (
|
|
164
|
+
if (options.vncPort) {
|
|
186
165
|
noWindow = true;
|
|
187
|
-
const portSuffix =
|
|
166
|
+
const portSuffix = options.vncPort - constants_1.defaultVncPort;
|
|
188
167
|
vncStr = `-vnc :${portSuffix}`;
|
|
189
168
|
}
|
|
190
169
|
// 启动goldfish的命令和参数
|
|
@@ -211,15 +190,20 @@ class GoldfishInstance {
|
|
|
211
190
|
var _a;
|
|
212
191
|
this.goldfishProcess = (0, child_process_1.spawn)(spawnBin, spawnArgs, { stdio: stdioType, shell: true });
|
|
213
192
|
(_a = this.goldfishProcess.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
214
|
-
console.log
|
|
193
|
+
const stderrCb = options.stderrCallback || console.log;
|
|
194
|
+
stderrCb(data.toString());
|
|
215
195
|
});
|
|
216
196
|
this.goldfishProcess.on('exit', (code) => {
|
|
217
197
|
ColorConsole_1.default.error(`### Emulator ### Goldfish emulator exited with code ${code}`);
|
|
198
|
+
if (options.exitCallback) {
|
|
199
|
+
options.exitCallback(code);
|
|
200
|
+
}
|
|
218
201
|
});
|
|
219
202
|
const p1 = new Promise((resolve) => {
|
|
220
203
|
var _a, _b;
|
|
221
204
|
(_b = (_a = this.goldfishProcess) === null || _a === void 0 ? void 0 : _a.stdout) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
|
|
222
|
-
console.log
|
|
205
|
+
const stdoutCb = options.stdoutCallback || console.log;
|
|
206
|
+
stdoutCb(data.toString());
|
|
223
207
|
if (data.toString().includes('(NSH)')) {
|
|
224
208
|
ColorConsole_1.default.log(`### Emulator ### Goldfish emulator starts successfully`);
|
|
225
209
|
resolve();
|
|
@@ -264,84 +248,28 @@ class GoldfishInstance {
|
|
|
264
248
|
return adbConnected;
|
|
265
249
|
});
|
|
266
250
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}
|
|
277
|
-
/** 杀死进程 */
|
|
278
|
-
killProcess(currProcess) {
|
|
279
|
-
if (currProcess && currProcess.pid && currProcess.exitCode === null) {
|
|
280
|
-
console.log('process pid:', currProcess.pid);
|
|
281
|
-
try {
|
|
282
|
-
if (os_1.default.platform() === 'win32') {
|
|
283
|
-
(0, child_process_1.execSync)(`taskkill /pid ${currProcess.pid} /T /F`);
|
|
284
|
-
}
|
|
285
|
-
else if (os_1.default.platform() === 'darwin') {
|
|
286
|
-
process.kill(currProcess.pid);
|
|
287
|
-
}
|
|
288
|
-
else {
|
|
289
|
-
currProcess.kill();
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
catch (err) {
|
|
293
|
-
ColorConsole_1.default.log(`### Emulator ### kill process get error :\n${err.stack}`);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
251
|
+
pushRpk(sourceRoot) {
|
|
252
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
253
|
+
const { package: appPackageName } = this.projectInfo;
|
|
254
|
+
const appRunDir = path_1.default.resolve(this.sdkHome, 'qa/app', appPackageName);
|
|
255
|
+
ColorConsole_1.default.log(`### Emulator ### Pushing ${appPackageName} to ${appRunDir}`);
|
|
256
|
+
fs_1.default.rmSync(appRunDir, { recursive: true, force: true });
|
|
257
|
+
FileUtil_1.default.copyFiles(sourceRoot, appRunDir);
|
|
258
|
+
ColorConsole_1.default.log(`### Emulator ### Push ${appPackageName} to ${appRunDir} successfully`);
|
|
259
|
+
});
|
|
296
260
|
}
|
|
297
261
|
/** 停止模拟器并释放相关资源 */
|
|
298
262
|
stop() {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
if (os_1.default.platform() === 'linux' && this.goldfishProcess.pid) {
|
|
303
|
-
process.kill(this.goldfishProcess.pid + 1);
|
|
304
|
-
}
|
|
305
|
-
this.killProcess(this.goldfishProcess);
|
|
306
|
-
this.goldfishProcess = undefined;
|
|
307
|
-
}
|
|
308
|
-
if (this.v9fsProcess) {
|
|
309
|
-
this.killProcess(this.v9fsProcess);
|
|
310
|
-
this.v9fsProcess = undefined;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
/** 重启模拟器 */
|
|
314
|
-
restart() {
|
|
315
|
-
if (this.goldfishProcess) {
|
|
316
|
-
this.killProcess(this.goldfishProcess);
|
|
317
|
-
this.goldfishProcess = undefined;
|
|
318
|
-
}
|
|
319
|
-
this.start(this.startOptions);
|
|
320
|
-
}
|
|
321
|
-
/** 创建server */
|
|
322
|
-
createWebsockeServer() {
|
|
323
|
-
var _a;
|
|
263
|
+
const _super = Object.create(null, {
|
|
264
|
+
stop: { get: () => super.stop }
|
|
265
|
+
});
|
|
324
266
|
return __awaiter(this, void 0, void 0, function* () {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
socket.on('error', err => {
|
|
331
|
-
ColorConsole_1.default.error(`### App Socket server ### Websocket server error: ${err.message}`);
|
|
332
|
-
});
|
|
333
|
-
socket.on('message', data => {
|
|
334
|
-
const message = JSON.parse(data.toString());
|
|
335
|
-
ColorConsole_1.default.log(`### App Socket server ### Websocket server get data: ${data}`);
|
|
336
|
-
if (message.type === 'restart') {
|
|
337
|
-
this.restart();
|
|
338
|
-
}
|
|
339
|
-
else if (message.type === 'stop') {
|
|
340
|
-
this.stop();
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
});
|
|
267
|
+
_super.stop.call(this);
|
|
268
|
+
if (this.v9fsProcess) {
|
|
269
|
+
this.killProcess(this.v9fsProcess);
|
|
270
|
+
this.v9fsProcess = undefined;
|
|
271
|
+
}
|
|
344
272
|
});
|
|
345
273
|
}
|
|
346
274
|
}
|
|
347
|
-
exports.default =
|
|
275
|
+
exports.default = OldGoldfishInstance;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
10.0.2.15:101
|
package/lib/typing/Instance.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { IAvdResourcePaths } from "./Avd";
|
|
2
3
|
export interface INewGoldfishInstanceParams extends IAvdResourcePaths {
|
|
3
4
|
projectPath: string;
|
|
@@ -9,4 +10,7 @@ export interface IStartOptions {
|
|
|
9
10
|
disableNSH?: boolean;
|
|
10
11
|
serverPort?: number;
|
|
11
12
|
vncPort?: number;
|
|
13
|
+
stdoutCallback?: (buffer: Buffer) => void;
|
|
14
|
+
stderrCallback?: (buffer: Buffer) => void;
|
|
15
|
+
exitCallback?: (code: number | null) => void;
|
|
12
16
|
}
|
package/lib/utils/index.d.ts
CHANGED
|
@@ -3,3 +3,10 @@
|
|
|
3
3
|
* 所以15.0.0之前无法通过os.arch()区分,也无法通过execSync('uname -m')区分
|
|
4
4
|
*/
|
|
5
5
|
export declare function getSystemArch(): string | void;
|
|
6
|
+
/** 根据PID杀死进程 */
|
|
7
|
+
export declare function killProcessByPid(pid: string): void;
|
|
8
|
+
/**
|
|
9
|
+
* 根据命令杀死进程
|
|
10
|
+
*/
|
|
11
|
+
export declare function killProcessByCmd(cmd: string): Promise<void>;
|
|
12
|
+
export declare function sleep(time: number): Promise<void>;
|
package/lib/utils/index.js
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
2
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
13
|
};
|
|
5
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getSystemArch = void 0;
|
|
15
|
+
exports.sleep = exports.killProcessByCmd = exports.killProcessByPid = exports.getSystemArch = void 0;
|
|
7
16
|
const ColorConsole_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole"));
|
|
8
17
|
const child_process_1 = require("child_process");
|
|
18
|
+
const find_process_1 = __importDefault(require("find-process"));
|
|
9
19
|
const os_1 = __importDefault(require("os"));
|
|
10
20
|
const semver_1 = __importDefault(require("semver"));
|
|
11
21
|
const cpuArch = {
|
|
@@ -37,3 +47,41 @@ function getSystemArch() {
|
|
|
37
47
|
return cpuArch[osArch];
|
|
38
48
|
}
|
|
39
49
|
exports.getSystemArch = getSystemArch;
|
|
50
|
+
/** 根据PID杀死进程 */
|
|
51
|
+
function killProcessByPid(pid) {
|
|
52
|
+
try {
|
|
53
|
+
const cmd = os_1.default.platform() === "win32"
|
|
54
|
+
? `taskkill /pid ${pid} /T /F`
|
|
55
|
+
: `kill -9 ${pid}`;
|
|
56
|
+
(0, child_process_1.execSync)(cmd);
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
console.error(`kill process ${pid} get error: ${e}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.killProcessByPid = killProcessByPid;
|
|
63
|
+
/**
|
|
64
|
+
* 根据命令杀死进程
|
|
65
|
+
*/
|
|
66
|
+
function killProcessByCmd(cmd) {
|
|
67
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
68
|
+
if (!cmd)
|
|
69
|
+
return;
|
|
70
|
+
try {
|
|
71
|
+
const list = yield (0, find_process_1.default)('name', cmd);
|
|
72
|
+
list.forEach((item) => __awaiter(this, void 0, void 0, function* () {
|
|
73
|
+
killProcessByPid(item.pid.toString());
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
console.error(`kill process ${cmd} get error: ${e}`);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
exports.killProcessByCmd = killProcessByCmd;
|
|
82
|
+
function sleep(time) {
|
|
83
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
+
return new Promise(resolve => setTimeout(resolve, time));
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
exports.sleep = sleep;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiot-toolkit/emulator",
|
|
3
|
-
"version": "2.0.2-dev.
|
|
3
|
+
"version": "2.0.2-dev.5",
|
|
4
4
|
"description": "vela emulator tool.",
|
|
5
5
|
"homepage": "",
|
|
6
6
|
"license": "ISC",
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
"emulator"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@aiot-toolkit/aiotpack": "2.0.2-dev.
|
|
39
|
-
"@aiot-toolkit/shared-utils": "2.0.2-dev.
|
|
38
|
+
"@aiot-toolkit/aiotpack": "2.0.2-dev.5",
|
|
39
|
+
"@aiot-toolkit/shared-utils": "2.0.2-dev.5",
|
|
40
40
|
"find-process": "^1.4.7",
|
|
41
41
|
"portfinder": "^1.0.32"
|
|
42
42
|
},
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "0c123fdd458966a4ca438cca03cc9efc2b5f634c"
|
|
44
44
|
}
|