@arkts/image-manager 0.4.2 → 0.5.0
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/README.md +1 -75
- package/dist/default-emulator-config.d.cts +274 -3
- package/dist/default-emulator-config.d.mts +274 -3
- package/dist/default-product-config.cjs +8 -0
- package/dist/default-product-config.d.cts +379 -3
- package/dist/default-product-config.d.mts +379 -3
- package/dist/default-product-config.mjs +8 -0
- package/dist/index.cjs +1380 -1070
- package/dist/index.d.cts +1113 -540
- package/dist/index.d.mts +1112 -539
- package/dist/index.mjs +1306 -1037
- package/package.json +7 -2
- package/dist/emulator-config-DbI3FRE5.d.mts +0 -64
- package/dist/emulator-config-HeXlMqZ-.d.cts +0 -64
- package/dist/product-config-ByDVg0-5.d.mts +0 -67
- package/dist/product-config-DuzOJEvZ.d.cts +0 -67
- package/dist/types-CayFonNb.d.cts +0 -16
- package/dist/types-DD8_iqBV.d.mts +0 -16
package/dist/index.cjs
CHANGED
|
@@ -26,1339 +26,1645 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
}) : target, mod));
|
|
27
27
|
|
|
28
28
|
//#endregion
|
|
29
|
-
let axios = require("axios");
|
|
30
|
-
axios = __toESM(axios);
|
|
31
|
-
let semver_functions_satisfies = require("semver/functions/satisfies");
|
|
32
|
-
semver_functions_satisfies = __toESM(semver_functions_satisfies);
|
|
33
29
|
let ini = require("ini");
|
|
34
30
|
ini = __toESM(ini);
|
|
35
|
-
let
|
|
36
|
-
|
|
37
|
-
let progress_stream = require("progress-stream");
|
|
38
|
-
progress_stream = __toESM(progress_stream);
|
|
31
|
+
let base64_js = require("base64-js");
|
|
32
|
+
let vscode_fs = require("vscode-fs");
|
|
39
33
|
|
|
40
|
-
//#region
|
|
41
|
-
var
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
let DevModel = /* @__PURE__ */ function(DevModel) {
|
|
46
|
-
DevModel["MCHEMU_AL00CN"] = "MCHEMU-AL00CN";
|
|
47
|
-
DevModel["PHEMU_FD00"] = "PHEMU-FD00";
|
|
48
|
-
DevModel["PHEMU_FD01"] = "PHEMU-FD01";
|
|
49
|
-
DevModel["PHEMU_FD02"] = "PHEMU-FD02";
|
|
50
|
-
DevModel["PHEMU_FD06"] = "PHEMU-FD06";
|
|
51
|
-
DevModel["PCEMU_FD00"] = "PCEMU-FD00";
|
|
52
|
-
DevModel["PCEMU_FD05"] = "PCEMU-FD05";
|
|
53
|
-
return DevModel;
|
|
54
|
-
}({});
|
|
55
|
-
|
|
56
|
-
//#endregion
|
|
57
|
-
//#region src/emulator-config.ts
|
|
58
|
-
let BaseEmulatorConfigItem;
|
|
59
|
-
(function(_BaseEmulatorConfigItem) {
|
|
60
|
-
function is(value) {
|
|
61
|
-
return typeof value === "object" && value !== null && "name" in value && typeof value.name === "string" && "deviceType" in value && typeof value.deviceType === "string" && "api" in value && typeof value.api === "number";
|
|
62
|
-
}
|
|
63
|
-
_BaseEmulatorConfigItem.is = is;
|
|
64
|
-
})(BaseEmulatorConfigItem || (BaseEmulatorConfigItem = {}));
|
|
65
|
-
let ParentEmulatorConfigItem;
|
|
66
|
-
(function(_ParentEmulatorConfigItem) {
|
|
67
|
-
function is(value) {
|
|
68
|
-
return BaseEmulatorConfigItem.is(value) && "resolutionWidth" in value && typeof value.resolutionWidth === "number" && "resolutionHeight" in value && typeof value.resolutionHeight === "number" && "physicalWidth" in value && typeof value.physicalWidth === "number" && "physicalHeight" in value && typeof value.physicalHeight === "number" && "diagonalSize" in value && typeof value.diagonalSize === "number" && "density" in value && typeof value.density === "number" && "memoryRamSize" in value && typeof value.memoryRamSize === "number" && "datadiskSize" in value && typeof value.datadiskSize === "number" && "procNumber" in value && typeof value.procNumber === "number" && "api" in value && typeof value.api === "number";
|
|
69
|
-
}
|
|
70
|
-
_ParentEmulatorConfigItem.is = is;
|
|
71
|
-
})(ParentEmulatorConfigItem || (ParentEmulatorConfigItem = {}));
|
|
72
|
-
let PhoneAllEmulatorConfigItem;
|
|
73
|
-
(function(_PhoneAllEmulatorConfigItem) {
|
|
74
|
-
function is(value) {
|
|
75
|
-
return ParentEmulatorConfigItem.is(value);
|
|
34
|
+
//#region src/common/serializable-content.ts
|
|
35
|
+
var SerializableContentImpl = class {
|
|
36
|
+
constructor(imageManager, content) {
|
|
37
|
+
this.imageManager = imageManager;
|
|
38
|
+
this.content = content;
|
|
76
39
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
let GroupPhoneAllEmulatorConfigItem;
|
|
80
|
-
(function(_GroupPhoneAllEmulatorConfigItem) {
|
|
81
|
-
function is(value) {
|
|
82
|
-
return BaseEmulatorConfigItem.is(value) && "children" in value && Array.isArray(value.children) && value.children.every(PhoneAllEmulatorConfigItem.is);
|
|
40
|
+
getImageManager() {
|
|
41
|
+
return this.imageManager;
|
|
83
42
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
let PCAllEmulatorConfigItem;
|
|
87
|
-
(function(_PCAllEmulatorConfigItem) {
|
|
88
|
-
function is(value) {
|
|
89
|
-
return ParentEmulatorConfigItem.is(value);
|
|
43
|
+
getContent() {
|
|
44
|
+
return this.content;
|
|
90
45
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
(
|
|
95
|
-
|
|
96
|
-
return BaseEmulatorConfigItem.is(value) && "children" in value && Array.isArray(value.children) && value.children.every(PCAllEmulatorConfigItem.is);
|
|
46
|
+
toJSON() {
|
|
47
|
+
return {
|
|
48
|
+
imageManager: this.getImageManager().toJSON(),
|
|
49
|
+
content: this.getContent()
|
|
50
|
+
};
|
|
97
51
|
}
|
|
98
|
-
|
|
99
|
-
})(GroupPCAllEmulatorConfigItem || (GroupPCAllEmulatorConfigItem = {}));
|
|
52
|
+
};
|
|
100
53
|
|
|
101
54
|
//#endregion
|
|
102
|
-
//#region src/
|
|
103
|
-
var
|
|
104
|
-
constructor(
|
|
105
|
-
super(
|
|
106
|
-
this.
|
|
107
|
-
this.
|
|
108
|
-
this.cause = cause;
|
|
55
|
+
//#region src/common/serializable-file.ts
|
|
56
|
+
var SerializableFileImpl = class extends SerializableContentImpl {
|
|
57
|
+
constructor(imageManager, content) {
|
|
58
|
+
super(imageManager, content);
|
|
59
|
+
this.imageManager = imageManager;
|
|
60
|
+
this.content = content;
|
|
109
61
|
}
|
|
110
|
-
|
|
111
|
-
return this.
|
|
62
|
+
getImageManager() {
|
|
63
|
+
return this.imageManager;
|
|
64
|
+
}
|
|
65
|
+
async writeToFileSystem(uri) {
|
|
66
|
+
const { adapter: { fs, dirname } } = this.imageManager.getOptions();
|
|
67
|
+
const directoryUri = dirname(uri);
|
|
68
|
+
if (!await fs.exists(directoryUri)) await fs.createDirectory(directoryUri);
|
|
69
|
+
const serializedContent = await this.serialize();
|
|
70
|
+
const encodedContent = new TextEncoder().encode(serializedContent);
|
|
71
|
+
await fs.writeFile(uri, encodedContent);
|
|
72
|
+
}
|
|
73
|
+
toJSON() {
|
|
74
|
+
return {
|
|
75
|
+
imageManager: this.getImageManager().toJSON(),
|
|
76
|
+
content: this.getContent()
|
|
77
|
+
};
|
|
112
78
|
}
|
|
113
79
|
};
|
|
114
|
-
(function(_DeployError) {
|
|
115
|
-
_DeployError.Code = /* @__PURE__ */ function(Code) {
|
|
116
|
-
Code["DEVICE_ALREADY_DEPLOYED"] = "DEVICE_ALREADY_DEPLOYED";
|
|
117
|
-
Code["LIST_JSON_NOT_AN_ARRAY"] = "LIST_JSON_NOT_AN_ARRAY";
|
|
118
|
-
Code["CATCHED_ERROR"] = "CATCHED_ERROR";
|
|
119
|
-
Code["MAYBE_OPENED_DEVICE_MANAGER_IN_DEVECO_STUDIO"] = "MAYBE_OPENED_DEVICE_MANAGER_IN_DEVECO_STUDIO";
|
|
120
|
-
Code["SYMLINK_SDK_PATH_EXISTS"] = "SYMLINK_SDK_PATH_EXISTS";
|
|
121
|
-
return Code;
|
|
122
|
-
}({});
|
|
123
|
-
})(DeployError || (DeployError = {}));
|
|
124
80
|
|
|
125
81
|
//#endregion
|
|
126
|
-
//#region src/
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
82
|
+
//#region src/configs/config-ini/config-ini.ts
|
|
83
|
+
let ConfigIniFile;
|
|
84
|
+
(function(_ConfigIniFile) {
|
|
85
|
+
function is(value) {
|
|
86
|
+
return value instanceof ConfigIniFileImpl;
|
|
87
|
+
}
|
|
88
|
+
_ConfigIniFile.is = is;
|
|
89
|
+
})(ConfigIniFile || (ConfigIniFile = {}));
|
|
90
|
+
var ConfigIniFileImpl = class extends SerializableFileImpl {
|
|
91
|
+
constructor(device, configIniFilePath, content) {
|
|
92
|
+
super(device.getImageManager(), content);
|
|
93
|
+
this.device = device;
|
|
94
|
+
this.configIniFilePath = configIniFilePath;
|
|
95
|
+
this.content = content;
|
|
96
|
+
}
|
|
97
|
+
getDevice() {
|
|
98
|
+
return this.device;
|
|
99
|
+
}
|
|
100
|
+
static getFileUri(device) {
|
|
101
|
+
const { deployedPath, adapter: { join } } = device.getImageManager().getOptions();
|
|
102
|
+
return join(deployedPath, device.getListsFileItem().getContent().name, "config.ini");
|
|
103
|
+
}
|
|
104
|
+
static async safeReadAndParse(device) {
|
|
105
|
+
const { adapter: { fs } } = device.getImageManager().getOptions();
|
|
106
|
+
try {
|
|
107
|
+
const configIniFileContent = await fs.readFile(this.getFileUri(device)).then((buffer) => buffer.toString(), () => void 0);
|
|
108
|
+
if (!configIniFileContent?.length) return;
|
|
109
|
+
return ini.default.parse(configIniFileContent);
|
|
110
|
+
} catch {}
|
|
111
|
+
}
|
|
112
|
+
getFileUri() {
|
|
113
|
+
return this.configIniFilePath;
|
|
114
|
+
}
|
|
115
|
+
async serialize() {
|
|
116
|
+
return ini.default.stringify(Object.fromEntries(Object.entries(this.getContent()).filter(([key, value]) => {
|
|
117
|
+
return value !== void 0 && key.length > 0;
|
|
118
|
+
})));
|
|
119
|
+
}
|
|
120
|
+
async write() {
|
|
121
|
+
return this.writeToFileSystem(this.getFileUri());
|
|
122
|
+
}
|
|
123
|
+
toJSON() {
|
|
124
|
+
return {
|
|
125
|
+
...super.toJSON(),
|
|
126
|
+
fileUri: this.getFileUri().toJSON()
|
|
127
|
+
};
|
|
133
128
|
}
|
|
134
129
|
};
|
|
135
130
|
|
|
136
131
|
//#endregion
|
|
137
|
-
//#region src/
|
|
138
|
-
let
|
|
139
|
-
(function(
|
|
132
|
+
//#region src/configs/emulator/emulator-basic-item.ts
|
|
133
|
+
let EmulatorBasicItem;
|
|
134
|
+
(function(_EmulatorBasicItem) {
|
|
140
135
|
function is(value) {
|
|
141
|
-
return
|
|
136
|
+
return value instanceof EmulatorBasicItemImpl;
|
|
142
137
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
//#endregion
|
|
147
|
-
//#region src/types.ts
|
|
148
|
-
function isPhoneAllSnakecaseDeviceType(value) {
|
|
149
|
-
return value === "phone" || value === "triplefold" || value === "widefold" || value === "foldable";
|
|
150
|
-
}
|
|
151
|
-
function isPCAllSnakecaseDeviceType(value) {
|
|
152
|
-
return value === "2in1_foldable" || value === "2in1";
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
//#endregion
|
|
156
|
-
//#region src/screens/base-screen.ts
|
|
157
|
-
var BaseScreenImpl = class {
|
|
158
|
-
constructor(options) {
|
|
159
|
-
this.options = options;
|
|
138
|
+
_EmulatorBasicItem.is = is;
|
|
139
|
+
function isDeviceType(value) {
|
|
140
|
+
return value === "2in1" || value === "tablet" || value === "tv" || value === "wearable" || value === "phone";
|
|
160
141
|
}
|
|
161
|
-
|
|
162
|
-
|
|
142
|
+
_EmulatorBasicItem.isDeviceType = isDeviceType;
|
|
143
|
+
function isContent(value) {
|
|
144
|
+
return typeof value === "object" && value !== null && "name" in value && "deviceType" in value && isDeviceType(value.deviceType);
|
|
163
145
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
146
|
+
_EmulatorBasicItem.isContent = isContent;
|
|
147
|
+
})(EmulatorBasicItem || (EmulatorBasicItem = {}));
|
|
148
|
+
var EmulatorBasicItemImpl = class extends SerializableContentImpl {
|
|
149
|
+
constructor(emulatorFile, content) {
|
|
150
|
+
super(emulatorFile.getImageManager(), content);
|
|
151
|
+
this.emulatorFile = emulatorFile;
|
|
152
|
+
this.content = content;
|
|
167
153
|
}
|
|
168
|
-
|
|
169
|
-
return this.
|
|
154
|
+
getEmulatorFile() {
|
|
155
|
+
return this.emulatorFile;
|
|
170
156
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
//#endregion
|
|
160
|
+
//#region src/configs/emulator/emulator-fold-item.ts
|
|
161
|
+
let EmulatorFoldItem;
|
|
162
|
+
(function(_EmulatorFoldItem) {
|
|
163
|
+
function is(value) {
|
|
164
|
+
return value instanceof EmulatorFoldItemImpl;
|
|
174
165
|
}
|
|
175
|
-
|
|
176
|
-
|
|
166
|
+
_EmulatorFoldItem.is = is;
|
|
167
|
+
function isDeviceType(value) {
|
|
168
|
+
return value === "foldable" || value === "2in1_foldable" || value === "triplefold" || value === "widefold";
|
|
177
169
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
return
|
|
170
|
+
_EmulatorFoldItem.isDeviceType = isDeviceType;
|
|
171
|
+
function isContent(value) {
|
|
172
|
+
return typeof value === "object" && value !== null && "name" in value && "deviceType" in value && isDeviceType(value.deviceType);
|
|
181
173
|
}
|
|
182
|
-
|
|
183
|
-
|
|
174
|
+
_EmulatorFoldItem.isContent = isContent;
|
|
175
|
+
})(EmulatorFoldItem || (EmulatorFoldItem = {}));
|
|
176
|
+
var EmulatorFoldItemImpl = class extends SerializableContentImpl {
|
|
177
|
+
constructor(emulatorFile, content) {
|
|
178
|
+
super(emulatorFile.getImageManager(), content);
|
|
179
|
+
this.emulatorFile = emulatorFile;
|
|
180
|
+
this.content = content;
|
|
181
|
+
}
|
|
182
|
+
getEmulatorFile() {
|
|
183
|
+
return this.emulatorFile;
|
|
184
184
|
}
|
|
185
185
|
};
|
|
186
186
|
|
|
187
187
|
//#endregion
|
|
188
|
-
//#region src/
|
|
189
|
-
let
|
|
190
|
-
(function(
|
|
188
|
+
//#region src/configs/emulator/emulator-triplefold-item.ts
|
|
189
|
+
let EmulatorTripleFoldItem;
|
|
190
|
+
(function(_EmulatorTripleFoldItem) {
|
|
191
191
|
function is(value) {
|
|
192
|
-
return value instanceof
|
|
192
|
+
return value instanceof EmulatorTripleFoldItemImpl;
|
|
193
193
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
constructor(options, screen) {
|
|
198
|
-
super(options);
|
|
199
|
-
this.options = options;
|
|
200
|
-
this.screen = screen;
|
|
194
|
+
_EmulatorTripleFoldItem.is = is;
|
|
195
|
+
function isDeviceType(value) {
|
|
196
|
+
return value === "triplefold";
|
|
201
197
|
}
|
|
202
|
-
|
|
203
|
-
|
|
198
|
+
_EmulatorTripleFoldItem.isDeviceType = isDeviceType;
|
|
199
|
+
function isContent(value) {
|
|
200
|
+
return typeof value === "object" && value !== null && "name" in value && "deviceType" in value && isDeviceType(value.deviceType);
|
|
201
|
+
}
|
|
202
|
+
_EmulatorTripleFoldItem.isContent = isContent;
|
|
203
|
+
})(EmulatorTripleFoldItem || (EmulatorTripleFoldItem = {}));
|
|
204
|
+
var EmulatorTripleFoldItemImpl = class extends SerializableContentImpl {
|
|
205
|
+
constructor(emulatorFile, content) {
|
|
206
|
+
super(emulatorFile.getImageManager(), content);
|
|
207
|
+
this.emulatorFile = emulatorFile;
|
|
208
|
+
this.content = content;
|
|
209
|
+
}
|
|
210
|
+
getEmulatorFile() {
|
|
211
|
+
return this.emulatorFile;
|
|
204
212
|
}
|
|
205
213
|
};
|
|
206
|
-
function createCoverScreen(options, screen) {
|
|
207
|
-
return new CoverScreenImpl(options, screen);
|
|
208
|
-
}
|
|
209
214
|
|
|
210
215
|
//#endregion
|
|
211
|
-
//#region src/
|
|
212
|
-
let
|
|
213
|
-
(function(
|
|
216
|
+
//#region src/configs/emulator/group-item.ts
|
|
217
|
+
let EmulatorGroupItem;
|
|
218
|
+
(function(_EmulatorGroupItem) {
|
|
214
219
|
function is(value) {
|
|
215
|
-
return value instanceof
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
220
|
+
return value instanceof EmulatorGroupItemImpl;
|
|
221
|
+
}
|
|
222
|
+
_EmulatorGroupItem.is = is;
|
|
223
|
+
function isContent(value) {
|
|
224
|
+
return typeof value === "object" && value !== null && "name" in value && "deviceType" in value && "api" in value && "children" in value && Array.isArray(value.children) && value.children.every(EmulatorFile.isItemContent);
|
|
225
|
+
}
|
|
226
|
+
_EmulatorGroupItem.isContent = isContent;
|
|
227
|
+
})(EmulatorGroupItem || (EmulatorGroupItem = {}));
|
|
228
|
+
var EmulatorGroupItemImpl = class extends SerializableContentImpl {
|
|
229
|
+
constructor(emulatorFile, content) {
|
|
230
|
+
super(emulatorFile.getImageManager(), content);
|
|
231
|
+
this.emulatorFile = emulatorFile;
|
|
232
|
+
this.content = content;
|
|
233
|
+
}
|
|
234
|
+
getEmulatorFile() {
|
|
235
|
+
return this.emulatorFile;
|
|
236
|
+
}
|
|
237
|
+
getChildren() {
|
|
238
|
+
return this.getContent().children.map((children) => {
|
|
239
|
+
if (EmulatorBasicItem.isContent(children)) return new EmulatorBasicItemImpl(this.emulatorFile, children);
|
|
240
|
+
else if (EmulatorFoldItem.isContent(children)) return new EmulatorFoldItemImpl(this.emulatorFile, children);
|
|
241
|
+
else if (EmulatorTripleFoldItem.isContent(children)) return new EmulatorTripleFoldItemImpl(this.emulatorFile, children);
|
|
242
|
+
}).filter(Boolean);
|
|
227
243
|
}
|
|
228
244
|
};
|
|
229
|
-
function createDoubleScreen(options, screen) {
|
|
230
|
-
return new DoubleScreenImpl(options, screen);
|
|
231
|
-
}
|
|
232
245
|
|
|
233
246
|
//#endregion
|
|
234
|
-
//#region src/
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
247
|
+
//#region src/configs/emulator/emulator.ts
|
|
248
|
+
let EmulatorFile;
|
|
249
|
+
(function(_EmulatorFile) {
|
|
250
|
+
function is(value) {
|
|
251
|
+
return value instanceof EmulatorFileImpl;
|
|
252
|
+
}
|
|
253
|
+
_EmulatorFile.is = is;
|
|
254
|
+
function isItemContent(value) {
|
|
255
|
+
return typeof value === "object" && value !== null && (EmulatorBasicItem.isContent(value) || EmulatorFoldItem.isContent(value) || EmulatorTripleFoldItem.isContent(value));
|
|
256
|
+
}
|
|
257
|
+
_EmulatorFile.isItemContent = isItemContent;
|
|
258
|
+
function isContentItem(value) {
|
|
259
|
+
return typeof value === "object" && value !== null && (EmulatorGroupItem.isContent(value) || EmulatorFile.isItemContent(value));
|
|
260
|
+
}
|
|
261
|
+
_EmulatorFile.isContentItem = isContentItem;
|
|
262
|
+
})(EmulatorFile || (EmulatorFile = {}));
|
|
263
|
+
var EmulatorFileImpl = class extends SerializableFileImpl {
|
|
264
|
+
async serialize() {
|
|
265
|
+
return JSON.stringify(this.getContent(), null, 2);
|
|
266
|
+
}
|
|
267
|
+
async write() {
|
|
268
|
+
const { emulatorPath, adapter: { join } } = this.getImageManager().getOptions();
|
|
269
|
+
return this.writeToFileSystem(join(emulatorPath, "emulator.json"));
|
|
270
|
+
}
|
|
271
|
+
getItems() {
|
|
272
|
+
return this.getContent().map((item) => {
|
|
273
|
+
if (EmulatorGroupItem.isContent(item)) return new EmulatorGroupItemImpl(this, item);
|
|
274
|
+
else if (EmulatorFile.isItemContent(item)) {
|
|
275
|
+
if (EmulatorBasicItem.isContent(item)) return new EmulatorBasicItemImpl(this, item);
|
|
276
|
+
else if (EmulatorFoldItem.isContent(item)) return new EmulatorFoldItemImpl(this, item);
|
|
277
|
+
else if (EmulatorTripleFoldItem.isContent(item)) return new EmulatorTripleFoldItemImpl(this, item);
|
|
278
|
+
}
|
|
279
|
+
}).filter(Boolean);
|
|
280
|
+
}
|
|
281
|
+
findDeviceItems(options = {}) {
|
|
282
|
+
const items = [];
|
|
283
|
+
const pushDeviceItem = (item) => {
|
|
284
|
+
if (EmulatorBasicItem.is(item)) {
|
|
285
|
+
if (options.apiVersion && item.getContent().api === options.apiVersion && options.deviceType && item.getContent().deviceType === options.deviceType) items.push(item);
|
|
286
|
+
} else if (EmulatorFoldItem.is(item)) {
|
|
287
|
+
if (options.apiVersion && item.getContent().api === options.apiVersion && options.deviceType && item.getContent().deviceType === options.deviceType) items.push(item);
|
|
288
|
+
} else if (EmulatorTripleFoldItem.is(item)) {
|
|
289
|
+
if (options.apiVersion && item.getContent().api === options.apiVersion && options.deviceType && item.getContent().deviceType === options.deviceType) items.push(item);
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
for (const item of this.getItems()) if (EmulatorGroupItem.is(item)) for (const child of item.getChildren()) pushDeviceItem(child);
|
|
293
|
+
else pushDeviceItem(item);
|
|
294
|
+
return items;
|
|
239
295
|
}
|
|
240
|
-
|
|
241
|
-
return this.
|
|
296
|
+
findDeviceItem(options = {}) {
|
|
297
|
+
return this.findDeviceItems(options)[0];
|
|
298
|
+
}
|
|
299
|
+
findItems(options = {}) {
|
|
300
|
+
return this.getItems().filter((item) => {
|
|
301
|
+
if (options.apiVersion && item.getContent().api === options.apiVersion && options.fullDeviceType && item.getContent().deviceType === options.fullDeviceType) return true;
|
|
302
|
+
return false;
|
|
303
|
+
});
|
|
242
304
|
}
|
|
243
|
-
|
|
244
|
-
return this.
|
|
305
|
+
findItem(options = {}) {
|
|
306
|
+
return this.findItems(options)[0];
|
|
245
307
|
}
|
|
246
308
|
toJSON() {
|
|
247
|
-
return {
|
|
309
|
+
return {
|
|
310
|
+
...super.toJSON(),
|
|
311
|
+
items: this.getItems().map((item) => item.toJSON())
|
|
312
|
+
};
|
|
248
313
|
}
|
|
249
314
|
};
|
|
250
|
-
function createEmulatorPreset(emulatorConfigItem, screenPreset) {
|
|
251
|
-
return new EmulatorPresetImpl(emulatorConfigItem, screenPreset);
|
|
252
|
-
}
|
|
253
315
|
|
|
254
316
|
//#endregion
|
|
255
|
-
//#region src/
|
|
256
|
-
let
|
|
257
|
-
(function(
|
|
317
|
+
//#region src/configs/lists/item.ts
|
|
318
|
+
let ListsFileItem;
|
|
319
|
+
(function(_ListsFileItem) {
|
|
258
320
|
function is(value) {
|
|
259
|
-
return value instanceof
|
|
260
|
-
}
|
|
261
|
-
_OuterScreen.is = is;
|
|
262
|
-
})(OuterScreen || (OuterScreen = {}));
|
|
263
|
-
var OuterScreenImpl = class extends BaseScreenImpl {
|
|
264
|
-
outerDoubleScreen;
|
|
265
|
-
constructor(options, screen) {
|
|
266
|
-
super(options);
|
|
267
|
-
this.options = options;
|
|
268
|
-
this.screen = screen;
|
|
269
|
-
if (options.double) this.outerDoubleScreen = OuterDoubleScreen.is(options.double) ? options.double : createOuterDoubleScreen(options.double, this);
|
|
321
|
+
return value instanceof ListsFileItemImpl;
|
|
270
322
|
}
|
|
271
|
-
|
|
272
|
-
|
|
323
|
+
_ListsFileItem.is = is;
|
|
324
|
+
})(ListsFileItem || (ListsFileItem = {}));
|
|
325
|
+
var ListsFileItemImpl = class extends SerializableContentImpl {
|
|
326
|
+
constructor(listsFile, content) {
|
|
327
|
+
super(listsFile.getImageManager(), content);
|
|
328
|
+
this.listsFile = listsFile;
|
|
329
|
+
this.content = content;
|
|
273
330
|
}
|
|
274
|
-
|
|
275
|
-
return this.
|
|
331
|
+
getListsFile() {
|
|
332
|
+
return this.listsFile;
|
|
276
333
|
}
|
|
277
|
-
|
|
278
|
-
this.
|
|
279
|
-
return this;
|
|
334
|
+
getContent() {
|
|
335
|
+
return this.content;
|
|
280
336
|
}
|
|
281
337
|
toJSON() {
|
|
282
338
|
return {
|
|
283
|
-
|
|
284
|
-
|
|
339
|
+
imageManager: this.getImageManager().toJSON(),
|
|
340
|
+
content: this.getContent(),
|
|
341
|
+
listsFile: this.getListsFile().toJSON()
|
|
285
342
|
};
|
|
286
343
|
}
|
|
287
344
|
};
|
|
288
|
-
function createOuterScreen(options, screen) {
|
|
289
|
-
return new OuterScreenImpl(options, screen);
|
|
290
|
-
}
|
|
291
345
|
|
|
292
346
|
//#endregion
|
|
293
|
-
//#region src/
|
|
294
|
-
let
|
|
295
|
-
(function(
|
|
347
|
+
//#region src/configs/lists/lists.ts
|
|
348
|
+
let ListsFile;
|
|
349
|
+
(function(_ListsFile) {
|
|
296
350
|
function is(value) {
|
|
297
|
-
return value instanceof
|
|
351
|
+
return value instanceof ListsFileImpl;
|
|
352
|
+
}
|
|
353
|
+
_ListsFile.is = is;
|
|
354
|
+
})(ListsFile || (ListsFile = {}));
|
|
355
|
+
var ListsFileImpl = class extends SerializableFileImpl {
|
|
356
|
+
_isChanged = false;
|
|
357
|
+
getListsFileItems() {
|
|
358
|
+
return this.getContent().map((item) => new ListsFileItemImpl(this, item));
|
|
359
|
+
}
|
|
360
|
+
removeDuplicateListFileItems(listsFileItems) {
|
|
361
|
+
this.content = listsFileItems.filter((item, index, self) => index === self.findIndex((t) => t.uuid === item.uuid)).filter((item, index, self) => index === self.findIndex((t) => t.name === item.name));
|
|
362
|
+
}
|
|
363
|
+
addListsFileItem(listsFileItem) {
|
|
364
|
+
this.content.push(listsFileItem);
|
|
365
|
+
this.removeDuplicateListFileItems(this.content);
|
|
366
|
+
this._isChanged = true;
|
|
367
|
+
return new ListsFileItemImpl(this, listsFileItem);
|
|
368
|
+
}
|
|
369
|
+
get isChanged() {
|
|
370
|
+
return this._isChanged;
|
|
371
|
+
}
|
|
372
|
+
deleteListsFileItem(listsFileItem) {
|
|
373
|
+
const index = this.content.findIndex((item) => item.uuid === listsFileItem.getContent().uuid);
|
|
374
|
+
if (index === -1) return this;
|
|
375
|
+
this.content.splice(index, 1);
|
|
376
|
+
this._isChanged = true;
|
|
377
|
+
return this;
|
|
298
378
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
var OuterDoubleScreenImpl = class extends OuterScreenImpl {
|
|
302
|
-
constructor(options, outerScreen) {
|
|
303
|
-
super(options, outerScreen.getScreen());
|
|
304
|
-
this.options = options;
|
|
305
|
-
this.outerScreen = outerScreen;
|
|
379
|
+
async serialize() {
|
|
380
|
+
return JSON.stringify(this.getContent(), null, 2);
|
|
306
381
|
}
|
|
307
|
-
|
|
308
|
-
|
|
382
|
+
async write() {
|
|
383
|
+
if (!this.isChanged) return;
|
|
384
|
+
await this.writeToFileSystem(this.getImageManager().getListsFilePath());
|
|
385
|
+
this._isChanged = false;
|
|
386
|
+
}
|
|
387
|
+
toJSON() {
|
|
388
|
+
return {
|
|
389
|
+
imageManager: this.getImageManager().toJSON(),
|
|
390
|
+
content: this.getContent(),
|
|
391
|
+
listsFileItems: this.getListsFileItems().map((item) => item.toJSON())
|
|
392
|
+
};
|
|
309
393
|
}
|
|
310
394
|
};
|
|
311
|
-
function createOuterDoubleScreen(options, outerScreen) {
|
|
312
|
-
return new OuterDoubleScreenImpl(options, outerScreen);
|
|
313
|
-
}
|
|
314
395
|
|
|
315
396
|
//#endregion
|
|
316
|
-
//#region src/
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
397
|
+
//#region src/configs/product/item.ts
|
|
398
|
+
let ProductConfigItem;
|
|
399
|
+
(function(_ProductConfigItem) {
|
|
400
|
+
function is(value) {
|
|
401
|
+
return value instanceof ProductConfigItemImpl;
|
|
402
|
+
}
|
|
403
|
+
_ProductConfigItem.is = is;
|
|
404
|
+
})(ProductConfigItem || (ProductConfigItem = {}));
|
|
405
|
+
var ProductConfigItemImpl = class extends SerializableContentImpl {
|
|
406
|
+
constructor(productConfigFile, content, deviceType) {
|
|
407
|
+
super(productConfigFile.getImageManager(), content);
|
|
408
|
+
this.productConfigFile = productConfigFile;
|
|
409
|
+
this.content = content;
|
|
320
410
|
this.deviceType = deviceType;
|
|
321
|
-
this.screenPreset = screenPreset;
|
|
322
411
|
}
|
|
323
|
-
|
|
324
|
-
return this.
|
|
412
|
+
getProductConfigFile() {
|
|
413
|
+
return this.productConfigFile;
|
|
325
414
|
}
|
|
326
415
|
getDeviceType() {
|
|
327
416
|
return this.deviceType;
|
|
328
417
|
}
|
|
329
|
-
|
|
330
|
-
return this.
|
|
418
|
+
async serialize() {
|
|
419
|
+
return JSON.stringify(this.getContent(), null, 2);
|
|
420
|
+
}
|
|
421
|
+
getDevModel() {
|
|
422
|
+
switch (this.getDeviceType()) {
|
|
423
|
+
case "Phone":
|
|
424
|
+
case "2in1": return "PHEMU-FD00";
|
|
425
|
+
case "Foldable": return "PHEMU-FD01";
|
|
426
|
+
case "WideFold": return "PHEMU-FD02";
|
|
427
|
+
case "TripleFold": return "PHEMU-FD06";
|
|
428
|
+
case "2in1 Foldable": return "PCEMU-FD05";
|
|
429
|
+
case "Wearable": return "MCHEMU-AL00CN";
|
|
430
|
+
}
|
|
331
431
|
}
|
|
332
432
|
toJSON() {
|
|
333
433
|
return {
|
|
334
|
-
|
|
335
|
-
|
|
434
|
+
imageManager: this.getImageManager().toJSON(),
|
|
435
|
+
content: this.getContent(),
|
|
436
|
+
devModel: this.getDevModel(),
|
|
437
|
+
deviceType: this.getDeviceType(),
|
|
438
|
+
productConfigFile: this.getProductConfigFile().toJSON()
|
|
336
439
|
};
|
|
337
440
|
}
|
|
338
441
|
};
|
|
339
|
-
function createProductPreset(productConfig, deviceType, screenPreset) {
|
|
340
|
-
return new ProductPresetImpl(productConfig, deviceType, screenPreset);
|
|
341
|
-
}
|
|
342
442
|
|
|
343
443
|
//#endregion
|
|
344
|
-
//#region src/
|
|
345
|
-
let
|
|
346
|
-
(function(
|
|
444
|
+
//#region src/configs/product/product.ts
|
|
445
|
+
let ProductConfigFile;
|
|
446
|
+
(function(_ProductConfigFile) {
|
|
347
447
|
function is(value) {
|
|
348
|
-
return value instanceof
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
})(
|
|
352
|
-
var
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
448
|
+
return value instanceof ProductConfigFileImpl;
|
|
449
|
+
}
|
|
450
|
+
_ProductConfigFile.is = is;
|
|
451
|
+
})(ProductConfigFile || (ProductConfigFile = {}));
|
|
452
|
+
var ProductConfigFileImpl = class extends SerializableFileImpl {
|
|
453
|
+
async serialize() {
|
|
454
|
+
return JSON.stringify(this.getContent(), null, 2);
|
|
455
|
+
}
|
|
456
|
+
async write() {
|
|
457
|
+
const { imageBasePath, adapter: { join } } = this.getImageManager().getOptions();
|
|
458
|
+
return this.writeToFileSystem(join(imageBasePath, "productConfig.json"));
|
|
459
|
+
}
|
|
460
|
+
findProductConfigItems(options = {}) {
|
|
461
|
+
const content = this.getContent();
|
|
462
|
+
const items = [];
|
|
463
|
+
for (const deviceType of Object.keys(content)) {
|
|
464
|
+
if (options.deviceType && deviceType !== options.deviceType) continue;
|
|
465
|
+
for (const item of content[deviceType]) {
|
|
466
|
+
if (options.name && item.name !== options.name) continue;
|
|
467
|
+
items.push(new ProductConfigItemImpl(this, item, deviceType));
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
return items;
|
|
357
471
|
}
|
|
358
|
-
|
|
359
|
-
return this.
|
|
472
|
+
findProductConfigItem(options = {}) {
|
|
473
|
+
return this.findProductConfigItems(options)[0];
|
|
360
474
|
}
|
|
361
475
|
};
|
|
362
|
-
function createSingleScreen(options, screen) {
|
|
363
|
-
return new SingleScreenImpl(options, screen);
|
|
364
|
-
}
|
|
365
476
|
|
|
366
477
|
//#endregion
|
|
367
|
-
//#region src/
|
|
368
|
-
let
|
|
369
|
-
(function(
|
|
478
|
+
//#region src/devices/device.ts
|
|
479
|
+
let Device;
|
|
480
|
+
(function(_Device) {
|
|
370
481
|
function is(value) {
|
|
371
|
-
return value instanceof
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
})(
|
|
375
|
-
var
|
|
376
|
-
outerScreen;
|
|
377
|
-
coverScreen;
|
|
378
|
-
singleScreen;
|
|
379
|
-
doubleScreen;
|
|
482
|
+
return value instanceof DeviceImpl;
|
|
483
|
+
}
|
|
484
|
+
_Device.is = is;
|
|
485
|
+
})(Device || (Device = {}));
|
|
486
|
+
var DeviceImpl = class {
|
|
380
487
|
constructor(options) {
|
|
381
|
-
super(options);
|
|
382
488
|
this.options = options;
|
|
383
|
-
if (options.outer) this.outerScreen = OuterScreen.is(options.outer) ? options.outer : createOuterScreen(options.outer, this);
|
|
384
|
-
if (options.cover) this.coverScreen = CoverScreen.is(options.cover) ? options.cover : createCoverScreen(options.cover, this);
|
|
385
|
-
if (options.single) this.singleScreen = SingleScreen.is(options.single) ? options.single : createSingleScreen(options.single, this);
|
|
386
|
-
if (options.double) this.doubleScreen = DoubleScreen.is(options.double) ? options.double : createDoubleScreen(options.double, this);
|
|
387
489
|
}
|
|
388
490
|
getScreen() {
|
|
389
|
-
return this;
|
|
491
|
+
return this.options.screen;
|
|
390
492
|
}
|
|
391
|
-
|
|
392
|
-
return this.options.
|
|
493
|
+
getListsFile() {
|
|
494
|
+
return this.options.listsFile;
|
|
393
495
|
}
|
|
394
|
-
|
|
395
|
-
return this.options.
|
|
496
|
+
getListsFileItem() {
|
|
497
|
+
return this.options.listFileItem;
|
|
396
498
|
}
|
|
397
|
-
|
|
398
|
-
return this.
|
|
499
|
+
getImageManager() {
|
|
500
|
+
return this.options.imageManager;
|
|
399
501
|
}
|
|
400
|
-
|
|
401
|
-
|
|
502
|
+
_configIniFile;
|
|
503
|
+
setConfigIniFile(configIniFile) {
|
|
504
|
+
this._configIniFile = configIniFile;
|
|
402
505
|
return this;
|
|
403
506
|
}
|
|
404
|
-
|
|
405
|
-
return this.
|
|
507
|
+
getConfigIniFile() {
|
|
508
|
+
return this._configIniFile;
|
|
509
|
+
}
|
|
510
|
+
_namedIniFile;
|
|
511
|
+
getNamedIniFile() {
|
|
512
|
+
return this._namedIniFile;
|
|
406
513
|
}
|
|
407
|
-
|
|
408
|
-
this.
|
|
514
|
+
setNamedIniFile(namedIniFile) {
|
|
515
|
+
this._namedIniFile = namedIniFile;
|
|
409
516
|
return this;
|
|
410
517
|
}
|
|
411
|
-
|
|
412
|
-
|
|
518
|
+
getExecutableUri() {
|
|
519
|
+
const { emulatorPath, adapter: { join, process } } = this.getImageManager().getOptions();
|
|
520
|
+
return join(emulatorPath, process.platform === "win32" ? "Emulator.exe" : "Emulator");
|
|
413
521
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
return this;
|
|
522
|
+
getSnapshotUri() {
|
|
523
|
+
const { deployedPath, adapter: { join } } = this.getImageManager().getOptions();
|
|
524
|
+
return join(deployedPath, this.getListsFileItem().getContent().name, "Snapshot.png");
|
|
417
525
|
}
|
|
418
|
-
|
|
419
|
-
|
|
526
|
+
async getSnapshot() {
|
|
527
|
+
const snapshotUri = this.getSnapshotUri();
|
|
528
|
+
const { adapter: { fs } } = this.getImageManager().getOptions();
|
|
529
|
+
return (0, base64_js.fromByteArray)(await fs.readFile(snapshotUri));
|
|
420
530
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
return this
|
|
531
|
+
getStartCommand() {
|
|
532
|
+
const listFileItemContent = this.getListsFileItem().getContent();
|
|
533
|
+
return [this.getExecutableUri().fsPath, [
|
|
534
|
+
"-hvd",
|
|
535
|
+
listFileItemContent.name,
|
|
536
|
+
"-path",
|
|
537
|
+
this.getImageManager().getOptions().deployedPath.fsPath,
|
|
538
|
+
"-imageRoot",
|
|
539
|
+
this.getImageManager().getOptions().imageBasePath.fsPath
|
|
540
|
+
]];
|
|
541
|
+
}
|
|
542
|
+
async start() {
|
|
543
|
+
const { emulatorPath, adapter: { child_process } } = this.getImageManager().getOptions();
|
|
544
|
+
const [executableUri, args] = this.getStartCommand();
|
|
545
|
+
return child_process.spawn(executableUri, args, {
|
|
546
|
+
cwd: emulatorPath.fsPath,
|
|
547
|
+
stdio: [
|
|
548
|
+
"ignore",
|
|
549
|
+
"pipe",
|
|
550
|
+
"pipe"
|
|
551
|
+
]
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
getStopCommand() {
|
|
555
|
+
const listFileItemContent = this.getListsFileItem().getContent();
|
|
556
|
+
return [this.getExecutableUri().fsPath, ["-stop", listFileItemContent.name]];
|
|
557
|
+
}
|
|
558
|
+
async stop() {
|
|
559
|
+
const { emulatorPath, adapter: { child_process } } = this.getImageManager().getOptions();
|
|
560
|
+
const [executableUri, args] = this.getStopCommand();
|
|
561
|
+
return child_process.spawn(executableUri, args, {
|
|
562
|
+
cwd: emulatorPath.fsPath,
|
|
563
|
+
stdio: [
|
|
564
|
+
"ignore",
|
|
565
|
+
"pipe",
|
|
566
|
+
"pipe"
|
|
567
|
+
]
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
async delete() {
|
|
571
|
+
const { deployedPath, adapter: { join, fs } } = this.getImageManager().getOptions();
|
|
572
|
+
await Promise.allSettled([
|
|
573
|
+
fs.delete(join(deployedPath, this.getListsFileItem().getContent().name), { recursive: true }),
|
|
574
|
+
fs.delete(join(deployedPath, `${this.getListsFileItem().getContent().name}.ini`), { recursive: false }),
|
|
575
|
+
this.getImageManager().readListsFile().then(async (listsFile) => {
|
|
576
|
+
const listsFileItem = listsFile.getListsFileItems().find((item) => {
|
|
577
|
+
return item.getContent().name === this.getListsFileItem().getContent().name;
|
|
578
|
+
});
|
|
579
|
+
if (!listsFileItem) return;
|
|
580
|
+
await listsFile.deleteListsFileItem(listsFileItem).write();
|
|
581
|
+
})
|
|
582
|
+
]);
|
|
583
|
+
}
|
|
584
|
+
async getStorageSize() {
|
|
585
|
+
const { deployedPath, adapter: { join, fs } } = this.getImageManager().getOptions();
|
|
586
|
+
return (await fs.stat(join(deployedPath, this.getListsFileItem().getContent().name))).size;
|
|
587
|
+
}
|
|
588
|
+
_watcher;
|
|
589
|
+
async getWatcher() {
|
|
590
|
+
if (this._watcher && !this._watcher.isDisposed) return this._watcher;
|
|
591
|
+
const { deployedPath, adapter: { fs, join } } = this.getImageManager().getOptions();
|
|
592
|
+
this._watcher = await fs.createWatcher(new vscode_fs.RelativePattern(join(deployedPath, this.getListsFileItem().getContent().name), "**"));
|
|
593
|
+
return this._watcher;
|
|
594
|
+
}
|
|
595
|
+
toJSON() {
|
|
596
|
+
return {
|
|
597
|
+
screen: this.getScreen(),
|
|
598
|
+
listsFile: this.getListsFile().toJSON(),
|
|
599
|
+
listsFileItem: this.getListsFileItem().toJSON(),
|
|
600
|
+
configIniFile: this.getConfigIniFile().toJSON(),
|
|
601
|
+
namedIniFile: this.getNamedIniFile().toJSON(),
|
|
602
|
+
executableUri: this.getExecutableUri().toJSON(),
|
|
603
|
+
snapshotUri: this.getSnapshotUri().toJSON(),
|
|
604
|
+
startCommand: this.getStartCommand(),
|
|
605
|
+
stopCommand: this.getStopCommand()
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
//#endregion
|
|
611
|
+
//#region src/configs/named-ini/named-ini.ts
|
|
612
|
+
let NamedIniFile;
|
|
613
|
+
(function(_NamedIniFile) {
|
|
614
|
+
function is(value) {
|
|
615
|
+
return value instanceof NamedIniFileImpl;
|
|
616
|
+
}
|
|
617
|
+
_NamedIniFile.is = is;
|
|
618
|
+
})(NamedIniFile || (NamedIniFile = {}));
|
|
619
|
+
var NamedIniFileImpl = class extends SerializableFileImpl {
|
|
620
|
+
constructor(device, namedIniFilePath, content) {
|
|
621
|
+
super(device.getImageManager(), content);
|
|
622
|
+
this.device = device;
|
|
623
|
+
this.namedIniFilePath = namedIniFilePath;
|
|
624
|
+
this.content = content;
|
|
625
|
+
}
|
|
626
|
+
getDevice() {
|
|
627
|
+
return this.device;
|
|
628
|
+
}
|
|
629
|
+
static getFileUri(device) {
|
|
630
|
+
const { deployedPath, adapter: { join } } = device.getImageManager().getOptions();
|
|
631
|
+
return join(deployedPath, `${device.getListsFileItem().getContent().name}.ini`);
|
|
632
|
+
}
|
|
633
|
+
getFileUri() {
|
|
634
|
+
return this.namedIniFilePath;
|
|
635
|
+
}
|
|
636
|
+
static async safeReadAndParse(device) {
|
|
637
|
+
try {
|
|
638
|
+
const { adapter: { fs } } = device.getImageManager().getOptions();
|
|
639
|
+
const namedIniFileUri = this.getFileUri(device);
|
|
640
|
+
const namedIniFileContent = await fs.readFile(namedIniFileUri).then((buffer) => buffer.toString(), () => void 0);
|
|
641
|
+
if (!namedIniFileContent?.length) return;
|
|
642
|
+
return ini.default.parse(namedIniFileContent);
|
|
643
|
+
} catch {}
|
|
644
|
+
}
|
|
645
|
+
async serialize() {
|
|
646
|
+
return ini.default.stringify(this.getContent());
|
|
647
|
+
}
|
|
648
|
+
async write() {
|
|
649
|
+
const { deployedPath, adapter: { join } } = this.getImageManager().getOptions();
|
|
650
|
+
return this.writeToFileSystem(join(deployedPath, `${this.getDevice().getListsFileItem().getContent().name}.ini`));
|
|
651
|
+
}
|
|
652
|
+
toJSON() {
|
|
653
|
+
return {
|
|
654
|
+
imageManager: this.getImageManager().toJSON(),
|
|
655
|
+
content: this.getContent(),
|
|
656
|
+
fileUri: this.getFileUri().toJSON()
|
|
657
|
+
};
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
|
|
661
|
+
//#endregion
|
|
662
|
+
//#region src/screens/customize-screen.ts
|
|
663
|
+
let CustomizeScreen;
|
|
664
|
+
(function(_CustomizeScreen) {
|
|
665
|
+
function is(value) {
|
|
666
|
+
return value instanceof CustomizeScreenImpl;
|
|
667
|
+
}
|
|
668
|
+
_CustomizeScreen.is = is;
|
|
669
|
+
})(CustomizeScreen || (CustomizeScreen = {}));
|
|
670
|
+
var CustomizeScreenImpl = class {
|
|
671
|
+
constructor(screenPreset, options) {
|
|
672
|
+
this.screenPreset = screenPreset;
|
|
673
|
+
this.options = options;
|
|
674
|
+
}
|
|
675
|
+
getConfigName() {
|
|
676
|
+
return this.options?.configName ?? "Customize_01";
|
|
677
|
+
}
|
|
678
|
+
getDiagonalSize() {
|
|
679
|
+
return this.options?.diagonalSize ?? 0;
|
|
680
|
+
}
|
|
681
|
+
getResolutionWidth() {
|
|
682
|
+
return this.options?.resolutionWidth ?? 0;
|
|
683
|
+
}
|
|
684
|
+
getResolutionHeight() {
|
|
685
|
+
return this.options?.resolutionHeight ?? 0;
|
|
424
686
|
}
|
|
425
687
|
getDensity() {
|
|
426
|
-
return this.options
|
|
688
|
+
return this.options?.density ?? 0;
|
|
427
689
|
}
|
|
428
|
-
|
|
429
|
-
this.
|
|
430
|
-
|
|
690
|
+
getScreenPreset() {
|
|
691
|
+
return this.screenPreset;
|
|
692
|
+
}
|
|
693
|
+
toJSON() {
|
|
694
|
+
return {
|
|
695
|
+
configName: this.getConfigName(),
|
|
696
|
+
diagonalSize: this.getDiagonalSize(),
|
|
697
|
+
resolutionWidth: this.getResolutionWidth(),
|
|
698
|
+
resolutionHeight: this.getResolutionHeight(),
|
|
699
|
+
density: this.getDensity()
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
|
|
704
|
+
//#endregion
|
|
705
|
+
//#region src/screens/customize-foldable-screen.ts
|
|
706
|
+
let CustomizeFoldableScreen;
|
|
707
|
+
(function(_CustomizeFoldableScreen) {
|
|
708
|
+
function is(value) {
|
|
709
|
+
return value instanceof CustomizeFoldableScreenImpl;
|
|
710
|
+
}
|
|
711
|
+
_CustomizeFoldableScreen.is = is;
|
|
712
|
+
})(CustomizeFoldableScreen || (CustomizeFoldableScreen = {}));
|
|
713
|
+
var CustomizeFoldableScreenImpl = class extends CustomizeScreenImpl {
|
|
714
|
+
constructor(screenPreset, options, foldableOptions) {
|
|
715
|
+
super(screenPreset, options);
|
|
716
|
+
this.screenPreset = screenPreset;
|
|
717
|
+
this.options = options;
|
|
718
|
+
this.foldableOptions = foldableOptions;
|
|
719
|
+
}
|
|
720
|
+
getCoverResolutionWidth() {
|
|
721
|
+
return this.foldableOptions?.coverResolutionWidth ?? 0;
|
|
722
|
+
}
|
|
723
|
+
getCoverResolutionHeight() {
|
|
724
|
+
return this.foldableOptions?.coverResolutionHeight ?? 0;
|
|
725
|
+
}
|
|
726
|
+
getCoverDiagonalSize() {
|
|
727
|
+
return this.foldableOptions?.coverDiagonalSize ?? 0;
|
|
431
728
|
}
|
|
432
729
|
toJSON() {
|
|
433
730
|
return {
|
|
434
731
|
...super.toJSON(),
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
outer: this.outerScreen?.toJSON(),
|
|
439
|
-
cover: this.coverScreen?.toJSON(),
|
|
440
|
-
single: this.singleScreen?.toJSON()
|
|
732
|
+
coverResolutionWidth: this.getCoverResolutionWidth(),
|
|
733
|
+
coverResolutionHeight: this.getCoverResolutionHeight(),
|
|
734
|
+
coverDiagonalSize: this.getCoverDiagonalSize()
|
|
441
735
|
};
|
|
442
736
|
}
|
|
443
737
|
};
|
|
444
|
-
function createScreen(options) {
|
|
445
|
-
return new ScreenImpl(options);
|
|
446
|
-
}
|
|
447
738
|
|
|
448
739
|
//#endregion
|
|
449
740
|
//#region src/screens/screen-preset.ts
|
|
450
741
|
let ScreenPreset;
|
|
451
742
|
(function(_ScreenPreset) {
|
|
452
|
-
let ScreenOptions;
|
|
453
|
-
(function(_ScreenOptions) {
|
|
454
|
-
function is(value) {
|
|
455
|
-
return typeof value === "object" && value !== null && "screen" in value && Screen.is(value.screen);
|
|
456
|
-
}
|
|
457
|
-
_ScreenOptions.is = is;
|
|
458
|
-
})(ScreenOptions || (ScreenOptions = _ScreenPreset.ScreenOptions || (_ScreenPreset.ScreenOptions = {})));
|
|
459
|
-
let ProductOptions;
|
|
460
|
-
(function(_ProductOptions) {
|
|
461
|
-
function is(value) {
|
|
462
|
-
return typeof value === "object" && value !== null && "image" in value && "productConfig" in value && ProductConfigItem.is(value.productConfig);
|
|
463
|
-
}
|
|
464
|
-
_ProductOptions.is = is;
|
|
465
|
-
})(ProductOptions || (ProductOptions = _ScreenPreset.ProductOptions || (_ScreenPreset.ProductOptions = {})));
|
|
466
|
-
let EmulatorOptions;
|
|
467
|
-
(function(_EmulatorOptions) {
|
|
468
|
-
function is(value) {
|
|
469
|
-
return typeof value === "object" && value !== null && "image" in value && "emulatorConfig" in value;
|
|
470
|
-
}
|
|
471
|
-
_EmulatorOptions.is = is;
|
|
472
|
-
})(EmulatorOptions || (EmulatorOptions = _ScreenPreset.EmulatorOptions || (_ScreenPreset.EmulatorOptions = {})));
|
|
473
743
|
function is(value) {
|
|
474
744
|
return value instanceof ScreenPresetImpl;
|
|
475
745
|
}
|
|
476
746
|
_ScreenPreset.is = is;
|
|
477
747
|
})(ScreenPreset || (ScreenPreset = {}));
|
|
478
748
|
var ScreenPresetImpl = class {
|
|
479
|
-
emulatorPreset;
|
|
480
|
-
productPreset;
|
|
481
749
|
constructor(options) {
|
|
482
750
|
this.options = options;
|
|
483
|
-
this._screen = this.getScreen();
|
|
484
|
-
this.setEmulatorPreset();
|
|
485
|
-
this.setProductPreset();
|
|
486
751
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
if (ScreenPreset.ScreenOptions.is(this.options)) return this.options.screen;
|
|
490
|
-
if (this._screen) return this._screen;
|
|
491
|
-
if (ScreenPreset.ProductOptions.is(this.options)) {
|
|
492
|
-
this._screen = createScreen({
|
|
493
|
-
width: Number(this.options.productConfig.screenWidth),
|
|
494
|
-
height: Number(this.options.productConfig.screenHeight),
|
|
495
|
-
diagonal: Number(this.options.productConfig.screenDiagonal),
|
|
496
|
-
density: Number(this.options.productConfig.screenDensity),
|
|
497
|
-
apiVersion: Number.parseInt(this.options.image.getApiVersion()),
|
|
498
|
-
deviceType: this.options.image.getSnakecaseDeviceType()
|
|
499
|
-
});
|
|
500
|
-
if (this.options.productConfig.outerScreenWidth && this.options.productConfig.outerScreenHeight && this.options.productConfig.outerScreenDiagonal) this._screen.setOuterScreen(createOuterScreen({
|
|
501
|
-
width: Number(this.options.productConfig.outerScreenWidth),
|
|
502
|
-
height: Number(this.options.productConfig.outerScreenHeight),
|
|
503
|
-
diagonal: Number(this.options.productConfig.outerScreenDiagonal)
|
|
504
|
-
}, this._screen));
|
|
505
|
-
if (this.options.productConfig.outerDoubleScreenWidth && this.options.productConfig.outerDoubleScreenHeight && this.options.productConfig.outerDoubleScreenDiagonal) this._screen.getOuterScreen()?.setOuterDoubleScreen(createOuterDoubleScreen({
|
|
506
|
-
width: Number(this.options.productConfig.outerDoubleScreenWidth),
|
|
507
|
-
height: Number(this.options.productConfig.outerDoubleScreenHeight),
|
|
508
|
-
diagonal: Number(this.options.productConfig.outerDoubleScreenDiagonal)
|
|
509
|
-
}, this._screen.getOuterScreen()));
|
|
510
|
-
return this._screen;
|
|
511
|
-
}
|
|
512
|
-
if (ScreenPreset.EmulatorOptions.is(this.options)) {
|
|
513
|
-
this._screen = createScreen({
|
|
514
|
-
width: this.options.emulatorConfig.resolutionWidth,
|
|
515
|
-
height: this.options.emulatorConfig.resolutionHeight,
|
|
516
|
-
diagonal: this.options.emulatorConfig.diagonalSize,
|
|
517
|
-
density: this.options.emulatorConfig.density,
|
|
518
|
-
apiVersion: Number.parseInt(this.options.image.getApiVersion()),
|
|
519
|
-
deviceType: this.options.image.getSnakecaseDeviceType()
|
|
520
|
-
});
|
|
521
|
-
if (this.options.emulatorConfig.coverResolutionWidth && this.options.emulatorConfig.coverResolutionHeight && this.options.emulatorConfig.coverDiagonalSize) this._screen.setCoverScreen(createCoverScreen({
|
|
522
|
-
width: this.options.emulatorConfig.coverResolutionWidth,
|
|
523
|
-
height: this.options.emulatorConfig.coverResolutionHeight,
|
|
524
|
-
diagonal: this.options.emulatorConfig.coverDiagonalSize
|
|
525
|
-
}, this._screen));
|
|
526
|
-
if (PhoneAllEmulatorConfigItem.is(this.options.emulatorConfig)) {
|
|
527
|
-
if (this.options.emulatorConfig.singleResolutionWidth && this.options.emulatorConfig.singleResolutionHeight && this.options.emulatorConfig.singleDiagonalSize) this._screen.setSingleScreen(createSingleScreen({
|
|
528
|
-
width: this.options.emulatorConfig.singleResolutionWidth,
|
|
529
|
-
height: this.options.emulatorConfig.singleResolutionHeight,
|
|
530
|
-
diagonal: this.options.emulatorConfig.singleDiagonalSize
|
|
531
|
-
}, this._screen));
|
|
532
|
-
if (this.options.emulatorConfig.doubleResolutionWidth && this.options.emulatorConfig.doubleResolutionHeight && this.options.emulatorConfig.doubleDiagonalSize) this._screen.setDoubleScreen(createDoubleScreen({
|
|
533
|
-
width: this.options.emulatorConfig.doubleResolutionWidth,
|
|
534
|
-
height: this.options.emulatorConfig.doubleResolutionHeight,
|
|
535
|
-
diagonal: this.options.emulatorConfig.doubleDiagonalSize
|
|
536
|
-
}, this._screen));
|
|
537
|
-
}
|
|
538
|
-
return this._screen;
|
|
539
|
-
}
|
|
540
|
-
throw new Error("Invalid createScreenPreset options.");
|
|
541
|
-
}
|
|
542
|
-
getProductConfigItemsByScreenOptions() {
|
|
543
|
-
if (!ScreenPreset.ScreenOptions.is(this.options)) return;
|
|
544
|
-
for (const [pascalCaseDeviceType, productConfigItem] of Object.entries(this.options.productConfig ?? {})) if (pascalCaseDeviceType === "2in1" && this.getScreen().getSnakecaseDeviceType() === "2in1") return [productConfigItem, pascalCaseDeviceType];
|
|
545
|
-
else if (pascalCaseDeviceType === "2in1 Foldable" && this.getScreen().getSnakecaseDeviceType() === "2in1_foldable") return [productConfigItem, pascalCaseDeviceType];
|
|
546
|
-
else if (pascalCaseDeviceType === "Foldable" && this.getScreen().getSnakecaseDeviceType() === "foldable") return [productConfigItem, pascalCaseDeviceType];
|
|
547
|
-
else if (pascalCaseDeviceType === "Phone" && this.getScreen().getSnakecaseDeviceType() === "phone") return [productConfigItem, pascalCaseDeviceType];
|
|
548
|
-
else if (pascalCaseDeviceType === "TV" && this.getScreen().getSnakecaseDeviceType() === "tv") return [productConfigItem, pascalCaseDeviceType];
|
|
549
|
-
else if (pascalCaseDeviceType === "Tablet" && this.getScreen().getSnakecaseDeviceType() === "tablet") return [productConfigItem, pascalCaseDeviceType];
|
|
550
|
-
else if (pascalCaseDeviceType === "TripleFold" && this.getScreen().getSnakecaseDeviceType() === "triplefold") return [productConfigItem, pascalCaseDeviceType];
|
|
551
|
-
else if (pascalCaseDeviceType === "Wearable" && this.getScreen().getSnakecaseDeviceType() === "wearable") return [productConfigItem, pascalCaseDeviceType];
|
|
552
|
-
else if (pascalCaseDeviceType === "WideFold" && this.getScreen().getSnakecaseDeviceType() === "widefold") return [productConfigItem, pascalCaseDeviceType];
|
|
553
|
-
else if (pascalCaseDeviceType.toLowerCase() === this.getScreen().getSnakecaseDeviceType().toLowerCase()) return [productConfigItem, pascalCaseDeviceType];
|
|
554
|
-
}
|
|
555
|
-
setProductPreset() {
|
|
556
|
-
if (ScreenPreset.ScreenOptions.is(this.options)) {
|
|
557
|
-
const [productConfigItems = [], pascalCaseDeviceType] = this.getProductConfigItemsByScreenOptions() ?? [];
|
|
558
|
-
if (!pascalCaseDeviceType || !productConfigItems.length) return;
|
|
559
|
-
for (const productConfigItem of productConfigItems) {
|
|
560
|
-
if (this.getScreen().getWidth() !== Number(productConfigItem.screenWidth) || this.getScreen().getHeight() !== Number(productConfigItem.screenHeight) || this.getScreen().getDiagonal() !== Number(productConfigItem.screenDiagonal) || this.getScreen().getDensity() !== Number(productConfigItem.screenDensity)) continue;
|
|
561
|
-
if (productConfigItem.outerScreenWidth && productConfigItem.outerScreenHeight && productConfigItem.outerScreenDiagonal) {
|
|
562
|
-
const outerScreen = this.getScreen().getOuterScreen();
|
|
563
|
-
if (!outerScreen) continue;
|
|
564
|
-
if (outerScreen.getWidth() !== Number(productConfigItem.outerScreenWidth) || outerScreen.getHeight() !== Number(productConfigItem.outerScreenHeight) || outerScreen.getDiagonal() !== Number(productConfigItem.outerScreenDiagonal)) continue;
|
|
565
|
-
}
|
|
566
|
-
if (productConfigItem.outerDoubleScreenWidth && productConfigItem.outerDoubleScreenHeight && productConfigItem.outerDoubleScreenDiagonal) {
|
|
567
|
-
const outerDoubleScreen = this.getScreen().getOuterScreen()?.getOuterDoubleScreen();
|
|
568
|
-
if (!outerDoubleScreen) continue;
|
|
569
|
-
if (outerDoubleScreen.getWidth() !== Number(productConfigItem.outerDoubleScreenWidth) || outerDoubleScreen.getHeight() !== Number(productConfigItem.outerDoubleScreenHeight) || outerDoubleScreen.getDiagonal() !== Number(productConfigItem.outerDoubleScreenDiagonal)) continue;
|
|
570
|
-
}
|
|
571
|
-
this.productPreset = createProductPreset(productConfigItem, pascalCaseDeviceType, this);
|
|
572
|
-
return;
|
|
573
|
-
}
|
|
574
|
-
} else if (ScreenPreset.ProductOptions.is(this.options)) this.productPreset = createProductPreset(this.options.productConfig, this.options.pascalCaseDeviceType, this);
|
|
575
|
-
else if (ScreenPreset.EmulatorOptions.is(this.options)) this.emulatorPreset = createEmulatorPreset(this.options.emulatorConfig, this);
|
|
576
|
-
}
|
|
577
|
-
setEmulatorPreset() {
|
|
578
|
-
if (ScreenPreset.ScreenOptions.is(this.options)) {
|
|
579
|
-
if (!this.options.emulatorConfig) return;
|
|
580
|
-
for (const parentConfigItem of this.options.emulatorConfig) {
|
|
581
|
-
if (parentConfigItem.api !== this.options.screen.getApiVersion()) continue;
|
|
582
|
-
if (ParentEmulatorConfigItem.is(parentConfigItem) && parentConfigItem.deviceType === this.options.screen.getSnakecaseDeviceType()) {
|
|
583
|
-
this.emulatorPreset = createEmulatorPreset(parentConfigItem, this);
|
|
584
|
-
return;
|
|
585
|
-
}
|
|
586
|
-
if (GroupPhoneAllEmulatorConfigItem.is(parentConfigItem) && isPhoneAllSnakecaseDeviceType(this.options.screen.getSnakecaseDeviceType())) {
|
|
587
|
-
for (const childrenConfigItem of parentConfigItem.children) if (PhoneAllEmulatorConfigItem.is(childrenConfigItem) && childrenConfigItem.deviceType === this.options.screen.getSnakecaseDeviceType()) {
|
|
588
|
-
this.emulatorPreset = createEmulatorPreset(childrenConfigItem, this);
|
|
589
|
-
return;
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
if (GroupPCAllEmulatorConfigItem.is(parentConfigItem) && isPCAllSnakecaseDeviceType(this.options.screen.getSnakecaseDeviceType())) {
|
|
593
|
-
for (const childrenConfigItem of parentConfigItem.children) if (PCAllEmulatorConfigItem.is(childrenConfigItem) && childrenConfigItem.deviceType === this.options.screen.getSnakecaseDeviceType()) {
|
|
594
|
-
this.emulatorPreset = createEmulatorPreset(childrenConfigItem, this);
|
|
595
|
-
return;
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
} else if (ScreenPreset.EmulatorOptions.is(this.options)) this.emulatorPreset = createEmulatorPreset(this.options.emulatorConfig, this);
|
|
752
|
+
getEmulatorDeviceItem() {
|
|
753
|
+
return this.options.emulatorDeviceItem;
|
|
600
754
|
}
|
|
601
|
-
|
|
602
|
-
return this.
|
|
755
|
+
getProductConfigItem() {
|
|
756
|
+
return this.options.productConfigItem;
|
|
603
757
|
}
|
|
604
|
-
|
|
605
|
-
|
|
758
|
+
_customizeScreen;
|
|
759
|
+
getCustomizeScreenConfig() {
|
|
760
|
+
if (this._customizeScreen) return this._customizeScreen;
|
|
761
|
+
if (this.getEmulatorDeviceItem().getContent().deviceType === "foldable" && this.options.productConfigItem.getContent().name === "Customize" && "customizeScreen" in this.options && "customizeFoldableScreen" in this.options) this._customizeScreen = new CustomizeFoldableScreenImpl(this, this.options.customizeScreen, this.options.customizeFoldableScreen);
|
|
762
|
+
else if (this.options.productConfigItem.getContent().name === "Customize" && "customizeScreen" in this.options) this._customizeScreen = new CustomizeScreenImpl(this, this.options.customizeScreen);
|
|
763
|
+
return this._customizeScreen;
|
|
606
764
|
}
|
|
607
765
|
toJSON() {
|
|
608
766
|
return {
|
|
609
|
-
|
|
610
|
-
|
|
767
|
+
customizeScreenConfig: this.getCustomizeScreenConfig()?.toJSON(),
|
|
768
|
+
emulatorDeviceItem: this.getEmulatorDeviceItem().toJSON(),
|
|
769
|
+
productConfigItem: this.getProductConfigItem().toJSON()
|
|
611
770
|
};
|
|
612
771
|
}
|
|
613
772
|
};
|
|
614
|
-
function createScreenPreset(options) {
|
|
615
|
-
return new ScreenPresetImpl(options);
|
|
616
|
-
}
|
|
617
773
|
|
|
618
774
|
//#endregion
|
|
619
|
-
//#region src/
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
this.options = options;
|
|
625
|
-
this.uuid = image.getImageManager().getOptions().crypto.randomUUID();
|
|
626
|
-
}
|
|
627
|
-
getOptions() {
|
|
628
|
-
return this.options;
|
|
629
|
-
}
|
|
630
|
-
getImage() {
|
|
631
|
-
return this.image;
|
|
632
|
-
}
|
|
633
|
-
getScreen() {
|
|
634
|
-
if (this.options.screen instanceof ScreenPresetImpl) return this.options.screen.getScreen();
|
|
635
|
-
return this.options.screen;
|
|
775
|
+
//#region src/images/base-image.ts
|
|
776
|
+
let BaseImage;
|
|
777
|
+
(function(_BaseImage) {
|
|
778
|
+
function is(value) {
|
|
779
|
+
return value instanceof BaseImageImpl;
|
|
636
780
|
}
|
|
637
|
-
|
|
638
|
-
|
|
781
|
+
_BaseImage.is = is;
|
|
782
|
+
})(BaseImage || (BaseImage = {}));
|
|
783
|
+
var BaseImageImpl = class {
|
|
784
|
+
constructor(options) {
|
|
785
|
+
this.options = options;
|
|
639
786
|
}
|
|
640
|
-
|
|
641
|
-
this.
|
|
642
|
-
return this;
|
|
787
|
+
getImageManager() {
|
|
788
|
+
return this.options.imageManager;
|
|
643
789
|
}
|
|
644
|
-
|
|
645
|
-
return this.
|
|
790
|
+
getRelativePath() {
|
|
791
|
+
return this.options.relativePath;
|
|
646
792
|
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
this.
|
|
650
|
-
return this;
|
|
793
|
+
getFullPath() {
|
|
794
|
+
const { imageBasePath, adapter: { join } } = this.getImageManager().getOptions();
|
|
795
|
+
return join(imageBasePath, this.getRelativePath());
|
|
651
796
|
}
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
this.cachedIni = ini;
|
|
655
|
-
return this;
|
|
797
|
+
getApiVersion() {
|
|
798
|
+
return this.options.apiVersion;
|
|
656
799
|
}
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
"name": this.options.name,
|
|
663
|
-
"apiVersion": this.image.getApiVersion(),
|
|
664
|
-
"cpuNumber": this.options.cpuNumber.toFixed(),
|
|
665
|
-
"diagonalSize": screen.getDiagonal().toFixed(2),
|
|
666
|
-
"resolutionHeight": screen.getHeight().toFixed(),
|
|
667
|
-
"resolutionWidth": screen.getWidth().toFixed(),
|
|
668
|
-
"density": screen.getDensity().toFixed(),
|
|
669
|
-
"memoryRamSize": this.options.memorySize.toFixed(),
|
|
670
|
-
"dataDiskSize": this.options.diskSize.toFixed(),
|
|
671
|
-
"path": path.resolve(deployedPath, this.options.name),
|
|
672
|
-
"type": this.image.getSnakecaseDeviceType(),
|
|
673
|
-
"uuid": this.uuid,
|
|
674
|
-
"version": this.image.getVersion(),
|
|
675
|
-
"imageDir": this.image.getPath().split(",").join(path.sep) + path.sep,
|
|
676
|
-
"showVersion": `${this.image.getTargetOS()} ${this.image.getTargetVersion()}(${this.image.getApiVersion()})`,
|
|
677
|
-
"harmonyos.sdk.path": imageBasePath,
|
|
678
|
-
"harmonyos.config.path": configPath,
|
|
679
|
-
"harmonyos.log.path": logPath,
|
|
680
|
-
"hw.apiName": this.image.getTargetVersion(),
|
|
681
|
-
"abi": this.image.getArch(),
|
|
682
|
-
"harmonyOSVersion": `${this.image.getTargetOS()}-${this.image.getTargetVersion()}`,
|
|
683
|
-
"guestVersion": `${this.image.getTargetOS()} ${this.image.getVersion()}(${this.image.getReleaseType()})`
|
|
684
|
-
};
|
|
685
|
-
if (this.options.screen instanceof ScreenPresetImpl) {
|
|
686
|
-
const productConfig = this.options.screen.getProductPreset()?.getProductConfig();
|
|
687
|
-
if (productConfig?.devModel) list.devModel = productConfig.devModel;
|
|
688
|
-
if (productConfig?.name) list.model = productConfig.name;
|
|
689
|
-
}
|
|
690
|
-
return list;
|
|
691
|
-
}
|
|
692
|
-
buildIni(options = {}) {
|
|
693
|
-
if (this.cachedIni) return this.cachedIni;
|
|
694
|
-
const listConfig = this.buildList();
|
|
695
|
-
const screen = this.getScreen();
|
|
696
|
-
const is2in1Foldable = listConfig.type === "2in1_foldable";
|
|
697
|
-
const screenPreset = this.options.screen instanceof ScreenPresetImpl ? this.options.screen.getProductPreset() : null;
|
|
698
|
-
const productConfig = screenPreset?.getProductConfig();
|
|
699
|
-
const useDualScreen = is2in1Foldable && productConfig?.outerScreenWidth != null && productConfig?.outerScreenHeight != null && productConfig?.outerScreenDiagonal != null;
|
|
700
|
-
const singleDiagonal = useDualScreen ? productConfig.outerScreenDiagonal : screen.getDiagonal().toString();
|
|
701
|
-
const singleHeight = useDualScreen ? productConfig.outerScreenHeight : screen.getHeight().toString();
|
|
702
|
-
const singleWidth = useDualScreen ? productConfig.outerScreenWidth : screen.getWidth().toString();
|
|
703
|
-
const doubleDiagonal = useDualScreen ? productConfig.screenDiagonal : void 0;
|
|
704
|
-
const doubleHeight = useDualScreen ? productConfig.screenHeight : void 0;
|
|
705
|
-
const doubleWidth = useDualScreen ? productConfig.screenWidth : void 0;
|
|
706
|
-
const ini = {
|
|
707
|
-
"name": listConfig.name,
|
|
708
|
-
"deviceType": listConfig.type,
|
|
709
|
-
"deviceModel": listConfig.devModel,
|
|
710
|
-
"productModel": listConfig.model,
|
|
711
|
-
"vendorCountry": options.vendorCountry ?? "CN",
|
|
712
|
-
"uuid": this.uuid,
|
|
713
|
-
"configPath": listConfig["harmonyos.config.path"],
|
|
714
|
-
"logPath": listConfig["harmonyos.log.path"],
|
|
715
|
-
"sdkPath": listConfig["harmonyos.sdk.path"],
|
|
716
|
-
"imageSubPath": listConfig.imageDir,
|
|
717
|
-
"instancePath": listConfig.path,
|
|
718
|
-
"os.osVersion": `${this.image.getTargetOS()} ${this.image.getTargetVersion()}(${this.image.getApiVersion()})`,
|
|
719
|
-
"os.apiVersion": this.image.getApiVersion(),
|
|
720
|
-
"os.softwareVersion": this.image.getVersion(),
|
|
721
|
-
"os.isPublic": options.isPublic ?? true ? "true" : "false",
|
|
722
|
-
"hw.cpu.arch": listConfig.abi,
|
|
723
|
-
"hw.cpu.ncore": listConfig.cpuNumber,
|
|
724
|
-
"hw.lcd.density": screen.getDensity().toFixed(),
|
|
725
|
-
"hw.lcd.single.diagonalSize": singleDiagonal,
|
|
726
|
-
"hw.lcd.single.height": singleHeight,
|
|
727
|
-
"hw.lcd.single.width": singleWidth,
|
|
728
|
-
"hw.lcd.number": useDualScreen ? "2" : "1",
|
|
729
|
-
"hw.ramSize": listConfig.memoryRamSize,
|
|
730
|
-
"hw.dataPartitionSize": listConfig.dataDiskSize,
|
|
731
|
-
"isCustomize": screenPreset ? "false" : "true",
|
|
732
|
-
"hw.hdc.port": "notset",
|
|
733
|
-
...options.overrides
|
|
734
|
-
};
|
|
735
|
-
if (useDualScreen && doubleDiagonal != null && doubleHeight != null && doubleWidth != null) {
|
|
736
|
-
ini["hw.lcd.double.diagonalSize"] = doubleDiagonal;
|
|
737
|
-
ini["hw.lcd.double.height"] = doubleHeight;
|
|
738
|
-
ini["hw.lcd.double.width"] = doubleWidth;
|
|
739
|
-
}
|
|
740
|
-
if (screenPreset && productConfig && !useDualScreen) {
|
|
741
|
-
if (productConfig.outerScreenHeight) ini["hw.phy.height"] = productConfig.outerScreenHeight;
|
|
742
|
-
if (productConfig.outerScreenWidth) ini["hw.phy.width"] = productConfig.outerScreenWidth;
|
|
800
|
+
async isDownloaded() {
|
|
801
|
+
try {
|
|
802
|
+
return (await this.getImageManager().getLocalImages()).some((localImage) => localImage.getFullPath().toString() === this.getFullPath().toString());
|
|
803
|
+
} catch {
|
|
804
|
+
return false;
|
|
743
805
|
}
|
|
744
|
-
return ini;
|
|
745
806
|
}
|
|
746
|
-
|
|
747
|
-
return `${Object.entries(this.buildIni()).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}=${value}`).join("\n")}\n`;
|
|
748
|
-
}
|
|
749
|
-
buildDeviceIni() {
|
|
807
|
+
toJSON() {
|
|
750
808
|
return {
|
|
751
|
-
|
|
752
|
-
|
|
809
|
+
imageType: this.imageType,
|
|
810
|
+
imageManager: this.getImageManager().toJSON(),
|
|
811
|
+
relativePath: this.getRelativePath(),
|
|
812
|
+
fullPath: this.getFullPath().toJSON(),
|
|
813
|
+
apiVersion: this.getApiVersion(),
|
|
814
|
+
fullDeviceType: this.getFullDeviceType()
|
|
753
815
|
};
|
|
754
816
|
}
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
const listConfig = this.buildList();
|
|
764
|
-
if (!fs.existsSync(listsPath)) return fs.writeFileSync(listsPath, JSON.stringify([listConfig], null, 2));
|
|
765
|
-
const lists = JSON.parse(fs.readFileSync(listsPath, "utf-8")) ?? [];
|
|
766
|
-
if (!Array.isArray(lists)) throw new DeployError(DeployError.Code.LIST_JSON_NOT_AN_ARRAY, "Lists is not an array");
|
|
767
|
-
if (lists.find((item) => item.name === listConfig.name)) throw new DeployError(DeployError.Code.DEVICE_ALREADY_DEPLOYED, `Image ${listConfig.name} already deployed in lists.json`);
|
|
768
|
-
lists.push(listConfig);
|
|
769
|
-
fs.mkdirSync(listConfig.path, { recursive: true });
|
|
770
|
-
fs.writeFileSync(path.join(listConfig.path, "config.ini"), this.toIniString());
|
|
771
|
-
fs.writeFileSync(path.join(deployedPath, `${this.options.name}.ini`), this.buildDeviceIniString());
|
|
772
|
-
fs.writeFileSync(listsPath, JSON.stringify(lists, null, 2));
|
|
817
|
+
};
|
|
818
|
+
|
|
819
|
+
//#endregion
|
|
820
|
+
//#region src/images/local-image.ts
|
|
821
|
+
let LocalImage;
|
|
822
|
+
(function(_LocalImage) {
|
|
823
|
+
function is(value) {
|
|
824
|
+
return value instanceof LocalImageImpl;
|
|
773
825
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
826
|
+
_LocalImage.is = is;
|
|
827
|
+
})(LocalImage || (LocalImage = {}));
|
|
828
|
+
var LocalImageImpl = class extends BaseImageImpl {
|
|
829
|
+
imageType = "local";
|
|
830
|
+
constructor(imageManager, sdkPkgFile, infoFile) {
|
|
831
|
+
super({
|
|
832
|
+
imageManager,
|
|
833
|
+
apiVersion: Number.parseInt(sdkPkgFile?.data?.apiVersion ?? "0"),
|
|
834
|
+
relativePath: sdkPkgFile?.data?.path?.split(",").join("/")
|
|
835
|
+
});
|
|
836
|
+
this.imageManager = imageManager;
|
|
837
|
+
this.sdkPkgFile = sdkPkgFile;
|
|
838
|
+
this.infoFile = infoFile;
|
|
839
|
+
}
|
|
840
|
+
getSdkPkgFile() {
|
|
841
|
+
return this.sdkPkgFile;
|
|
842
|
+
}
|
|
843
|
+
getFullDeviceType() {
|
|
844
|
+
const name = this.getSdkPkgFile().data?.displayName?.split("-");
|
|
845
|
+
return name?.[name.length - 1];
|
|
846
|
+
}
|
|
847
|
+
async createDevice(options) {
|
|
848
|
+
const { deployedPath, imageBasePath, configPath, logPath, adapter: { join } } = this.getImageManager().getOptions();
|
|
849
|
+
const screen = new ScreenPresetImpl(options.screen);
|
|
850
|
+
const emulatorDeviceItem = screen.getEmulatorDeviceItem();
|
|
851
|
+
const productConfigItem = screen.getProductConfigItem();
|
|
852
|
+
const listsFile = await this.getImageManager().readListsFile();
|
|
853
|
+
const uuid = crypto.randomUUID();
|
|
854
|
+
const deviceFolderPath = join(deployedPath, options.name);
|
|
855
|
+
const listFileItem = listsFile.addListsFileItem({
|
|
856
|
+
uuid,
|
|
857
|
+
"name": options.name,
|
|
858
|
+
"apiVersion": this.getApiVersion().toString(),
|
|
859
|
+
"cpuNumber": options.cpuNumber.toString(),
|
|
860
|
+
"path": deviceFolderPath.fsPath,
|
|
861
|
+
"memoryRamSize": options.memoryRamSize.toString(),
|
|
862
|
+
"dataDiskSize": options.dataDiskSize.toString(),
|
|
863
|
+
"version": this.getSdkPkgFile().data?.version ?? "",
|
|
864
|
+
"imageDir": this.getRelativePath(),
|
|
865
|
+
"showVersion": this.getSdkPkgFile().data?.guestVersion ?? "",
|
|
866
|
+
"harmonyos.sdk.path": imageBasePath.fsPath,
|
|
867
|
+
"harmonyos.config.path": configPath.fsPath,
|
|
868
|
+
"harmonyos.log.path": logPath.fsPath,
|
|
869
|
+
"hw.apiName": this.getSdkPkgFile().data?.platformVersion ?? "",
|
|
870
|
+
"abi": this.infoFile.abi,
|
|
871
|
+
"harmonyOSVersion": `${this.getSdkPkgFile().data?.guestVersion?.split(" ")[0]}-${this.getSdkPkgFile().data?.platformVersion}`,
|
|
872
|
+
"guestVersion": this.getSdkPkgFile().data?.guestVersion ?? "",
|
|
873
|
+
"diagonalSize": emulatorDeviceItem.getContent().diagonalSize.toString(),
|
|
874
|
+
"density": emulatorDeviceItem.getContent().density.toString(),
|
|
875
|
+
"resolutionWidth": emulatorDeviceItem.getContent().resolutionWidth.toString(),
|
|
876
|
+
"resolutionHeight": emulatorDeviceItem.getContent().resolutionHeight.toString(),
|
|
877
|
+
"coverResolutionWidth": EmulatorFoldItem.is(emulatorDeviceItem) ? emulatorDeviceItem.getContent().coverResolutionWidth.toString() : void 0,
|
|
878
|
+
"coverResolutionHeight": EmulatorFoldItem.is(emulatorDeviceItem) ? emulatorDeviceItem.getContent().coverResolutionHeight.toString() : void 0,
|
|
879
|
+
"coverDiagonalSize": EmulatorFoldItem.is(emulatorDeviceItem) ? emulatorDeviceItem.getContent().coverDiagonalSize.toString() : void 0,
|
|
880
|
+
"type": emulatorDeviceItem.getContent().deviceType,
|
|
881
|
+
"devModel": productConfigItem.getDevModel(),
|
|
882
|
+
"model": productConfigItem.getContent().name
|
|
883
|
+
});
|
|
884
|
+
const device = new DeviceImpl({
|
|
885
|
+
imageManager: this.getImageManager(),
|
|
886
|
+
listsFile,
|
|
887
|
+
listFileItem,
|
|
888
|
+
screen
|
|
889
|
+
});
|
|
890
|
+
const deviceIniFile = new ConfigIniFileImpl(device, ConfigIniFileImpl.getFileUri(device), {
|
|
891
|
+
"name": listFileItem.getContent().name,
|
|
892
|
+
"deviceType": listFileItem.getContent().type,
|
|
893
|
+
"deviceModel": listFileItem.getContent().devModel,
|
|
894
|
+
"productModel": listFileItem.getContent().model,
|
|
895
|
+
"vendorCountry": options.vendorCountry ?? "CN",
|
|
896
|
+
"uuid": listFileItem.getContent().uuid,
|
|
897
|
+
"configPath": listFileItem.getContent()["harmonyos.config.path"],
|
|
898
|
+
"logPath": listFileItem.getContent()["harmonyos.log.path"],
|
|
899
|
+
"sdkPath": listFileItem.getContent()["harmonyos.sdk.path"],
|
|
900
|
+
"imageSubPath": listFileItem.getContent().imageDir,
|
|
901
|
+
"instancePath": listFileItem.getContent().path,
|
|
902
|
+
"os.osVersion": `${this.getSdkPkgFile().data?.guestVersion?.split(" ")[0]} ${this.getSdkPkgFile().data?.platformVersion}(${this.getApiVersion()})`,
|
|
903
|
+
"os.apiVersion": this.getApiVersion().toString(),
|
|
904
|
+
"os.softwareVersion": this.getSdkPkgFile().data?.version ?? "",
|
|
905
|
+
"os.isPublic": options.isPublic ?? true ? "true" : "false",
|
|
906
|
+
"hw.cpu.arch": listFileItem.getContent().abi,
|
|
907
|
+
"hw.cpu.ncore": listFileItem.getContent().cpuNumber,
|
|
908
|
+
"hw.lcd.density": emulatorDeviceItem.getContent().density.toFixed(),
|
|
909
|
+
"hw.lcd.single.diagonalSize": EmulatorTripleFoldItem.is(emulatorDeviceItem) ? emulatorDeviceItem.getContent().singleDiagonalSize.toString() : void 0,
|
|
910
|
+
"hw.lcd.single.height": EmulatorTripleFoldItem.is(emulatorDeviceItem) ? emulatorDeviceItem.getContent().singleResolutionHeight.toString() : void 0,
|
|
911
|
+
"hw.lcd.single.width": EmulatorTripleFoldItem.is(emulatorDeviceItem) ? emulatorDeviceItem.getContent().singleResolutionWidth.toString() : void 0,
|
|
912
|
+
"hw.lcd.double.diagonalSize": EmulatorTripleFoldItem.is(emulatorDeviceItem) ? emulatorDeviceItem.getContent().doubleDiagonalSize.toString() : void 0,
|
|
913
|
+
"hw.lcd.double.height": EmulatorTripleFoldItem.is(emulatorDeviceItem) ? emulatorDeviceItem.getContent().doubleResolutionHeight.toString() : void 0,
|
|
914
|
+
"hw.lcd.double.width": EmulatorTripleFoldItem.is(emulatorDeviceItem) ? emulatorDeviceItem.getContent().doubleResolutionWidth.toString() : void 0,
|
|
915
|
+
"hw.lcd.phy.height": emulatorDeviceItem.getContent().physicalHeight.toString(),
|
|
916
|
+
"hw.lcd.phy.width": emulatorDeviceItem.getContent().physicalWidth.toString(),
|
|
917
|
+
"hw.lcd.number": EmulatorTripleFoldItem.is(emulatorDeviceItem) || EmulatorFoldItem.is(emulatorDeviceItem) ? "2" : "1",
|
|
918
|
+
"hw.ramSize": listFileItem.getContent().memoryRamSize,
|
|
919
|
+
"hw.dataPartitionSize": listFileItem.getContent().dataDiskSize,
|
|
920
|
+
"isCustomize": "true",
|
|
921
|
+
"hw.hdc.port": "notset"
|
|
922
|
+
});
|
|
923
|
+
device.setConfigIniFile(deviceIniFile);
|
|
924
|
+
const namedIniFile = new NamedIniFileImpl(device, NamedIniFileImpl.getFileUri(device), {
|
|
925
|
+
"hvd.ini.encoding": "UTF-8",
|
|
926
|
+
"path": listFileItem.getContent().path
|
|
927
|
+
});
|
|
928
|
+
device.setNamedIniFile(namedIniFile);
|
|
929
|
+
await namedIniFile.write();
|
|
930
|
+
await deviceIniFile.write();
|
|
931
|
+
await listsFile.write();
|
|
932
|
+
return device;
|
|
791
933
|
}
|
|
792
934
|
toJSON() {
|
|
793
935
|
return {
|
|
794
|
-
...
|
|
795
|
-
|
|
796
|
-
ini: this.buildIni()
|
|
936
|
+
...super.toJSON(),
|
|
937
|
+
sdkPkgFile: this.getSdkPkgFile()
|
|
797
938
|
};
|
|
798
939
|
}
|
|
799
940
|
};
|
|
800
|
-
function createDevice(image, options) {
|
|
801
|
-
return new DeviceImpl(image, options);
|
|
802
|
-
}
|
|
803
941
|
|
|
804
942
|
//#endregion
|
|
805
|
-
//#region src/
|
|
806
|
-
var
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
this.
|
|
943
|
+
//#region src/errors/request-error.ts
|
|
944
|
+
var RemoteImageRequestError = class extends Error {
|
|
945
|
+
constructor(message, code, cause) {
|
|
946
|
+
super(message, { cause });
|
|
947
|
+
this.message = message;
|
|
948
|
+
this.code = code;
|
|
949
|
+
this.cause = cause;
|
|
811
950
|
}
|
|
812
|
-
|
|
813
|
-
|
|
951
|
+
};
|
|
952
|
+
|
|
953
|
+
//#endregion
|
|
954
|
+
//#region src/event-emitter.ts
|
|
955
|
+
var EventEmitter = class {
|
|
956
|
+
_listeners = [];
|
|
957
|
+
/**
|
|
958
|
+
* The event listeners can subscribe to.
|
|
959
|
+
*/
|
|
960
|
+
event = (listener, thisArgs, disposables) => {
|
|
961
|
+
this._listeners.push([
|
|
962
|
+
listener,
|
|
963
|
+
thisArgs,
|
|
964
|
+
disposables
|
|
965
|
+
]);
|
|
966
|
+
return { dispose: () => {
|
|
967
|
+
this._listeners = this._listeners.filter((l) => l[0] !== listener && l[1] !== thisArgs && l[2] !== disposables);
|
|
968
|
+
disposables?.forEach((disposable) => disposable.dispose());
|
|
969
|
+
} };
|
|
970
|
+
};
|
|
971
|
+
/**
|
|
972
|
+
* Notify all subscribers of the {@link EventEmitter.event event}. Failure
|
|
973
|
+
* of one or more listener will not fail this function call.
|
|
974
|
+
*
|
|
975
|
+
* @param data The event object.
|
|
976
|
+
*/
|
|
977
|
+
fire(data) {
|
|
978
|
+
this._listeners.forEach((listener) => {
|
|
979
|
+
if (listener[1] !== void 0) listener[1].call(listener[2], data);
|
|
980
|
+
else listener[0](data);
|
|
981
|
+
});
|
|
814
982
|
}
|
|
815
|
-
|
|
816
|
-
|
|
983
|
+
/**
|
|
984
|
+
* Dispose this object and free resources.
|
|
985
|
+
*/
|
|
986
|
+
dispose() {
|
|
987
|
+
this._listeners.forEach((listener) => listener[2]?.forEach((disposable) => disposable.dispose()));
|
|
988
|
+
this._listeners = [];
|
|
817
989
|
}
|
|
818
|
-
|
|
819
|
-
|
|
990
|
+
};
|
|
991
|
+
|
|
992
|
+
//#endregion
|
|
993
|
+
//#region src/image-downloader.ts
|
|
994
|
+
var ImageDownloaderImpl = class {
|
|
995
|
+
constructor(remoteImage, url, abortController = new AbortController()) {
|
|
996
|
+
this.remoteImage = remoteImage;
|
|
820
997
|
this.url = url;
|
|
998
|
+
this.abortController = abortController;
|
|
821
999
|
}
|
|
822
|
-
|
|
823
|
-
|
|
1000
|
+
downloadProgressEmitter = new EventEmitter();
|
|
1001
|
+
extractProgressEmitter = new EventEmitter();
|
|
1002
|
+
checksumProgressEmitter = new EventEmitter();
|
|
1003
|
+
onDownloadProgress = this.downloadProgressEmitter.event;
|
|
1004
|
+
onExtractProgress = this.extractProgressEmitter.event;
|
|
1005
|
+
onChecksumProgress = this.checksumProgressEmitter.event;
|
|
1006
|
+
getRemoteImage() {
|
|
1007
|
+
return this.remoteImage;
|
|
824
1008
|
}
|
|
825
1009
|
getUrl() {
|
|
826
1010
|
return this.url;
|
|
827
1011
|
}
|
|
828
|
-
|
|
829
|
-
const {
|
|
830
|
-
return
|
|
1012
|
+
getCacheUri() {
|
|
1013
|
+
const { cachePath, adapter: { URI, join, basename } } = this.remoteImage.getImageManager().getOptions();
|
|
1014
|
+
return join(cachePath, basename(URI.parse(this.url)));
|
|
831
1015
|
}
|
|
832
|
-
async makeRequest(
|
|
833
|
-
const { fs } = this.
|
|
834
|
-
const
|
|
835
|
-
const transformProgress = this.createProgressTransformer(startByte);
|
|
1016
|
+
async makeRequest(startByte = 0, retried416 = false) {
|
|
1017
|
+
const { adapter: { fs, axios, isAxiosError } } = this.remoteImage.getImageManager().getOptions();
|
|
1018
|
+
const cacheUri = this.getCacheUri();
|
|
836
1019
|
try {
|
|
837
|
-
return await axios.
|
|
1020
|
+
return await axios.get(this.url, {
|
|
838
1021
|
headers: startByte > 0 ? { Range: `bytes=${startByte}-` } : {},
|
|
839
1022
|
responseType: "stream",
|
|
840
1023
|
validateStatus: (status) => status === 200 || status === 206,
|
|
841
|
-
|
|
842
|
-
signal
|
|
1024
|
+
signal: this.abortController.signal
|
|
843
1025
|
});
|
|
844
1026
|
} catch (err) {
|
|
845
|
-
if (err
|
|
846
|
-
if (fs.
|
|
847
|
-
return this.makeRequest(
|
|
1027
|
+
if (isAxiosError(err) && err.response?.status === 416 && !retried416) {
|
|
1028
|
+
if (await fs.exists(cacheUri)) await fs.delete(cacheUri, { recursive: true });
|
|
1029
|
+
return this.makeRequest(startByte, true);
|
|
848
1030
|
}
|
|
849
1031
|
throw err;
|
|
850
1032
|
}
|
|
851
1033
|
}
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
const
|
|
855
|
-
if (
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
const
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
const
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
1034
|
+
/** 获取文件总大小。206 时从 Content-Range 取 total,200 时从 Content-Length 取。 */
|
|
1035
|
+
parseTotalBytes(response) {
|
|
1036
|
+
const contentRange = response.headers["content-range"];
|
|
1037
|
+
if (contentRange) {
|
|
1038
|
+
const match = contentRange.match(/bytes \d+-\d+\/(\d+)/);
|
|
1039
|
+
if (match) return Number.parseInt(match[1], 10);
|
|
1040
|
+
}
|
|
1041
|
+
const contentLength = response.headers["content-length"];
|
|
1042
|
+
if (contentLength) return Number.parseInt(contentLength, 10);
|
|
1043
|
+
return null;
|
|
1044
|
+
}
|
|
1045
|
+
createDownloadProgressTransformer(startByte, totalBytes) {
|
|
1046
|
+
let receivedBytes = startByte;
|
|
1047
|
+
let lastReportedBytes = startByte;
|
|
1048
|
+
let lastReportedProgress = totalBytes != null && totalBytes > 0 ? Math.round(startByte / totalBytes * 1e4) / 100 : 0;
|
|
1049
|
+
let lastReportTime = performance.now();
|
|
1050
|
+
const reportThreshold = 64 * 1024;
|
|
1051
|
+
const report = () => {
|
|
1052
|
+
const now = performance.now();
|
|
1053
|
+
const bytesSinceLastReport = receivedBytes - lastReportedBytes;
|
|
1054
|
+
const timeDeltaSec = (now - lastReportTime) / 1e3;
|
|
1055
|
+
lastReportedBytes = receivedBytes;
|
|
1056
|
+
lastReportTime = now;
|
|
1057
|
+
const progress = totalBytes != null && totalBytes > 0 ? Math.min(100, Math.round(receivedBytes / totalBytes * 1e4) / 100) : 0;
|
|
1058
|
+
const increment = Math.round((progress - lastReportedProgress) * 100) / 100;
|
|
1059
|
+
lastReportedProgress = progress;
|
|
1060
|
+
const speedKBps = timeDeltaSec > 0 && bytesSinceLastReport > 0 ? bytesSinceLastReport / 1024 / timeDeltaSec : 0;
|
|
1061
|
+
const unit = speedKBps >= 1024 ? "MB" : "KB";
|
|
1062
|
+
const network = unit === "MB" ? speedKBps / 1024 : speedKBps;
|
|
1063
|
+
const roundedProgress = Math.round(progress * 100) / 100;
|
|
1064
|
+
const clampedIncrement = Math.max(0, Math.min(100, increment));
|
|
1065
|
+
if (clampedIncrement > 0) this.downloadProgressEmitter.fire({
|
|
1066
|
+
progressType: "download",
|
|
1067
|
+
increment: clampedIncrement,
|
|
1068
|
+
progress: roundedProgress,
|
|
1069
|
+
network: Math.round(network * 100) / 100,
|
|
1070
|
+
unit
|
|
1071
|
+
});
|
|
1072
|
+
};
|
|
1073
|
+
return new TransformStream({
|
|
1074
|
+
transform: (chunk, controller) => {
|
|
1075
|
+
receivedBytes += chunk.length;
|
|
1076
|
+
controller.enqueue(chunk);
|
|
1077
|
+
if (receivedBytes - lastReportedBytes >= reportThreshold) report();
|
|
1078
|
+
},
|
|
1079
|
+
flush: () => {
|
|
1080
|
+
if (receivedBytes !== lastReportedBytes) report();
|
|
1081
|
+
}
|
|
885
1082
|
});
|
|
886
1083
|
}
|
|
887
|
-
async
|
|
888
|
-
const {
|
|
889
|
-
const
|
|
890
|
-
|
|
891
|
-
const
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
stream.pipe(progressStream).pipe(extractStream);
|
|
905
|
-
await extractStream.promise();
|
|
906
|
-
if (symlinkOpenHarmonySdk) {
|
|
907
|
-
const symlinkSdkPath = path.resolve(imageBasePath, "default", "openharmony");
|
|
908
|
-
if (!fs.existsSync(path.dirname(symlinkSdkPath))) fs.mkdirSync(path.dirname(symlinkSdkPath), { recursive: true });
|
|
909
|
-
if (!fs.existsSync(symlinkSdkPath)) fs.symlinkSync(sdkPath, symlinkSdkPath, "dir");
|
|
1084
|
+
async startDownload(retried416 = false) {
|
|
1085
|
+
const { adapter: { fs, toWeb, dirname } } = this.remoteImage.getImageManager().getOptions();
|
|
1086
|
+
const cacheUri = this.getCacheUri();
|
|
1087
|
+
if (!await fs.exists(dirname(cacheUri))) await fs.createDirectory(dirname(cacheUri));
|
|
1088
|
+
const startByte = await fs.stat(cacheUri).then((stat) => stat.size ?? 0, () => 0);
|
|
1089
|
+
const response = await this.makeRequest(startByte, retried416);
|
|
1090
|
+
const totalBytes = this.parseTotalBytes(response);
|
|
1091
|
+
if (startByte > 0 && totalBytes != null && totalBytes > 0) {
|
|
1092
|
+
const startProgress = Math.round(startByte / totalBytes * 1e4) / 100;
|
|
1093
|
+
this.downloadProgressEmitter.fire({
|
|
1094
|
+
progressType: "download",
|
|
1095
|
+
increment: 0,
|
|
1096
|
+
progress: Math.min(100, startProgress),
|
|
1097
|
+
network: 0,
|
|
1098
|
+
unit: "KB",
|
|
1099
|
+
reset: true
|
|
1100
|
+
});
|
|
910
1101
|
}
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
const
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
let
|
|
919
|
-
|
|
920
|
-
const
|
|
921
|
-
|
|
922
|
-
const
|
|
923
|
-
const
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
const
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
return {
|
|
933
|
-
...progress,
|
|
934
|
-
total,
|
|
935
|
-
loaded,
|
|
936
|
-
network,
|
|
937
|
-
unit,
|
|
938
|
-
increment
|
|
939
|
-
};
|
|
1102
|
+
const writableStream = await fs.createWritableStream(cacheUri, startByte > 0 ? { flags: vscode_fs.WriteableFlags.Append } : void 0);
|
|
1103
|
+
const webReadable = toWeb(response.data);
|
|
1104
|
+
const progressTransform = this.createDownloadProgressTransformer(startByte, totalBytes);
|
|
1105
|
+
await webReadable.pipeThrough(progressTransform).pipeTo(writableStream);
|
|
1106
|
+
}
|
|
1107
|
+
createChecksumProgressTransformer(totalBytes, hash) {
|
|
1108
|
+
let readBytes = 0;
|
|
1109
|
+
let lastReportedBytes = 0;
|
|
1110
|
+
let lastReportedProgress = 0;
|
|
1111
|
+
const reportThreshold = 64 * 1024;
|
|
1112
|
+
const report = () => {
|
|
1113
|
+
const progress = totalBytes > 0 ? Math.min(100, Math.round(readBytes / totalBytes * 1e4) / 100) : 0;
|
|
1114
|
+
const increment = Math.round((progress - lastReportedProgress) * 100) / 100;
|
|
1115
|
+
lastReportedBytes = readBytes;
|
|
1116
|
+
lastReportedProgress = progress;
|
|
1117
|
+
const clampedIncrement = Math.max(0, Math.min(100, increment));
|
|
1118
|
+
if (clampedIncrement > 0) this.checksumProgressEmitter.fire({
|
|
1119
|
+
progressType: "checksum",
|
|
1120
|
+
increment: clampedIncrement,
|
|
1121
|
+
progress: Math.round(progress * 100) / 100
|
|
1122
|
+
});
|
|
940
1123
|
};
|
|
1124
|
+
return new TransformStream({
|
|
1125
|
+
transform: (chunk, controller) => {
|
|
1126
|
+
const chunkLength = chunk ? chunk.byteLength ?? chunk.length ?? 0 : 0;
|
|
1127
|
+
if (chunk) hash.update(chunk);
|
|
1128
|
+
readBytes += chunkLength;
|
|
1129
|
+
controller.enqueue(chunk);
|
|
1130
|
+
if (readBytes - lastReportedBytes >= reportThreshold) report();
|
|
1131
|
+
},
|
|
1132
|
+
flush: () => {
|
|
1133
|
+
if (readBytes !== lastReportedBytes) report();
|
|
1134
|
+
}
|
|
1135
|
+
});
|
|
1136
|
+
}
|
|
1137
|
+
async checkChecksum() {
|
|
1138
|
+
const { adapter: { fs, crypto } } = this.remoteImage.getImageManager().getOptions();
|
|
1139
|
+
const cacheUri = this.getCacheUri();
|
|
1140
|
+
const totalBytes = await fs.stat(cacheUri).then((stat) => stat.size ?? 0, () => 0);
|
|
1141
|
+
const readableStream = await fs.createReadableStream(cacheUri);
|
|
1142
|
+
const hash = crypto.createHash("sha256");
|
|
1143
|
+
const progressTransform = this.createChecksumProgressTransformer(totalBytes, hash);
|
|
1144
|
+
await readableStream.pipeThrough(progressTransform).pipeTo(new WritableStream(), { signal: this.abortController.signal });
|
|
1145
|
+
return hash.digest("hex") === this.getRemoteImage().getRemoteImageSDK().archive?.complete?.checksum;
|
|
1146
|
+
}
|
|
1147
|
+
async extract() {
|
|
1148
|
+
const { adapter: { fs, unzipper, fromWeb } } = this.remoteImage.getImageManager().getOptions();
|
|
1149
|
+
const cacheUri = this.getCacheUri();
|
|
1150
|
+
const totalBytes = await fs.stat(cacheUri).then((stat) => stat.size ?? 0, () => 0);
|
|
1151
|
+
const extract = unzipper.Extract({ path: this.getRemoteImage().getFullPath().fsPath });
|
|
1152
|
+
const webReadable = await fs.createReadableStream(cacheUri);
|
|
1153
|
+
let readBytes = 0;
|
|
1154
|
+
let lastReportedBytes = 0;
|
|
1155
|
+
let lastReportedProgress = 0;
|
|
1156
|
+
const reportThreshold = 64 * 1024;
|
|
1157
|
+
const copyAndProgressTransform = new TransformStream({
|
|
1158
|
+
transform: (chunk, controller) => {
|
|
1159
|
+
const chunkLength = chunk?.length ?? 0;
|
|
1160
|
+
if (chunkLength <= 0) return;
|
|
1161
|
+
readBytes += chunkLength;
|
|
1162
|
+
if (readBytes - lastReportedBytes >= reportThreshold) {
|
|
1163
|
+
const progress = totalBytes > 0 ? Math.min(100, Math.round(readBytes / totalBytes * 1e4) / 100) : 0;
|
|
1164
|
+
const increment = Math.round((progress - lastReportedProgress) * 100) / 100;
|
|
1165
|
+
lastReportedBytes = readBytes;
|
|
1166
|
+
lastReportedProgress = progress;
|
|
1167
|
+
const clampedIncrement = Math.max(0, Math.min(100, increment));
|
|
1168
|
+
if (clampedIncrement > 0) this.extractProgressEmitter.fire({
|
|
1169
|
+
progressType: "extract",
|
|
1170
|
+
increment: clampedIncrement,
|
|
1171
|
+
progress: Math.round(progress * 100) / 100
|
|
1172
|
+
});
|
|
1173
|
+
}
|
|
1174
|
+
controller.enqueue(chunk.slice(0));
|
|
1175
|
+
},
|
|
1176
|
+
flush: () => {
|
|
1177
|
+
if (readBytes !== lastReportedBytes) {
|
|
1178
|
+
const increment = Math.round((100 - lastReportedProgress) * 100) / 100;
|
|
1179
|
+
const clampedIncrement = Math.max(0, Math.min(100, increment));
|
|
1180
|
+
if (clampedIncrement > 0) this.extractProgressEmitter.fire({
|
|
1181
|
+
progressType: "extract",
|
|
1182
|
+
increment: clampedIncrement,
|
|
1183
|
+
progress: 100
|
|
1184
|
+
});
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
});
|
|
1188
|
+
const readable = fromWeb(webReadable.pipeThrough(copyAndProgressTransform));
|
|
1189
|
+
const abortHandler = () => readable.destroy(new DOMException("Aborted", "AbortError"));
|
|
1190
|
+
this.abortController.signal.addEventListener("abort", abortHandler);
|
|
1191
|
+
readable.pipe(extract);
|
|
1192
|
+
await extract.promise().finally(() => this.abortController.signal.removeEventListener("abort", abortHandler));
|
|
941
1193
|
}
|
|
942
1194
|
};
|
|
943
|
-
function createImageDownloader(image, url) {
|
|
944
|
-
return new ImageDownloaderImpl(image, url);
|
|
945
|
-
}
|
|
946
1195
|
|
|
947
1196
|
//#endregion
|
|
948
|
-
//#region src/images/image.ts
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
this.resolvedFsPath = resolvedFsPath;
|
|
954
|
-
}
|
|
955
|
-
getImageManager() {
|
|
956
|
-
return this.imageManager;
|
|
957
|
-
}
|
|
958
|
-
getArch() {
|
|
959
|
-
const [, , deviceTypeWithArch] = this.getPath()?.split(",") ?? [];
|
|
960
|
-
const split = deviceTypeWithArch?.split("_") ?? [];
|
|
961
|
-
return split[split.length - 1];
|
|
962
|
-
}
|
|
963
|
-
getPath() {
|
|
964
|
-
return this.response?.path;
|
|
965
|
-
}
|
|
966
|
-
getChecksum() {
|
|
967
|
-
return this.response?.archive?.complete?.checksum;
|
|
968
|
-
}
|
|
969
|
-
getReleaseType() {
|
|
970
|
-
return this.response?.releaseType;
|
|
971
|
-
}
|
|
972
|
-
getFsPath() {
|
|
973
|
-
return this.resolvedFsPath;
|
|
974
|
-
}
|
|
975
|
-
async isDownloaded() {
|
|
976
|
-
return this.imageManager.getOptions().fs.existsSync(this.getFsPath()) && this.imageManager.getOptions().fs.statSync(this.getFsPath()).isDirectory();
|
|
977
|
-
}
|
|
978
|
-
getVersion() {
|
|
979
|
-
return this.response?.version;
|
|
980
|
-
}
|
|
981
|
-
getApiVersion() {
|
|
982
|
-
return this.response?.apiVersion;
|
|
983
|
-
}
|
|
984
|
-
getTargetOS() {
|
|
985
|
-
const [, systemNameWithVersion] = this.getPath()?.split(",") ?? [];
|
|
986
|
-
const [systemName] = systemNameWithVersion?.split("-") ?? [];
|
|
987
|
-
return systemName ?? "";
|
|
1197
|
+
//#region src/images/remote-image.ts
|
|
1198
|
+
let RemoteImage;
|
|
1199
|
+
(function(_RemoteImage) {
|
|
1200
|
+
function is(value) {
|
|
1201
|
+
return value instanceof RemoteImageImpl;
|
|
988
1202
|
}
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
1203
|
+
_RemoteImage.is = is;
|
|
1204
|
+
})(RemoteImage || (RemoteImage = {}));
|
|
1205
|
+
var RemoteImageImpl = class extends BaseImageImpl {
|
|
1206
|
+
imageType = "remote";
|
|
1207
|
+
constructor(imageManager, remoteImageSDK = {}) {
|
|
1208
|
+
super({
|
|
1209
|
+
imageManager,
|
|
1210
|
+
relativePath: remoteImageSDK.path?.split(",").join("/") ?? "",
|
|
1211
|
+
apiVersion: remoteImageSDK.apiVersion ? Number.parseInt(remoteImageSDK.apiVersion) : 0
|
|
1212
|
+
});
|
|
1213
|
+
this.imageManager = imageManager;
|
|
1214
|
+
this.remoteImageSDK = remoteImageSDK;
|
|
993
1215
|
}
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
const [deviceType] = deviceTypeWithArch?.split("_") ?? [];
|
|
997
|
-
return deviceType ?? "";
|
|
1216
|
+
getRemoteImageSDK() {
|
|
1217
|
+
return this.remoteImageSDK;
|
|
998
1218
|
}
|
|
999
|
-
|
|
1000
|
-
const
|
|
1001
|
-
|
|
1002
|
-
return deviceType.toLowerCase();
|
|
1219
|
+
getFullDeviceType() {
|
|
1220
|
+
const name = this.getRemoteImageSDK().displayName?.split("-");
|
|
1221
|
+
return name?.[name.length - 1];
|
|
1003
1222
|
}
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
if (
|
|
1007
|
-
|
|
1223
|
+
_localImage;
|
|
1224
|
+
async getLocalImage(force = false) {
|
|
1225
|
+
if (!force && this._localImage) return this._localImage;
|
|
1226
|
+
this._localImage = (await this.getImageManager().getLocalImages()).find((localImage) => localImage.getFullPath().toString() === this.getFullPath().toString());
|
|
1227
|
+
return this._localImage;
|
|
1008
1228
|
}
|
|
1009
|
-
async
|
|
1229
|
+
async createDownloader(signals) {
|
|
1230
|
+
const { adapter: { axios, isAxiosError } } = this.imageManager.getOptions();
|
|
1010
1231
|
try {
|
|
1011
|
-
const response = await axios.
|
|
1012
|
-
osArch: this.
|
|
1013
|
-
osType: this.
|
|
1232
|
+
const response = await axios.post("https://devecostudio-drcn.deveco.dbankcloud.com/sdkmanager/v7/hos/download", {
|
|
1233
|
+
osArch: this.getImageManager().getArch(),
|
|
1234
|
+
osType: this.getImageManager().getOperatingSystem(),
|
|
1014
1235
|
path: {
|
|
1015
|
-
path: this.
|
|
1016
|
-
version: this.
|
|
1236
|
+
path: this.getRemoteImageSDK().path,
|
|
1237
|
+
version: this.getRemoteImageSDK().version
|
|
1017
1238
|
},
|
|
1018
1239
|
imei: "d490a470-8719-4baf-9cc4-9c78d40d"
|
|
1019
1240
|
});
|
|
1020
|
-
if (typeof response.data?.url !== "string")
|
|
1021
|
-
return response.data.url;
|
|
1241
|
+
if (typeof response.data?.url !== "string") throw new RemoteImageRequestError(response.data?.body, response.data?.code);
|
|
1242
|
+
return new ImageDownloaderImpl(this, response.data.url, signals);
|
|
1022
1243
|
} catch (error) {
|
|
1023
|
-
|
|
1244
|
+
if (isAxiosError(error)) throw new RemoteImageRequestError(error.message, Number(error.code), error);
|
|
1245
|
+
if (error instanceof Error) throw new RemoteImageRequestError(error.message, -1, error);
|
|
1246
|
+
throw new RemoteImageRequestError("Unknown request error.", -1, error);
|
|
1024
1247
|
}
|
|
1025
1248
|
}
|
|
1026
1249
|
toJSON() {
|
|
1027
1250
|
return {
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
path: this.getPath(),
|
|
1031
|
-
checksum: this.getChecksum(),
|
|
1032
|
-
fsPath: this.getFsPath(),
|
|
1033
|
-
version: this.getVersion(),
|
|
1034
|
-
apiVersion: this.getApiVersion(),
|
|
1035
|
-
targetOS: this.getTargetOS(),
|
|
1036
|
-
targetVersion: this.getTargetVersion(),
|
|
1037
|
-
deviceType: this.getDeviceType(),
|
|
1038
|
-
snakecaseDeviceType: this.getSnakecaseDeviceType()
|
|
1251
|
+
...super.toJSON(),
|
|
1252
|
+
remoteImageSDK: this.getRemoteImageSDK()
|
|
1039
1253
|
};
|
|
1040
1254
|
}
|
|
1041
1255
|
};
|
|
1042
1256
|
|
|
1043
1257
|
//#endregion
|
|
1044
|
-
//#region src/
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
"
|
|
1056
|
-
"
|
|
1057
|
-
"
|
|
1058
|
-
"
|
|
1059
|
-
"
|
|
1060
|
-
"
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
async getProductConfig(usingDefaultProductConfig = false) {
|
|
1068
|
-
const productConfig = usingDefaultProductConfig ? (await Promise.resolve().then(() => require("./default-product-config.cjs"))).default : await this.getImageManager().getProductConfig();
|
|
1069
|
-
const deviceType = this.getDeviceType().toLowerCase();
|
|
1070
|
-
if (!deviceType) return [];
|
|
1071
|
-
if (deviceType === "pc") return productConfig["2in1 Foldable"] ?? [];
|
|
1072
|
-
const key = Object.keys(productConfig).find((key) => key.toLowerCase() === deviceType);
|
|
1073
|
-
if (key) return productConfig[key] ?? [];
|
|
1074
|
-
return [];
|
|
1075
|
-
}
|
|
1076
|
-
async delete() {
|
|
1077
|
-
const { fs } = this.getImageManager().getOptions();
|
|
1078
|
-
const path = this.getFsPath();
|
|
1079
|
-
if (!fs.existsSync(path) || !fs.statSync(path).isDirectory()) return /* @__PURE__ */ new Error("Image path does not exist");
|
|
1080
|
-
fs.rmSync(path, { recursive: true });
|
|
1081
|
-
const devices = await this.getDevices();
|
|
1082
|
-
const error = await Promise.allSettled(devices.map((device) => device.delete())).then((results) => results.find((result) => result.status === "rejected"));
|
|
1083
|
-
if (error) return error.reason;
|
|
1084
|
-
}
|
|
1085
|
-
getExecutablePath() {
|
|
1086
|
-
const { emulatorPath, process, path } = this.getImageManager().getOptions();
|
|
1087
|
-
return process.platform === "win32" ? path.join(emulatorPath, "Emulator.exe") : path.join(emulatorPath, "Emulator");
|
|
1088
|
-
}
|
|
1089
|
-
async buildStartCommand(device) {
|
|
1090
|
-
const config = device.buildList();
|
|
1091
|
-
return `${this.getExecutablePath()} ${[
|
|
1092
|
-
"-hvd",
|
|
1093
|
-
`"${config.name.replace(/"/g, "\\\"")}"`,
|
|
1094
|
-
"-path",
|
|
1095
|
-
`"${this.getImageManager().getOptions().deployedPath.replace(/"/g, "\\\"")}"`,
|
|
1096
|
-
"-imageRoot",
|
|
1097
|
-
`"${this.getImageManager().getOptions().imageBasePath.replace(/"/g, "\\\"")}"`
|
|
1098
|
-
].join(" ")}`;
|
|
1099
|
-
}
|
|
1100
|
-
async start(deployer) {
|
|
1101
|
-
const { child_process, emulatorPath } = this.getImageManager().getOptions();
|
|
1102
|
-
return child_process.exec(await this.buildStartCommand(deployer), { cwd: emulatorPath });
|
|
1103
|
-
}
|
|
1104
|
-
async buildStopCommand(device) {
|
|
1105
|
-
const config = device.buildList();
|
|
1106
|
-
return `${this.getExecutablePath()} ${["-stop", `"${config.name.replace(/"/g, "\\\"")}"`].join(" ")}`;
|
|
1107
|
-
}
|
|
1108
|
-
async stop(device) {
|
|
1109
|
-
const { child_process, emulatorPath } = this.getImageManager().getOptions();
|
|
1110
|
-
return child_process.exec(await this.buildStopCommand(device), { cwd: emulatorPath });
|
|
1111
|
-
}
|
|
1112
|
-
async createScreenLike(listsJsonItem) {
|
|
1113
|
-
const productConfig = await this.getImageManager().getProductConfig();
|
|
1114
|
-
const pascalCaseDeviceType = await this.getPascalCaseDeviceType();
|
|
1115
|
-
const screen = createScreen({
|
|
1116
|
-
diagonal: Number(listsJsonItem.diagonalSize),
|
|
1117
|
-
height: Number(listsJsonItem.resolutionHeight),
|
|
1118
|
-
width: Number(listsJsonItem.resolutionWidth),
|
|
1119
|
-
density: Number(listsJsonItem.density),
|
|
1120
|
-
deviceType: listsJsonItem.type,
|
|
1121
|
-
apiVersion: Number(listsJsonItem.apiVersion),
|
|
1122
|
-
cover: listsJsonItem.coverResolutionWidth && listsJsonItem.coverResolutionHeight && listsJsonItem.coverDiagonalSize ? {
|
|
1123
|
-
height: Number(listsJsonItem.coverResolutionHeight),
|
|
1124
|
-
width: Number(listsJsonItem.coverResolutionWidth),
|
|
1125
|
-
diagonal: Number(listsJsonItem.coverDiagonalSize)
|
|
1126
|
-
} : void 0
|
|
1127
|
-
});
|
|
1128
|
-
if (pascalCaseDeviceType) {
|
|
1129
|
-
const productConfigItem = productConfig[pascalCaseDeviceType]?.find((item) => item.name === listsJsonItem.model);
|
|
1130
|
-
if (productConfigItem && productConfigItem.outerScreenWidth && productConfigItem.outerScreenHeight && productConfigItem.outerScreenDiagonal) screen.setOuterScreen(createOuterScreen({
|
|
1131
|
-
width: Number(productConfigItem.outerScreenWidth),
|
|
1132
|
-
height: Number(productConfigItem.outerScreenHeight),
|
|
1133
|
-
diagonal: Number(productConfigItem.outerScreenDiagonal)
|
|
1134
|
-
}, screen));
|
|
1135
|
-
if (productConfigItem && productConfigItem.outerDoubleScreenWidth && productConfigItem.outerDoubleScreenHeight && productConfigItem.outerDoubleScreenDiagonal) screen.getOuterScreen()?.setOuterDoubleScreen(createOuterDoubleScreen({
|
|
1136
|
-
width: Number(productConfigItem.outerDoubleScreenWidth),
|
|
1137
|
-
height: Number(productConfigItem.outerDoubleScreenHeight),
|
|
1138
|
-
diagonal: Number(productConfigItem.outerDoubleScreenDiagonal)
|
|
1139
|
-
}, screen.getOuterScreen()));
|
|
1258
|
+
//#region src/options.ts
|
|
1259
|
+
let OptionsResolver;
|
|
1260
|
+
(function(_OptionsResolver) {
|
|
1261
|
+
async function resolveAdapter(adapter) {
|
|
1262
|
+
const mergedAdapter = {
|
|
1263
|
+
os: adapter?.os ?? await import("node:os"),
|
|
1264
|
+
process: adapter?.process ?? await import("node:process"),
|
|
1265
|
+
crypto: adapter?.crypto ?? await import("node:crypto"),
|
|
1266
|
+
child_process: adapter?.child_process ?? await import("node:child_process"),
|
|
1267
|
+
axios: adapter?.axios ?? (await import("axios")).default,
|
|
1268
|
+
fs: adapter?.fs ?? await (0, vscode_fs.createNodeFileSystem)(),
|
|
1269
|
+
join: adapter?.join ?? (await import("vscode-uri")).Utils.joinPath,
|
|
1270
|
+
URI: adapter?.URI ?? (await import("vscode-uri")).URI,
|
|
1271
|
+
dirname: adapter?.dirname ?? (await import("vscode-uri")).Utils.dirname,
|
|
1272
|
+
basename: adapter?.basename ?? (await import("vscode-uri")).Utils.basename,
|
|
1273
|
+
toWeb: adapter?.toWeb ?? (await import("node:stream")).Readable.toWeb,
|
|
1274
|
+
fromWeb: adapter?.fromWeb ?? (await import("node:stream")).Readable.fromWeb,
|
|
1275
|
+
unzipper: adapter?.unzipper ?? await import("unzipper")
|
|
1276
|
+
};
|
|
1277
|
+
if (adapter?.isAxiosError) mergedAdapter.isAxiosError = adapter.isAxiosError;
|
|
1278
|
+
else {
|
|
1279
|
+
const axios = await import("axios");
|
|
1280
|
+
mergedAdapter.isAxiosError = (error) => axios.isAxiosError(error);
|
|
1140
1281
|
}
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
const listsJson = JSON.parse(fs.readFileSync(listsJsonPath, "utf-8"));
|
|
1154
|
-
if (!Array.isArray(listsJson) || this.imageType !== "local") return [];
|
|
1155
|
-
const devices = [];
|
|
1156
|
-
for (const listsJsonItem of listsJson) {
|
|
1157
|
-
if (path.resolve(imageBasePath, listsJsonItem.imageDir) !== this.getFsPath()) continue;
|
|
1158
|
-
const iniFilePath = path.resolve(listsJsonItem.path, "config.ini");
|
|
1159
|
-
if (!fs.existsSync(iniFilePath) || !fs.statSync(iniFilePath).isFile()) continue;
|
|
1160
|
-
const device = this.createDevice({
|
|
1161
|
-
name: listsJsonItem.name,
|
|
1162
|
-
cpuNumber: Number(listsJsonItem.cpuNumber),
|
|
1163
|
-
diskSize: Number(listsJsonItem.dataDiskSize),
|
|
1164
|
-
memorySize: Number(listsJsonItem.memoryRamSize),
|
|
1165
|
-
screen: await this.createScreenLike(listsJsonItem)
|
|
1166
|
-
});
|
|
1167
|
-
device.setUuid(listsJsonItem.uuid).setCachedList(listsJsonItem).setCachedIni(ini.default.parse(fs.readFileSync(iniFilePath, "utf-8")));
|
|
1168
|
-
if (!fs.existsSync(listsJsonItem.path) || !fs.statSync(listsJsonItem.path).isDirectory()) continue;
|
|
1169
|
-
devices.push(device);
|
|
1282
|
+
return mergedAdapter;
|
|
1283
|
+
}
|
|
1284
|
+
_OptionsResolver.resolveAdapter = resolveAdapter;
|
|
1285
|
+
async function resolveImageManagerOptions(options) {
|
|
1286
|
+
const adapter = await resolveAdapter(options.adapter);
|
|
1287
|
+
const { os, join, process, URI } = adapter;
|
|
1288
|
+
function resolveDefaultImageBasePath() {
|
|
1289
|
+
switch (process.platform) {
|
|
1290
|
+
case "win32": return typeof process.env.APPDATA === "string" && process.env.APPDATA.length > 0 ? join(URI.file(process.env.APPDATA), "Local", "Huawei", "Sdk") : join(URI.file(os.homedir()), "AppData", "Local", "Huawei", "Sdk");
|
|
1291
|
+
case "darwin": return join(URI.file(os.homedir()), "Library", "Huawei", "Sdk");
|
|
1292
|
+
default: return join(URI.file(os.homedir()), ".huawei", "Sdk");
|
|
1293
|
+
}
|
|
1170
1294
|
}
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1295
|
+
function resolveDefaultDeployedPath() {
|
|
1296
|
+
switch (process.platform) {
|
|
1297
|
+
case "win32": return typeof process.env.APPDATA === "string" && process.env.APPDATA.length > 0 ? join(URI.file(process.env.APPDATA), "Local", "Huawei", "Emulator", "deployed") : join(URI.file(os.homedir()), "AppData", "Local", "Huawei", "Emulator", "deployed");
|
|
1298
|
+
default: return join(URI.file(os.homedir()), ".huawei", "Emulator", "deployed");
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
function resolveDefaultSdkPath() {
|
|
1302
|
+
switch (process.platform) {
|
|
1303
|
+
case "darwin": return URI.file("/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony");
|
|
1304
|
+
case "win32": return URI.file("C:\\Program Files\\Huawei\\DevEco Studio\\sdk\\default\\openharmony");
|
|
1305
|
+
default: return join(URI.file(os.homedir()), ".huawei", "Sdk", "default", "openharmony");
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
function resolveDefaultConfigPath() {
|
|
1309
|
+
switch (process.platform) {
|
|
1310
|
+
case "darwin": return join(URI.file(os.homedir()), "Library", "Application Support", "Huawei", "DevEcoStudio6.0");
|
|
1311
|
+
case "win32": return join(URI.file(process.env.APPDATA ?? os.homedir()), "Roaming", "Huawei", "DevEcoStudio6.0");
|
|
1312
|
+
default: return join(URI.file(os.homedir()), ".huawei", "DevEcoStudio6.0");
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
function resolveDefaultLogPath() {
|
|
1316
|
+
switch (process.platform) {
|
|
1317
|
+
case "darwin": return join(URI.file(os.homedir()), "Library", "Logs", "Huawei", "DevEcoStudio6.0");
|
|
1318
|
+
case "win32": return join(URI.file(process.env.APPDATA ?? os.homedir()), "Local", "Huawei", "DevEcoStudio6.0", "log");
|
|
1319
|
+
default: return join(URI.file(os.homedir()), ".huawei", "DevEcoStudio6.0", "log");
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
function resolveDefaultEmulatorPath() {
|
|
1323
|
+
switch (process.platform) {
|
|
1324
|
+
case "darwin": return URI.file("/Applications/DevEco-Studio.app/Contents/tools/emulator");
|
|
1325
|
+
case "win32": return URI.file("C:\\Program Files\\Huawei\\DevEco Studio\\tools\\emulator");
|
|
1326
|
+
default: return join(URI.file(os.homedir()), ".huawei", "Emulator");
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
const imageBasePath = typeof options.imageBasePath === "string" ? URI.file(options.imageBasePath) : options.imageBasePath || resolveDefaultImageBasePath();
|
|
1330
|
+
const cachePath = typeof options.cachePath === "string" ? URI.file(options.cachePath) : options.cachePath || join(imageBasePath, "cache");
|
|
1174
1331
|
return {
|
|
1175
|
-
|
|
1176
|
-
|
|
1332
|
+
imageBasePath,
|
|
1333
|
+
deployedPath: typeof options.deployedPath === "string" ? URI.file(options.deployedPath) : options.deployedPath || resolveDefaultDeployedPath(),
|
|
1334
|
+
cachePath,
|
|
1335
|
+
sdkPath: typeof options.sdkPath === "string" ? URI.file(options.sdkPath) : options.sdkPath || resolveDefaultSdkPath(),
|
|
1336
|
+
configPath: typeof options.configPath === "string" ? URI.file(options.configPath) : options.configPath || resolveDefaultConfigPath(),
|
|
1337
|
+
logPath: typeof options.logPath === "string" ? URI.file(options.logPath) : options.logPath || resolveDefaultLogPath(),
|
|
1338
|
+
emulatorPath: typeof options.emulatorPath === "string" ? URI.file(options.emulatorPath) : options.emulatorPath || resolveDefaultEmulatorPath(),
|
|
1339
|
+
adapter
|
|
1177
1340
|
};
|
|
1178
1341
|
}
|
|
1179
|
-
|
|
1342
|
+
_OptionsResolver.resolveImageManagerOptions = resolveImageManagerOptions;
|
|
1343
|
+
})(OptionsResolver || (OptionsResolver = {}));
|
|
1180
1344
|
|
|
1181
1345
|
//#endregion
|
|
1182
|
-
//#region src/
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
return
|
|
1346
|
+
//#region src/sdk-list.ts
|
|
1347
|
+
let SDKList;
|
|
1348
|
+
(function(_SDKList) {
|
|
1349
|
+
function isOKResponse(result) {
|
|
1350
|
+
return "data" in result && Array.isArray(result.data);
|
|
1351
|
+
}
|
|
1352
|
+
_SDKList.isOKResponse = isOKResponse;
|
|
1353
|
+
class SDKListError extends Error {
|
|
1354
|
+
constructor(code, message, cause) {
|
|
1355
|
+
super(message);
|
|
1356
|
+
this.code = code;
|
|
1357
|
+
this.message = message;
|
|
1358
|
+
this.cause = cause;
|
|
1359
|
+
}
|
|
1187
1360
|
}
|
|
1188
|
-
|
|
1361
|
+
_SDKList.SDKListError = SDKListError;
|
|
1362
|
+
(function(_SDKListError) {
|
|
1363
|
+
_SDKListError.Code = /* @__PURE__ */ function(Code) {
|
|
1364
|
+
Code[Code["VALIDATION_ERROR"] = 400] = "VALIDATION_ERROR";
|
|
1365
|
+
Code[Code["REQUEST_ERROR"] = 500] = "REQUEST_ERROR";
|
|
1366
|
+
return Code;
|
|
1367
|
+
}({});
|
|
1368
|
+
})(SDKListError || (SDKListError = _SDKList.SDKListError || (_SDKList.SDKListError = {})));
|
|
1369
|
+
})(SDKList || (SDKList = {}));
|
|
1189
1370
|
|
|
1190
1371
|
//#endregion
|
|
1191
|
-
//#region src/
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
case "
|
|
1199
|
-
case "
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
default: return path.resolve(os.homedir(), ".huawei", "Emulator", "deployed");
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
function resolveDefaultSdkPath() {
|
|
1210
|
-
switch (process.platform) {
|
|
1211
|
-
case "darwin": return "/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony";
|
|
1212
|
-
case "win32": return "C:\\Program Files\\Huawei\\DevEco Studio\\sdk\\default\\openharmony";
|
|
1213
|
-
default: return path.resolve(os.homedir(), ".huawei", "Sdk", "default", "openharmony");
|
|
1372
|
+
//#region src/utils/devicetype-converter.ts
|
|
1373
|
+
let DeviceTypeConverter;
|
|
1374
|
+
(function(_DeviceTypeConverter) {
|
|
1375
|
+
function snakecaseToCamelcase(snakecaseDeviceType) {
|
|
1376
|
+
switch (snakecaseDeviceType) {
|
|
1377
|
+
case "phone": return "Phone";
|
|
1378
|
+
case "2in1": return "2in1";
|
|
1379
|
+
case "2in1_foldable": return "2in1 Foldable";
|
|
1380
|
+
case "foldable": return "Foldable";
|
|
1381
|
+
case "tablet": return "Tablet";
|
|
1382
|
+
case "triplefold": return "TripleFold";
|
|
1383
|
+
case "tv": return "TV";
|
|
1384
|
+
case "wearable": return "Wearable";
|
|
1385
|
+
case "widefold": return "WideFold";
|
|
1386
|
+
default: return snakecaseDeviceType.toLowerCase().split("_").join(" ");
|
|
1214
1387
|
}
|
|
1215
1388
|
}
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
case "darwin": return path.resolve(os.homedir(), "Library", "Application Support", "Huawei", "DevEcoStudio6.0");
|
|
1219
|
-
case "win32": return path.resolve(process.env.APPDATA ?? os.homedir(), "Roaming", "Huawei", "DevEcoStudio6.0");
|
|
1220
|
-
default: return path.resolve(os.homedir(), ".huawei", "DevEcoStudio6.0");
|
|
1221
|
-
}
|
|
1222
|
-
}
|
|
1223
|
-
function resolveDefaultLogPath() {
|
|
1224
|
-
switch (process.platform) {
|
|
1225
|
-
case "darwin": return path.resolve(os.homedir(), "Library", "Logs", "Huawei", "DevEcoStudio6.0");
|
|
1226
|
-
case "win32": return path.resolve(process.env.APPDATA ?? os.homedir(), "Local", "Huawei", "DevEcoStudio6.0", "log");
|
|
1227
|
-
default: return path.resolve(os.homedir(), ".huawei", "DevEcoStudio6.0", "log");
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
function resolveDefaultEmulatorPath() {
|
|
1231
|
-
switch (process.platform) {
|
|
1232
|
-
case "darwin": return "/Applications/DevEco-Studio.app/Contents/tools/emulator";
|
|
1233
|
-
case "win32": return "C:\\Program Files\\Huawei\\DevEco Studio\\tools\\emulator";
|
|
1234
|
-
default: return path.resolve(os.homedir(), ".huawei", "Emulator");
|
|
1235
|
-
}
|
|
1236
|
-
}
|
|
1237
|
-
const imageBasePath = options.imageBasePath || resolveDefaultImageBasePath();
|
|
1238
|
-
const cachePath = options.cachePath || path.resolve(imageBasePath, "cache");
|
|
1239
|
-
return {
|
|
1240
|
-
imageBasePath,
|
|
1241
|
-
deployedPath: options.deployedPath || resolveDefaultDeployedPath(),
|
|
1242
|
-
cachePath,
|
|
1243
|
-
sdkPath: options.sdkPath || resolveDefaultSdkPath(),
|
|
1244
|
-
configPath: options.configPath || resolveDefaultConfigPath(),
|
|
1245
|
-
logPath: options.logPath || resolveDefaultLogPath(),
|
|
1246
|
-
emulatorPath: options.emulatorPath || resolveDefaultEmulatorPath(),
|
|
1247
|
-
path,
|
|
1248
|
-
os,
|
|
1249
|
-
fs: options.fs ?? await import("node:fs"),
|
|
1250
|
-
process: options.process ?? await import("node:process"),
|
|
1251
|
-
crypto: options.crypto ?? await import("node:crypto"),
|
|
1252
|
-
child_process: options.child_process ?? await import("node:child_process")
|
|
1253
|
-
};
|
|
1254
|
-
}
|
|
1389
|
+
_DeviceTypeConverter.snakecaseToCamelcase = snakecaseToCamelcase;
|
|
1390
|
+
})(DeviceTypeConverter || (DeviceTypeConverter = {}));
|
|
1255
1391
|
|
|
1256
1392
|
//#endregion
|
|
1257
1393
|
//#region src/image-manager.ts
|
|
1258
1394
|
var ImageManagerImpl = class {
|
|
1259
|
-
constructor(
|
|
1260
|
-
this.
|
|
1395
|
+
constructor(options) {
|
|
1396
|
+
this.options = options;
|
|
1261
1397
|
}
|
|
1262
1398
|
getOptions() {
|
|
1263
|
-
return this.
|
|
1399
|
+
return this.options;
|
|
1264
1400
|
}
|
|
1265
|
-
|
|
1266
|
-
switch (this.
|
|
1401
|
+
getOperatingSystem() {
|
|
1402
|
+
switch (this.options.adapter.process.platform) {
|
|
1267
1403
|
case "win32": return "windows";
|
|
1268
1404
|
case "darwin": return "mac";
|
|
1269
1405
|
default: return "linux";
|
|
1270
1406
|
}
|
|
1271
1407
|
}
|
|
1272
1408
|
getArch() {
|
|
1273
|
-
if (this.
|
|
1409
|
+
if (this.options.adapter.process.arch.toLowerCase().includes("arm")) return "arm64";
|
|
1274
1410
|
return "x86";
|
|
1275
1411
|
}
|
|
1276
|
-
async
|
|
1277
|
-
const
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1412
|
+
async requestSdkList(supportVersion = "6.0-hos-single-9") {
|
|
1413
|
+
const { adapter: { axios } } = this.getOptions();
|
|
1414
|
+
try {
|
|
1415
|
+
return await axios.post("https://devecostudio-drcn.deveco.dbankcloud.com/sdkmanager/v8/hos/getSdkList", {
|
|
1416
|
+
osArch: this.getArch(),
|
|
1417
|
+
osType: this.getOperatingSystem(),
|
|
1418
|
+
supportVersion
|
|
1419
|
+
});
|
|
1420
|
+
} catch (error) {
|
|
1421
|
+
return error;
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
async safeReadAndParseSdkPkgFile(sdkPkgFileUri) {
|
|
1425
|
+
const { adapter: { fs } } = this.getOptions();
|
|
1426
|
+
try {
|
|
1427
|
+
const sdkPkgFileContent = await fs.readFile(sdkPkgFileUri).then((buffer) => buffer.toString());
|
|
1428
|
+
if (!sdkPkgFileContent.length) return void 0;
|
|
1429
|
+
return JSON.parse(sdkPkgFileContent);
|
|
1430
|
+
} catch {
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
async safeReadAndParseInfoFile(infoFileUri) {
|
|
1435
|
+
const { adapter: { fs } } = this.getOptions();
|
|
1436
|
+
try {
|
|
1437
|
+
const infoFileContent = await fs.readFile(infoFileUri).then((buffer) => buffer.toString());
|
|
1438
|
+
if (!infoFileContent.length) return void 0;
|
|
1439
|
+
return JSON.parse(infoFileContent);
|
|
1440
|
+
} catch {
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
async getLocalImages() {
|
|
1445
|
+
const { adapter: { fs, join } } = this.getOptions();
|
|
1446
|
+
const localImages = [];
|
|
1447
|
+
const systemImagePath = join(this.options.imageBasePath, "system-image");
|
|
1448
|
+
const sdkPkgFiles = await fs.glob(new vscode_fs.RelativePattern(systemImagePath, "**/sdk-pkg.json"), { deep: 3 });
|
|
1449
|
+
for (const sdkPkgFileUri of sdkPkgFiles) {
|
|
1450
|
+
const sdkPkgFile = await this.safeReadAndParseSdkPkgFile(sdkPkgFileUri);
|
|
1451
|
+
if (!sdkPkgFile) continue;
|
|
1452
|
+
const infoFile = await this.safeReadAndParseInfoFile(sdkPkgFileUri.with({ path: sdkPkgFileUri.path.replace("sdk-pkg.json", "info.json") }));
|
|
1453
|
+
if (!infoFile) continue;
|
|
1454
|
+
localImages.push(new LocalImageImpl(this, sdkPkgFile, infoFile));
|
|
1455
|
+
}
|
|
1456
|
+
return localImages;
|
|
1457
|
+
}
|
|
1458
|
+
async getRemoteImages(supportVersion = "6.0-hos-single-9") {
|
|
1459
|
+
const remoteImages = [];
|
|
1460
|
+
const { adapter: { isAxiosError } } = this.getOptions();
|
|
1461
|
+
const resultOrError = await this.requestSdkList(supportVersion);
|
|
1462
|
+
if (isAxiosError(resultOrError)) return new SDKList.SDKListError(SDKList.SDKListError.Code.REQUEST_ERROR, "Request failed with image sdk list.", resultOrError);
|
|
1463
|
+
if (!Array.isArray(resultOrError.data)) return new SDKList.SDKListError(SDKList.SDKListError.Code.REQUEST_ERROR, "Request failed with image sdk list.", resultOrError);
|
|
1464
|
+
for (const item of resultOrError.data) {
|
|
1465
|
+
if (typeof item !== "object" || item === null || Array.isArray(item)) continue;
|
|
1466
|
+
remoteImages.push(new RemoteImageImpl(this, item));
|
|
1467
|
+
}
|
|
1468
|
+
return remoteImages;
|
|
1469
|
+
}
|
|
1470
|
+
async getDownloadedRemoteImages(supportVersion) {
|
|
1471
|
+
const remoteImages = await this.getRemoteImages(supportVersion);
|
|
1472
|
+
if (remoteImages instanceof SDKList.SDKListError) return remoteImages;
|
|
1473
|
+
const downloadedRemoteImages = [];
|
|
1474
|
+
for (const remoteImage of remoteImages) {
|
|
1475
|
+
if (!await remoteImage.getLocalImage()) continue;
|
|
1476
|
+
downloadedRemoteImages.push(remoteImage);
|
|
1477
|
+
}
|
|
1478
|
+
return downloadedRemoteImages;
|
|
1479
|
+
}
|
|
1480
|
+
getListsFilePath() {
|
|
1481
|
+
const { deployedPath, adapter: { join } } = this.getOptions();
|
|
1482
|
+
return join(deployedPath, "lists.json");
|
|
1483
|
+
}
|
|
1484
|
+
async readListsFile() {
|
|
1485
|
+
try {
|
|
1486
|
+
const { adapter: { fs } } = this.getOptions();
|
|
1487
|
+
const listsFilePath = this.getListsFilePath();
|
|
1488
|
+
const listsFileContent = await fs.readFile(listsFilePath).then((buffer) => buffer.toString());
|
|
1489
|
+
if (!listsFileContent.length) return new ListsFileImpl(this, []);
|
|
1490
|
+
return new ListsFileImpl(this, JSON.parse(listsFileContent));
|
|
1491
|
+
} catch {
|
|
1492
|
+
return new ListsFileImpl(this, []);
|
|
1288
1493
|
}
|
|
1289
|
-
return images;
|
|
1290
1494
|
}
|
|
1291
|
-
async
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1495
|
+
async readEmulatorFile() {
|
|
1496
|
+
try {
|
|
1497
|
+
const { adapter: { fs, join } } = this.getOptions();
|
|
1498
|
+
const emulatorFilePath = join(this.options.emulatorPath, "emulator.json");
|
|
1499
|
+
const emulatorFileContent = await fs.readFile(emulatorFilePath).then((buffer) => buffer.toString());
|
|
1500
|
+
if (!emulatorFileContent.length) return new EmulatorFileImpl(this, (await Promise.resolve().then(() => require("./default-emulator-config.cjs"))).default);
|
|
1501
|
+
return new EmulatorFileImpl(this, JSON.parse(emulatorFileContent));
|
|
1502
|
+
} catch {
|
|
1503
|
+
return new EmulatorFileImpl(this, (await Promise.resolve().then(() => require("./default-emulator-config.cjs"))).default);
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
async readProductConfigFile() {
|
|
1507
|
+
try {
|
|
1508
|
+
const { adapter: { fs, join } } = this.getOptions();
|
|
1509
|
+
const productConfigFilePath = join(this.options.emulatorPath, "product-config.json");
|
|
1510
|
+
const productConfigFileContent = await fs.readFile(productConfigFilePath).then((buffer) => buffer.toString());
|
|
1511
|
+
if (!productConfigFileContent.length) return new ProductConfigFileImpl(this, (await Promise.resolve().then(() => require("./default-product-config.cjs"))).default);
|
|
1512
|
+
return new ProductConfigFileImpl(this, JSON.parse(productConfigFileContent));
|
|
1513
|
+
} catch {
|
|
1514
|
+
return new ProductConfigFileImpl(this, (await Promise.resolve().then(() => require("./default-product-config.cjs"))).default);
|
|
1515
|
+
}
|
|
1295
1516
|
}
|
|
1296
|
-
async
|
|
1297
|
-
const
|
|
1298
|
-
|
|
1299
|
-
|
|
1517
|
+
async getDeployedDevices() {
|
|
1518
|
+
const deployedDevices = [];
|
|
1519
|
+
const listsFile = await this.readListsFile();
|
|
1520
|
+
const productConfigFile = await this.readProductConfigFile();
|
|
1521
|
+
const emulatorFile = await this.readEmulatorFile();
|
|
1522
|
+
for (const listFileItem of listsFile.getListsFileItems()) {
|
|
1523
|
+
const productConfigItem = productConfigFile.findProductConfigItem({
|
|
1524
|
+
deviceType: DeviceTypeConverter.snakecaseToCamelcase(listFileItem.getContent().type),
|
|
1525
|
+
name: listFileItem.getContent().model
|
|
1526
|
+
});
|
|
1527
|
+
if (!productConfigItem) continue;
|
|
1528
|
+
const emulatorDeviceItem = emulatorFile.findDeviceItem({
|
|
1529
|
+
deviceType: listFileItem.getContent().type,
|
|
1530
|
+
apiVersion: Number(listFileItem.getContent().apiVersion)
|
|
1531
|
+
});
|
|
1532
|
+
if (!emulatorDeviceItem) continue;
|
|
1533
|
+
const screen = new ScreenPresetImpl({
|
|
1534
|
+
productConfigItem,
|
|
1535
|
+
emulatorDeviceItem
|
|
1536
|
+
});
|
|
1537
|
+
const device = new DeviceImpl({
|
|
1538
|
+
imageManager: this,
|
|
1539
|
+
listsFile,
|
|
1540
|
+
listFileItem,
|
|
1541
|
+
screen
|
|
1542
|
+
});
|
|
1543
|
+
const configIniFileUri = ConfigIniFileImpl.getFileUri(device);
|
|
1544
|
+
const parsedConfigIniFile = await ConfigIniFileImpl.safeReadAndParse(device);
|
|
1545
|
+
if (!parsedConfigIniFile) {
|
|
1546
|
+
listsFile.deleteListsFileItem(listFileItem);
|
|
1547
|
+
continue;
|
|
1548
|
+
}
|
|
1549
|
+
device.setConfigIniFile(new ConfigIniFileImpl(device, configIniFileUri, parsedConfigIniFile));
|
|
1550
|
+
const namedIniFileUri = NamedIniFileImpl.getFileUri(device);
|
|
1551
|
+
const parsedNamedIniFile = await NamedIniFileImpl.safeReadAndParse(device);
|
|
1552
|
+
if (!parsedNamedIniFile) {
|
|
1553
|
+
listsFile.deleteListsFileItem(listFileItem);
|
|
1554
|
+
continue;
|
|
1555
|
+
}
|
|
1556
|
+
device.setNamedIniFile(new NamedIniFileImpl(device, namedIniFileUri, parsedNamedIniFile));
|
|
1557
|
+
deployedDevices.push(device);
|
|
1558
|
+
}
|
|
1559
|
+
if (listsFile.isChanged) listsFile.write();
|
|
1560
|
+
return deployedDevices;
|
|
1300
1561
|
}
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1562
|
+
toJSON() {
|
|
1563
|
+
return {
|
|
1564
|
+
options: this.getOptions(),
|
|
1565
|
+
operatingSystem: this.getOperatingSystem(),
|
|
1566
|
+
arch: this.getArch(),
|
|
1567
|
+
listsFilePath: this.getListsFilePath()
|
|
1568
|
+
};
|
|
1305
1569
|
}
|
|
1306
1570
|
async isCompatible() {
|
|
1307
|
-
const { fs,
|
|
1308
|
-
const sdkPkgPath =
|
|
1309
|
-
if (!fs.
|
|
1310
|
-
const sdkPkg = JSON.parse(fs.
|
|
1571
|
+
const { emulatorPath, adapter: { fs, join, URI } } = this.getOptions();
|
|
1572
|
+
const sdkPkgPath = join(emulatorPath, "sdk-pkg.json").fsPath;
|
|
1573
|
+
if (!await fs.isFile(URI.file(sdkPkgPath))) return false;
|
|
1574
|
+
const sdkPkg = JSON.parse(await fs.readFile(URI.file(sdkPkgPath)).then((buffer) => buffer.toString()));
|
|
1311
1575
|
if (!sdkPkg?.data?.version || typeof sdkPkg.data.version !== "string") return false;
|
|
1312
1576
|
const [major, minor, patch] = sdkPkg.data.version.split(".").map(Number);
|
|
1313
|
-
|
|
1577
|
+
const satisfies = (await import("semver/functions/satisfies")).default;
|
|
1578
|
+
return satisfies(`${major}.${minor}.${patch}`, ">=6.0.2");
|
|
1314
1579
|
}
|
|
1315
1580
|
};
|
|
1316
|
-
async function createImageManager(options
|
|
1317
|
-
return new ImageManagerImpl(await resolveImageManagerOptions(options));
|
|
1581
|
+
async function createImageManager(options) {
|
|
1582
|
+
return new ImageManagerImpl(await OptionsResolver.resolveImageManagerOptions(options));
|
|
1318
1583
|
}
|
|
1319
1584
|
|
|
1320
1585
|
//#endregion
|
|
1321
|
-
Object.defineProperty(exports, '
|
|
1586
|
+
Object.defineProperty(exports, 'BaseImage', {
|
|
1587
|
+
enumerable: true,
|
|
1588
|
+
get: function () {
|
|
1589
|
+
return BaseImage;
|
|
1590
|
+
}
|
|
1591
|
+
});
|
|
1592
|
+
Object.defineProperty(exports, 'ConfigIniFile', {
|
|
1322
1593
|
enumerable: true,
|
|
1323
1594
|
get: function () {
|
|
1324
|
-
return
|
|
1595
|
+
return ConfigIniFile;
|
|
1325
1596
|
}
|
|
1326
1597
|
});
|
|
1327
|
-
Object.defineProperty(exports, '
|
|
1598
|
+
Object.defineProperty(exports, 'CustomizeFoldableScreen', {
|
|
1328
1599
|
enumerable: true,
|
|
1329
1600
|
get: function () {
|
|
1330
|
-
return
|
|
1601
|
+
return CustomizeFoldableScreen;
|
|
1331
1602
|
}
|
|
1332
1603
|
});
|
|
1333
|
-
exports
|
|
1334
|
-
Object.defineProperty(exports, 'GroupPCAllEmulatorConfigItem', {
|
|
1604
|
+
Object.defineProperty(exports, 'CustomizeScreen', {
|
|
1335
1605
|
enumerable: true,
|
|
1336
1606
|
get: function () {
|
|
1337
|
-
return
|
|
1607
|
+
return CustomizeScreen;
|
|
1338
1608
|
}
|
|
1339
1609
|
});
|
|
1340
|
-
Object.defineProperty(exports, '
|
|
1610
|
+
Object.defineProperty(exports, 'Device', {
|
|
1341
1611
|
enumerable: true,
|
|
1342
1612
|
get: function () {
|
|
1343
|
-
return
|
|
1613
|
+
return Device;
|
|
1344
1614
|
}
|
|
1345
1615
|
});
|
|
1346
|
-
Object.defineProperty(exports, '
|
|
1616
|
+
Object.defineProperty(exports, 'EmulatorBasicItem', {
|
|
1347
1617
|
enumerable: true,
|
|
1348
1618
|
get: function () {
|
|
1349
|
-
return
|
|
1619
|
+
return EmulatorBasicItem;
|
|
1350
1620
|
}
|
|
1351
1621
|
});
|
|
1352
|
-
Object.defineProperty(exports, '
|
|
1622
|
+
Object.defineProperty(exports, 'EmulatorFile', {
|
|
1353
1623
|
enumerable: true,
|
|
1354
1624
|
get: function () {
|
|
1355
|
-
return
|
|
1625
|
+
return EmulatorFile;
|
|
1356
1626
|
}
|
|
1357
1627
|
});
|
|
1358
|
-
Object.defineProperty(exports, '
|
|
1628
|
+
Object.defineProperty(exports, 'EmulatorFoldItem', {
|
|
1359
1629
|
enumerable: true,
|
|
1360
1630
|
get: function () {
|
|
1361
|
-
return
|
|
1631
|
+
return EmulatorFoldItem;
|
|
1632
|
+
}
|
|
1633
|
+
});
|
|
1634
|
+
Object.defineProperty(exports, 'EmulatorGroupItem', {
|
|
1635
|
+
enumerable: true,
|
|
1636
|
+
get: function () {
|
|
1637
|
+
return EmulatorGroupItem;
|
|
1638
|
+
}
|
|
1639
|
+
});
|
|
1640
|
+
Object.defineProperty(exports, 'EmulatorTripleFoldItem', {
|
|
1641
|
+
enumerable: true,
|
|
1642
|
+
get: function () {
|
|
1643
|
+
return EmulatorTripleFoldItem;
|
|
1644
|
+
}
|
|
1645
|
+
});
|
|
1646
|
+
Object.defineProperty(exports, 'ListsFile', {
|
|
1647
|
+
enumerable: true,
|
|
1648
|
+
get: function () {
|
|
1649
|
+
return ListsFile;
|
|
1650
|
+
}
|
|
1651
|
+
});
|
|
1652
|
+
Object.defineProperty(exports, 'ListsFileItem', {
|
|
1653
|
+
enumerable: true,
|
|
1654
|
+
get: function () {
|
|
1655
|
+
return ListsFileItem;
|
|
1656
|
+
}
|
|
1657
|
+
});
|
|
1658
|
+
Object.defineProperty(exports, 'LocalImage', {
|
|
1659
|
+
enumerable: true,
|
|
1660
|
+
get: function () {
|
|
1661
|
+
return LocalImage;
|
|
1662
|
+
}
|
|
1663
|
+
});
|
|
1664
|
+
Object.defineProperty(exports, 'ProductConfigFile', {
|
|
1665
|
+
enumerable: true,
|
|
1666
|
+
get: function () {
|
|
1667
|
+
return ProductConfigFile;
|
|
1362
1668
|
}
|
|
1363
1669
|
});
|
|
1364
1670
|
Object.defineProperty(exports, 'ProductConfigItem', {
|
|
@@ -1367,18 +1673,22 @@ Object.defineProperty(exports, 'ProductConfigItem', {
|
|
|
1367
1673
|
return ProductConfigItem;
|
|
1368
1674
|
}
|
|
1369
1675
|
});
|
|
1370
|
-
exports
|
|
1371
|
-
exports.createCoverScreen = createCoverScreen;
|
|
1372
|
-
exports.createDoubleScreen = createDoubleScreen;
|
|
1373
|
-
exports.createImageManager = createImageManager;
|
|
1374
|
-
exports.createOuterDoubleScreen = createOuterDoubleScreen;
|
|
1375
|
-
exports.createOuterScreen = createOuterScreen;
|
|
1376
|
-
exports.createScreen = createScreen;
|
|
1377
|
-
exports.createScreenPreset = createScreenPreset;
|
|
1378
|
-
exports.createSingleScreen = createSingleScreen;
|
|
1379
|
-
Object.defineProperty(exports, 'version', {
|
|
1676
|
+
Object.defineProperty(exports, 'RemoteImage', {
|
|
1380
1677
|
enumerable: true,
|
|
1381
1678
|
get: function () {
|
|
1382
|
-
return
|
|
1679
|
+
return RemoteImage;
|
|
1383
1680
|
}
|
|
1384
|
-
});
|
|
1681
|
+
});
|
|
1682
|
+
Object.defineProperty(exports, 'SDKList', {
|
|
1683
|
+
enumerable: true,
|
|
1684
|
+
get: function () {
|
|
1685
|
+
return SDKList;
|
|
1686
|
+
}
|
|
1687
|
+
});
|
|
1688
|
+
Object.defineProperty(exports, 'ScreenPreset', {
|
|
1689
|
+
enumerable: true,
|
|
1690
|
+
get: function () {
|
|
1691
|
+
return ScreenPreset;
|
|
1692
|
+
}
|
|
1693
|
+
});
|
|
1694
|
+
exports.createImageManager = createImageManager;
|