@onekeyfe/hd-core 1.2.0-alpha.128 → 1.2.0-alpha.129
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/__tests__/deviceUploadNft.test.ts +0 -1
- package/__tests__/firmware-update/firmware-prepared-resource-archive.test.ts +21 -0
- package/__tests__/firmware-update/firmware-update-v4-install-poll.test.ts +5 -0
- package/__tests__/protocol-v2-resources.test.ts +79 -71
- package/__tests__/protocol-v2.test.ts +67 -61
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/firmware/FirmwarePreparedResourceArchive.d.ts.map +1 -1
- package/dist/data-manager/DataManager.d.ts +3 -3
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +41 -38
- package/package.json +4 -4
- package/src/api/CheckAllFirmwareRelease.ts +1 -1
- package/src/api/FirmwareUpdateV4.ts +29 -20
- package/src/api/firmware/FirmwarePreparedResourceArchive.ts +10 -1
- package/src/api/protocol-v2/DeviceUploadNft.ts +1 -1
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +1 -1
- package/src/data-manager/DataManager.ts +23 -24
- package/src/types/settings.ts +1 -1
|
@@ -105,6 +105,27 @@ const createPreparedResourcePlan = ({
|
|
|
105
105
|
};
|
|
106
106
|
|
|
107
107
|
describe.each(['v2', 'v3'] as const)('%s prepared resource archive binding', executor => {
|
|
108
|
+
test('rejects a missing artifact reader', async () => {
|
|
109
|
+
const entryBinary = Uint8Array.from([1, 2, 3, 4]).buffer;
|
|
110
|
+
const zip = new JSZip();
|
|
111
|
+
zip.file('images/logo.bin', entryBinary);
|
|
112
|
+
const archiveBinary = await zip.generateAsync({ type: 'arraybuffer' });
|
|
113
|
+
const { preparedPlan } = createPreparedResourcePlan({
|
|
114
|
+
executor,
|
|
115
|
+
archiveBinary,
|
|
116
|
+
entryBinary,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
await expect(
|
|
120
|
+
readVerifiedPreparedResourceArchive({
|
|
121
|
+
preparedPlan,
|
|
122
|
+
reader: undefined,
|
|
123
|
+
})
|
|
124
|
+
).rejects.toMatchObject({
|
|
125
|
+
params: { firmwareUpdateCode: 'FirmwareArtifactReaderInvalid' },
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
108
129
|
test('uses canonical bytes extracted from the approved ZIP', async () => {
|
|
109
130
|
const entryBinary = Uint8Array.from([1, 2, 3, 4]).buffer;
|
|
110
131
|
const zip = new JSZip();
|
|
@@ -42,7 +42,12 @@ describe('FirmwareUpdateV4 install polling', () => {
|
|
|
42
42
|
|
|
43
43
|
method.device = {
|
|
44
44
|
getCommands: () => ({ typedCall, call }),
|
|
45
|
+
createProtocolV2UiPhaseMetadata: jest.fn().mockReturnValue(undefined),
|
|
46
|
+
toMessageObject: jest.fn().mockReturnValue({ connectId: 'pro2-ble' }),
|
|
47
|
+
setCancelableAction: jest.fn(),
|
|
48
|
+
clearCancelableAction: jest.fn(),
|
|
45
49
|
} as unknown as Device;
|
|
50
|
+
method.postMessage = jest.fn();
|
|
46
51
|
method.postTipMessage = jest.fn();
|
|
47
52
|
method.postProgressMessage = jest.fn();
|
|
48
53
|
|
|
@@ -31,25 +31,6 @@ const neoResourceSource = {
|
|
|
31
31
|
archiveSize: 12_345_678,
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
-
const pro2Features = {
|
|
35
|
-
deviceType: EDeviceType.Pro2,
|
|
36
|
-
firmwareVersion: '1.0.0',
|
|
37
|
-
} as unknown as Features;
|
|
38
|
-
|
|
39
|
-
const neoFeatures = {
|
|
40
|
-
deviceType: EDeviceType.Neo,
|
|
41
|
-
firmwareVersion: '1.0.0',
|
|
42
|
-
} as unknown as Features;
|
|
43
|
-
|
|
44
|
-
const createProtocolV2Release = (source: typeof resourceSource) => ({
|
|
45
|
-
required: false,
|
|
46
|
-
version: [1, 0, 0],
|
|
47
|
-
url: 'https://example.com/firmware.okpkg',
|
|
48
|
-
fingerprint: 'c'.repeat(64),
|
|
49
|
-
changelog: {},
|
|
50
|
-
resources: { source },
|
|
51
|
-
});
|
|
52
|
-
|
|
53
34
|
const manifestFiles = [
|
|
54
35
|
['bundles/firmware_logo-build.okpkg', 'firmware_logo.okpkg', 'vol0:/bundles/firmware_logo.okpkg'],
|
|
55
36
|
['bundles/font/noto-build.okpkg', 'noto.okpkg', 'vol0:/bundles/font/noto.okpkg'],
|
|
@@ -127,11 +108,38 @@ const createRemoteConfig = (): RemoteConfigResponse =>
|
|
|
127
108
|
mini: { firmware: [], ble: [] },
|
|
128
109
|
touch: { firmware: [], ble: [] },
|
|
129
110
|
pro: { firmware: [], ble: [] },
|
|
130
|
-
pro2: {
|
|
131
|
-
|
|
111
|
+
pro2: {
|
|
112
|
+
'firmware-v1': [
|
|
113
|
+
{
|
|
114
|
+
required: false,
|
|
115
|
+
version: [1, 0, 0],
|
|
116
|
+
url: 'https://example.com/pro2.okpkg',
|
|
117
|
+
fingerprint: 'a'.repeat(64),
|
|
118
|
+
changelog: { 'zh-CN': 'Pro2', 'en-US': 'Pro2' },
|
|
119
|
+
resources: { source: resourceSource },
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
ble: [],
|
|
123
|
+
},
|
|
124
|
+
neo: {
|
|
125
|
+
'firmware-v1': [
|
|
126
|
+
{
|
|
127
|
+
required: false,
|
|
128
|
+
version: [1, 0, 0],
|
|
129
|
+
url: 'https://example.com/neo.okpkg',
|
|
130
|
+
fingerprint: 'b'.repeat(64),
|
|
131
|
+
changelog: { 'zh-CN': 'Neo', 'en-US': 'Neo' },
|
|
132
|
+
resources: { source: neoResourceSource },
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
ble: [],
|
|
136
|
+
},
|
|
132
137
|
bridge: {},
|
|
133
138
|
} as unknown as RemoteConfigResponse);
|
|
134
139
|
|
|
140
|
+
const getProtocolV2Release = (deviceType: EDeviceType.Pro2 | EDeviceType.Neo) =>
|
|
141
|
+
DataManager.deviceMap[deviceType]?.['firmware-v1']?.[0];
|
|
142
|
+
|
|
135
143
|
describe('Pro2 resource configuration', () => {
|
|
136
144
|
beforeEach(() => {
|
|
137
145
|
jest.clearAllMocks();
|
|
@@ -203,52 +211,68 @@ describe('Pro2 resource configuration', () => {
|
|
|
203
211
|
expect(configFetcher).toHaveBeenCalledWith(
|
|
204
212
|
expect.stringMatching(/^https:\/\/data\.onekey\.so\/pre-config\.json\?noCache=/)
|
|
205
213
|
);
|
|
206
|
-
expect(DataManager.getProtocolV2ResourceSource(
|
|
214
|
+
expect(DataManager.getProtocolV2ResourceSource(getProtocolV2Release(EDeviceType.Pro2))).toEqual(
|
|
207
215
|
resourceSource
|
|
208
216
|
);
|
|
209
217
|
expect(DataManager.lastCheckTimestamp).toBeGreaterThan(0);
|
|
210
218
|
});
|
|
211
219
|
|
|
212
|
-
test('
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
220
|
+
test('uses the resource archive bound to the selected firmware release', async () => {
|
|
221
|
+
const newerResourceSource = {
|
|
222
|
+
archiveUrl: 'https://example.com/resource/pro2-resource-v2.zip',
|
|
223
|
+
archiveSha256: 'c'.repeat(64),
|
|
224
|
+
archiveSize: 20_000_000,
|
|
217
225
|
};
|
|
218
|
-
|
|
219
|
-
|
|
226
|
+
const remoteConfig = createRemoteConfig();
|
|
227
|
+
remoteConfig.pro2['firmware-v1']?.push({
|
|
228
|
+
...remoteConfig.pro2['firmware-v1'][0],
|
|
229
|
+
version: [2, 0, 0],
|
|
230
|
+
resources: { source: newerResourceSource },
|
|
231
|
+
});
|
|
220
232
|
|
|
221
233
|
await expect(
|
|
222
234
|
DataManager.load(createSettings(jest.fn().mockResolvedValue(remoteConfig)))
|
|
223
235
|
).resolves.toBe(true);
|
|
224
236
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
237
|
+
const selectedRelease = DataManager.getFirmwareLatestRelease(
|
|
238
|
+
{ deviceType: 'pro2', firmwareVersion: '1.0.0' } as Features,
|
|
239
|
+
EFirmwareType.Universal
|
|
240
|
+
);
|
|
241
|
+
expect(selectedRelease?.version).toEqual([2, 0, 0]);
|
|
242
|
+
expect(DataManager.getProtocolV2ResourceSource(selectedRelease)).toEqual(newerResourceSource);
|
|
228
243
|
});
|
|
229
244
|
|
|
230
|
-
test('
|
|
245
|
+
test('does not use a device-level Protocol V2 resource archive', async () => {
|
|
231
246
|
const remoteConfig = createRemoteConfig();
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
};
|
|
236
|
-
const latestRelease = {
|
|
237
|
-
...createProtocolV2Release(neoResourceSource),
|
|
238
|
-
version: [1, 1, 0],
|
|
247
|
+
delete remoteConfig.pro2['firmware-v1']?.[0].resources;
|
|
248
|
+
(remoteConfig.pro2 as unknown as { resources: unknown }).resources = {
|
|
249
|
+
source: resourceSource,
|
|
239
250
|
};
|
|
240
|
-
(remoteConfig.pro2 as { 'firmware-v1': unknown[] })['firmware-v1'] = [
|
|
241
|
-
olderRelease,
|
|
242
|
-
latestRelease,
|
|
243
|
-
];
|
|
244
251
|
|
|
245
252
|
await expect(
|
|
246
253
|
DataManager.load(createSettings(jest.fn().mockResolvedValue(remoteConfig)))
|
|
247
254
|
).resolves.toBe(true);
|
|
248
255
|
|
|
249
|
-
expect(
|
|
250
|
-
|
|
251
|
-
);
|
|
256
|
+
expect(
|
|
257
|
+
DataManager.getProtocolV2ResourceSource(getProtocolV2Release(EDeviceType.Pro2))
|
|
258
|
+
).toBeUndefined();
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
test('does not block the latest release when an older release has invalid resources', async () => {
|
|
262
|
+
const remoteConfig = createRemoteConfig();
|
|
263
|
+
(remoteConfig.pro2['firmware-v1']?.[0] as { resources?: unknown }).resources = { source: {} };
|
|
264
|
+
remoteConfig.pro2['firmware-v1']?.push({
|
|
265
|
+
...remoteConfig.pro2['firmware-v1'][0],
|
|
266
|
+
version: [2, 0, 0],
|
|
267
|
+
resources: { source: resourceSource },
|
|
268
|
+
});
|
|
269
|
+
const configFetcher = jest.fn().mockResolvedValue(remoteConfig);
|
|
270
|
+
|
|
271
|
+
await expect(DataManager.load(createSettings(configFetcher))).resolves.toBe(true);
|
|
272
|
+
await expect(DataManager.forceReloadData({ requireResources: true })).resolves.toBeUndefined();
|
|
273
|
+
|
|
274
|
+
const latestRelease = DataManager.deviceMap[EDeviceType.Pro2]?.['firmware-v1']?.[1];
|
|
275
|
+
expect(DataManager.getProtocolV2ResourceSource(latestRelease)).toEqual(resourceSource);
|
|
252
276
|
});
|
|
253
277
|
|
|
254
278
|
test('reuses the configuration fetched during SDK initialization for an immediate update', async () => {
|
|
@@ -263,40 +287,32 @@ describe('Pro2 resource configuration', () => {
|
|
|
263
287
|
|
|
264
288
|
test('keeps base SDK initialization available when remote Pro2 resources are invalid', async () => {
|
|
265
289
|
const remoteConfig = createRemoteConfig();
|
|
266
|
-
(
|
|
267
|
-
remoteConfig.pro2 as {
|
|
268
|
-
'firmware-v1': Array<{ resources?: unknown }>;
|
|
269
|
-
}
|
|
270
|
-
)['firmware-v1'][0].resources = { source: {} };
|
|
290
|
+
(remoteConfig.pro2['firmware-v1']?.[0] as { resources?: unknown }).resources = { source: {} };
|
|
271
291
|
const configFetcher = jest.fn().mockResolvedValue(remoteConfig);
|
|
272
292
|
|
|
273
293
|
await expect(DataManager.load(createSettings(configFetcher))).resolves.toBe(true);
|
|
274
294
|
|
|
275
295
|
expect(
|
|
276
|
-
DataManager.getProtocolV2ResourceSource(
|
|
296
|
+
DataManager.getProtocolV2ResourceSource(getProtocolV2Release(EDeviceType.Pro2))
|
|
277
297
|
).toBeUndefined();
|
|
278
298
|
expect(DataManager.protocolV2ResourcesConfigError).toBeInstanceOf(Error);
|
|
279
|
-
expect(DataManager.getProtocolV2ResourceSource(
|
|
299
|
+
expect(DataManager.getProtocolV2ResourceSource(getProtocolV2Release(EDeviceType.Neo))).toEqual(
|
|
280
300
|
neoResourceSource
|
|
281
301
|
);
|
|
282
302
|
});
|
|
283
303
|
|
|
284
304
|
test('keeps Pro2 resources available when remote Neo resources are invalid', async () => {
|
|
285
305
|
const remoteConfig = createRemoteConfig();
|
|
286
|
-
(
|
|
287
|
-
remoteConfig.neo as {
|
|
288
|
-
'firmware-v1': Array<{ resources?: unknown }>;
|
|
289
|
-
}
|
|
290
|
-
)['firmware-v1'][0].resources = { source: {} };
|
|
306
|
+
(remoteConfig.neo?.['firmware-v1']?.[0] as { resources?: unknown }).resources = { source: {} };
|
|
291
307
|
const configFetcher = jest.fn().mockResolvedValue(remoteConfig);
|
|
292
308
|
|
|
293
309
|
await expect(DataManager.load(createSettings(configFetcher))).resolves.toBe(true);
|
|
294
310
|
|
|
295
|
-
expect(DataManager.getProtocolV2ResourceSource(
|
|
311
|
+
expect(DataManager.getProtocolV2ResourceSource(getProtocolV2Release(EDeviceType.Pro2))).toEqual(
|
|
296
312
|
resourceSource
|
|
297
313
|
);
|
|
298
314
|
expect(
|
|
299
|
-
DataManager.getProtocolV2ResourceSource(
|
|
315
|
+
DataManager.getProtocolV2ResourceSource(getProtocolV2Release(EDeviceType.Neo))
|
|
300
316
|
).toBeUndefined();
|
|
301
317
|
await expect(
|
|
302
318
|
DataManager.forceReloadData({
|
|
@@ -317,11 +333,7 @@ describe('Pro2 resource configuration', () => {
|
|
|
317
333
|
|
|
318
334
|
test('only blocks resource mutation when the refreshed Pro2 resources are invalid', async () => {
|
|
319
335
|
const remoteConfig = createRemoteConfig();
|
|
320
|
-
(
|
|
321
|
-
remoteConfig.pro2 as {
|
|
322
|
-
'firmware-v1': Array<{ resources?: unknown }>;
|
|
323
|
-
}
|
|
324
|
-
)['firmware-v1'][0].resources = { source: {} };
|
|
336
|
+
(remoteConfig.pro2['firmware-v1']?.[0] as { resources?: unknown }).resources = { source: {} };
|
|
325
337
|
const settings = createSettings(jest.fn().mockResolvedValue(remoteConfig));
|
|
326
338
|
DataManager.settings = settings;
|
|
327
339
|
|
|
@@ -335,11 +347,7 @@ describe('Pro2 resource configuration', () => {
|
|
|
335
347
|
|
|
336
348
|
test('checks resource configuration errors for the requested device only', async () => {
|
|
337
349
|
const remoteConfig = createRemoteConfig();
|
|
338
|
-
(
|
|
339
|
-
remoteConfig.pro2 as {
|
|
340
|
-
'firmware-v1': Array<{ resources?: unknown }>;
|
|
341
|
-
}
|
|
342
|
-
)['firmware-v1'][0].resources = { source: {} };
|
|
350
|
+
(remoteConfig.pro2['firmware-v1']?.[0] as { resources?: unknown }).resources = { source: {} };
|
|
343
351
|
const settings = createSettings(jest.fn().mockResolvedValue(remoteConfig));
|
|
344
352
|
DataManager.settings = settings;
|
|
345
353
|
|
|
@@ -211,7 +211,7 @@ describe('DeviceUploadWallpaper', () => {
|
|
|
211
211
|
const result = await method.run();
|
|
212
212
|
|
|
213
213
|
expect(method.getSupportedProtocols()).toEqual(['V2']);
|
|
214
|
-
expect(method.unlockPolicy).toBe('
|
|
214
|
+
expect(method.unlockPolicy).toBe('none');
|
|
215
215
|
expect(typedCall).toHaveBeenNthCalledWith(1, 'FilesystemDirMake', 'Success', {
|
|
216
216
|
path: 'vol1:/wallpapers',
|
|
217
217
|
});
|
|
@@ -514,6 +514,10 @@ function stubDevice<T extends Record<string, any>>(device: T): T {
|
|
|
514
514
|
const d = device as any;
|
|
515
515
|
d.updateState ??= jest.fn();
|
|
516
516
|
d.markProtocolV2Reboot ??= jest.fn();
|
|
517
|
+
d.setCancelableAction ??= jest.fn();
|
|
518
|
+
d.clearCancelableAction ??= jest.fn();
|
|
519
|
+
d.toMessageObject ??= jest.fn(() => ({ connectId: d.originalDescriptor?.id }));
|
|
520
|
+
d.createProtocolV2UiPhaseMetadata ??= jest.fn(() => undefined);
|
|
517
521
|
d.isProtocolV2 ??= () => d.originalDescriptor?.protocolType === 'V2';
|
|
518
522
|
d.isBootloader ??= () => d.features?.mode === 'bootloader';
|
|
519
523
|
d.isRomloader ??= () => d.features?.mode === 'romloader';
|
|
@@ -4271,7 +4275,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
4271
4275
|
});
|
|
4272
4276
|
(method as any).protocolV2Reboot = jest.fn();
|
|
4273
4277
|
(method as any).enterProtocolV2BootloaderMode = jest.fn().mockResolvedValue(true);
|
|
4274
|
-
method.
|
|
4278
|
+
method.postMessage = jest.fn();
|
|
4275
4279
|
|
|
4276
4280
|
await method.run();
|
|
4277
4281
|
|
|
@@ -5254,10 +5258,26 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5254
5258
|
const targets = [{ target_id: 4, path: 'vol1:firmware.bin' }];
|
|
5255
5259
|
const typedCall = jest.fn().mockResolvedValue({ type: 'Success', message: {} });
|
|
5256
5260
|
const call = jest.fn().mockResolvedValue({ type: 'WriteCompleted', message: {} });
|
|
5261
|
+
const cancelDevice = jest.fn().mockResolvedValue(undefined);
|
|
5262
|
+
let cancelableAction: (() => Promise<unknown>) | undefined;
|
|
5263
|
+
const interaction = {
|
|
5264
|
+
interactionId: 'firmware-update',
|
|
5265
|
+
phaseId: 'firmware-update:phase-1',
|
|
5266
|
+
sequence: 1,
|
|
5267
|
+
phase: 'button',
|
|
5268
|
+
transition: 'start',
|
|
5269
|
+
protocol: 'V2',
|
|
5270
|
+
};
|
|
5257
5271
|
|
|
5258
5272
|
(method as any).device = stubDevice({
|
|
5259
|
-
getCommands: () => ({ typedCall, call }),
|
|
5273
|
+
getCommands: () => ({ typedCall, call, cancelDevice }),
|
|
5274
|
+
createProtocolV2UiPhaseMetadata: jest.fn().mockReturnValue(interaction),
|
|
5275
|
+
toMessageObject: jest.fn().mockReturnValue({ connectId: 'pro2' }),
|
|
5276
|
+
setCancelableAction: jest.fn(action => {
|
|
5277
|
+
cancelableAction = action;
|
|
5278
|
+
}),
|
|
5260
5279
|
});
|
|
5280
|
+
method.postMessage = jest.fn();
|
|
5261
5281
|
method.postTipMessage = jest.fn();
|
|
5262
5282
|
method.postProgressMessage = jest.fn();
|
|
5263
5283
|
|
|
@@ -5266,14 +5286,32 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5266
5286
|
).resolves.toBeUndefined();
|
|
5267
5287
|
|
|
5268
5288
|
expect(typedCall).toHaveBeenCalledWith('DeviceFirmwareUpdateStage', 'Success', { targets });
|
|
5289
|
+
expect(method.postMessage).toHaveBeenCalledWith({
|
|
5290
|
+
event: 'UI_EVENT',
|
|
5291
|
+
type: UI_REQUEST.REQUEST_BUTTON,
|
|
5292
|
+
payload: {
|
|
5293
|
+
device: { connectId: 'pro2' },
|
|
5294
|
+
source: 'method-lifecycle',
|
|
5295
|
+
reason: 'firmware-update',
|
|
5296
|
+
completion: 'operation-completed',
|
|
5297
|
+
deviceOnly: true,
|
|
5298
|
+
operation: 'firmwareUpdateV4',
|
|
5299
|
+
interaction,
|
|
5300
|
+
},
|
|
5301
|
+
});
|
|
5269
5302
|
expect(call).toHaveBeenCalledWith(
|
|
5270
5303
|
'DeviceFirmwareUpdateRequest',
|
|
5271
5304
|
{},
|
|
5272
5305
|
{ returnAfterWrite: true }
|
|
5273
5306
|
);
|
|
5274
5307
|
expect(typedCall.mock.invocationCallOrder[0]).toBeLessThan(call.mock.invocationCallOrder[0]);
|
|
5275
|
-
expect(method.
|
|
5308
|
+
expect((method.postMessage as jest.Mock).mock.invocationCallOrder[0]).toBeLessThan(
|
|
5309
|
+
call.mock.invocationCallOrder[0]
|
|
5310
|
+
);
|
|
5311
|
+
expect(method.postTipMessage).not.toHaveBeenCalled();
|
|
5276
5312
|
expect(method.postProgressMessage).not.toHaveBeenCalled();
|
|
5313
|
+
await cancelableAction?.();
|
|
5314
|
+
expect(cancelDevice).toHaveBeenCalledTimes(1);
|
|
5277
5315
|
});
|
|
5278
5316
|
|
|
5279
5317
|
test('does not send the install request when Protocol V2 staging fails', async () => {
|
|
@@ -5289,6 +5327,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5289
5327
|
(method as any).device = stubDevice({
|
|
5290
5328
|
getCommands: () => ({ typedCall, call }),
|
|
5291
5329
|
});
|
|
5330
|
+
method.postMessage = jest.fn();
|
|
5292
5331
|
method.postTipMessage = jest.fn();
|
|
5293
5332
|
method.postProgressMessage = jest.fn();
|
|
5294
5333
|
|
|
@@ -5299,6 +5338,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5299
5338
|
).rejects.toThrow('stage failed');
|
|
5300
5339
|
|
|
5301
5340
|
expect(call).not.toHaveBeenCalled();
|
|
5341
|
+
expect(method.postMessage).not.toHaveBeenCalled();
|
|
5302
5342
|
expect(method.postTipMessage).not.toHaveBeenCalled();
|
|
5303
5343
|
expect(method.postProgressMessage).not.toHaveBeenCalled();
|
|
5304
5344
|
});
|
|
@@ -5315,7 +5355,10 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5315
5355
|
|
|
5316
5356
|
(method as any).device = stubDevice({
|
|
5317
5357
|
getCommands: () => ({ typedCall, call }),
|
|
5358
|
+
createProtocolV2UiPhaseMetadata: jest.fn().mockReturnValue(undefined),
|
|
5359
|
+
toMessageObject: jest.fn().mockReturnValue({ connectId: 'pro2' }),
|
|
5318
5360
|
});
|
|
5361
|
+
method.postMessage = jest.fn();
|
|
5319
5362
|
method.postTipMessage = jest.fn();
|
|
5320
5363
|
method.postProgressMessage = jest.fn();
|
|
5321
5364
|
|
|
@@ -5347,16 +5390,14 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5347
5390
|
type: 'DeviceFirmwareUpdateStatus',
|
|
5348
5391
|
message: { records: [{ target_id: 4, status: 2 }] },
|
|
5349
5392
|
});
|
|
5350
|
-
const reconnectProtocolV2Device = jest
|
|
5351
|
-
|
|
5352
|
-
.mockRejectedValueOnce(new Error('Device rebooting'))
|
|
5353
|
-
.mockResolvedValue(undefined);
|
|
5393
|
+
const reconnectProtocolV2Device = jest.fn();
|
|
5394
|
+
const verifyProtocolV2ReconnectIdentity = jest.fn();
|
|
5354
5395
|
|
|
5355
5396
|
(method as any).device = stubDevice({
|
|
5356
5397
|
getCommands: () => ({ typedCall }),
|
|
5357
5398
|
});
|
|
5358
5399
|
(method as any).reconnectProtocolV2Device = reconnectProtocolV2Device;
|
|
5359
|
-
(method as any).verifyProtocolV2ReconnectIdentity =
|
|
5400
|
+
(method as any).verifyProtocolV2ReconnectIdentity = verifyProtocolV2ReconnectIdentity;
|
|
5360
5401
|
method.postProgressMessage = jest.fn();
|
|
5361
5402
|
method.postTipMessage = jest.fn();
|
|
5362
5403
|
|
|
@@ -5364,7 +5405,8 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5364
5405
|
{ target_id: 4, path: 'vol0:/application_p1.bin' },
|
|
5365
5406
|
]);
|
|
5366
5407
|
|
|
5367
|
-
expect(reconnectProtocolV2Device).
|
|
5408
|
+
expect(reconnectProtocolV2Device).not.toHaveBeenCalled();
|
|
5409
|
+
expect(verifyProtocolV2ReconnectIdentity).not.toHaveBeenCalled();
|
|
5368
5410
|
expect(typedCall.mock.calls.map(call => call[0])).toEqual([
|
|
5369
5411
|
'DeviceFirmwareUpdateStatusGet',
|
|
5370
5412
|
'DeviceFirmwareUpdateStatusGet',
|
|
@@ -5410,7 +5452,6 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5410
5452
|
(method as any).reconnectProtocolV2Device = reconnectProtocolV2Device;
|
|
5411
5453
|
(method as any).verifyProtocolV2ReconnectIdentity = jest.fn().mockResolvedValue(undefined);
|
|
5412
5454
|
method.postProgressMessage = jest.fn();
|
|
5413
|
-
method.postTipMessage = jest.fn();
|
|
5414
5455
|
|
|
5415
5456
|
try {
|
|
5416
5457
|
await (method as any).waitForProtocolV2FirmwareUpdateComplete([
|
|
@@ -5420,7 +5461,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5420
5461
|
setTimeoutSpy.mockRestore();
|
|
5421
5462
|
}
|
|
5422
5463
|
|
|
5423
|
-
expect(reconnectProtocolV2Device).
|
|
5464
|
+
expect(reconnectProtocolV2Device).not.toHaveBeenCalled();
|
|
5424
5465
|
expect(typedCall.mock.calls.map(call => call[0])).toEqual([
|
|
5425
5466
|
'DeviceFirmwareUpdateStatusGet',
|
|
5426
5467
|
'DeviceFirmwareUpdateStatusGet',
|
|
@@ -5465,7 +5506,6 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5465
5506
|
(method as any).reconnectProtocolV2Device = jest.fn().mockResolvedValue(undefined);
|
|
5466
5507
|
(method as any).verifyProtocolV2ReconnectIdentity = jest.fn().mockResolvedValue(undefined);
|
|
5467
5508
|
method.postProgressMessage = jest.fn();
|
|
5468
|
-
method.postTipMessage = jest.fn();
|
|
5469
5509
|
|
|
5470
5510
|
try {
|
|
5471
5511
|
await (method as any).waitForProtocolV2FirmwareUpdateComplete(
|
|
@@ -5477,50 +5517,9 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5477
5517
|
}
|
|
5478
5518
|
|
|
5479
5519
|
expect(typedCall).toHaveBeenCalledTimes(3);
|
|
5480
|
-
expect(method.postTipMessage).toHaveBeenCalledTimes(1);
|
|
5481
|
-
expect(method.postTipMessage).toHaveBeenCalledWith('FirmwareUpdating');
|
|
5482
5520
|
expect(method.postProgressMessage).toHaveBeenCalledWith(100, 'installingFirmware');
|
|
5483
5521
|
});
|
|
5484
5522
|
|
|
5485
|
-
test('reports missing current target records as unconfirmed device installation', async () => {
|
|
5486
|
-
const method = new FirmwareUpdateV4({
|
|
5487
|
-
id: 1,
|
|
5488
|
-
payload: {
|
|
5489
|
-
method: 'firmwareUpdateV4',
|
|
5490
|
-
},
|
|
5491
|
-
});
|
|
5492
|
-
const typedCall = jest.fn().mockResolvedValue({
|
|
5493
|
-
type: 'DeviceFirmwareUpdateStatus',
|
|
5494
|
-
message: {
|
|
5495
|
-
records: [{ target_id: 7, status: 2 }],
|
|
5496
|
-
},
|
|
5497
|
-
});
|
|
5498
|
-
let now = 0;
|
|
5499
|
-
jest.spyOn(Date, 'now').mockImplementation(() => now);
|
|
5500
|
-
jest.spyOn(global, 'setTimeout').mockImplementation(((callback: () => void) => {
|
|
5501
|
-
now += 31 * 1000;
|
|
5502
|
-
callback();
|
|
5503
|
-
return 0 as any;
|
|
5504
|
-
}) as typeof setTimeout);
|
|
5505
|
-
|
|
5506
|
-
(method as any).device = stubDevice({
|
|
5507
|
-
getCommands: () => ({ typedCall }),
|
|
5508
|
-
});
|
|
5509
|
-
(method as any).reconnectProtocolV2Device = jest.fn().mockResolvedValue(undefined);
|
|
5510
|
-
(method as any).verifyProtocolV2ReconnectIdentity = jest.fn().mockResolvedValue(undefined);
|
|
5511
|
-
|
|
5512
|
-
await expect(
|
|
5513
|
-
(method as any).waitForProtocolV2FirmwareUpdateComplete(
|
|
5514
|
-
[{ target_id: 4, path: 'vol0:/application_p1.bin' }],
|
|
5515
|
-
true
|
|
5516
|
-
)
|
|
5517
|
-
).rejects.toMatchObject({
|
|
5518
|
-
errorCode: HardwareErrorCode.FirmwareError,
|
|
5519
|
-
message: expect.stringContaining('was not confirmed on the device'),
|
|
5520
|
-
});
|
|
5521
|
-
expect(typedCall).toHaveBeenCalledTimes(2);
|
|
5522
|
-
});
|
|
5523
|
-
|
|
5524
5523
|
test('ignores stale finished records until the current install starts', async () => {
|
|
5525
5524
|
const method = new FirmwareUpdateV4({
|
|
5526
5525
|
id: 1,
|
|
@@ -5750,7 +5749,9 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5750
5749
|
'DeviceFirmwareUpdateStatusGet',
|
|
5751
5750
|
'DeviceFirmwareUpdateStatusGet',
|
|
5752
5751
|
]);
|
|
5753
|
-
expect((method as any).
|
|
5752
|
+
expect((method as any).reconnectProtocolV2Device).toHaveBeenCalledTimes(1);
|
|
5753
|
+
expect((method as any).verifyProtocolV2ReconnectIdentity).toHaveBeenCalledTimes(1);
|
|
5754
|
+
expect((method as any).probeProtocolV2NormalMode).not.toHaveBeenCalled();
|
|
5754
5755
|
});
|
|
5755
5756
|
|
|
5756
5757
|
test('rejects a finished target whose payload version conflicts with the plan', () => {
|
|
@@ -5960,7 +5961,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5960
5961
|
])
|
|
5961
5962
|
).resolves.toBeUndefined();
|
|
5962
5963
|
|
|
5963
|
-
expect(reconnectProtocolV2Device).
|
|
5964
|
+
expect(reconnectProtocolV2Device).not.toHaveBeenCalled();
|
|
5964
5965
|
expect(typedCall).toHaveBeenCalledWith(
|
|
5965
5966
|
'DeviceFirmwareUpdateStatusGet',
|
|
5966
5967
|
['DeviceFirmwareUpdateStatus', 'Success'],
|
|
@@ -6059,7 +6060,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6059
6060
|
{ target_id: 4, path: 'vol0:/application_p1.bin' },
|
|
6060
6061
|
])
|
|
6061
6062
|
).resolves.toBeUndefined();
|
|
6062
|
-
expect(reconnectProtocolV2Device).toHaveBeenCalledTimes(
|
|
6063
|
+
expect(reconnectProtocolV2Device).toHaveBeenCalledTimes(1);
|
|
6063
6064
|
expect(typedCall).toHaveBeenCalledTimes(4);
|
|
6064
6065
|
});
|
|
6065
6066
|
|
|
@@ -8470,7 +8471,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
8470
8471
|
expect(writePayloads.map(payload => payload.file.data.byteLength)).toEqual([1960, 1]);
|
|
8471
8472
|
});
|
|
8472
8473
|
|
|
8473
|
-
test('
|
|
8474
|
+
test('keeps the confirmation UI active after Stage and the empty Request are written', async () => {
|
|
8474
8475
|
const method = new FirmwareUpdateV4({
|
|
8475
8476
|
id: 1,
|
|
8476
8477
|
payload: {
|
|
@@ -8488,7 +8489,10 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
8488
8489
|
|
|
8489
8490
|
(method as any).device = stubDevice({
|
|
8490
8491
|
getCommands: () => ({ typedCall, call }),
|
|
8492
|
+
createProtocolV2UiPhaseMetadata: jest.fn().mockReturnValue(undefined),
|
|
8493
|
+
toMessageObject: jest.fn().mockReturnValue({ connectId: 'pro2' }),
|
|
8491
8494
|
});
|
|
8495
|
+
method.postMessage = jest.fn();
|
|
8492
8496
|
method.postProgressMessage = jest.fn();
|
|
8493
8497
|
method.postTipMessage = jest.fn();
|
|
8494
8498
|
|
|
@@ -8514,9 +8518,8 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
8514
8518
|
|
|
8515
8519
|
resolveWrite?.({ type: 'WriteCompleted', message: {} });
|
|
8516
8520
|
await startPromise;
|
|
8517
|
-
expect(method.postTipMessage).
|
|
8521
|
+
expect(method.postTipMessage).not.toHaveBeenCalled();
|
|
8518
8522
|
expect(method.postProgressMessage).not.toHaveBeenCalled();
|
|
8519
|
-
expect(method.postTipMessage).toHaveBeenCalledTimes(1);
|
|
8520
8523
|
});
|
|
8521
8524
|
|
|
8522
8525
|
test('sends an empty Protocol V2 firmware install request without waiting for its response', async () => {
|
|
@@ -8534,7 +8537,10 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
8534
8537
|
|
|
8535
8538
|
(method as any).device = stubDevice({
|
|
8536
8539
|
getCommands: () => ({ typedCall, call }),
|
|
8540
|
+
createProtocolV2UiPhaseMetadata: jest.fn().mockReturnValue(undefined),
|
|
8541
|
+
toMessageObject: jest.fn().mockReturnValue({ connectId: 'pro2' }),
|
|
8537
8542
|
});
|
|
8543
|
+
method.postMessage = jest.fn();
|
|
8538
8544
|
method.postProgressMessage = jest.fn();
|
|
8539
8545
|
method.postTipMessage = jest.fn();
|
|
8540
8546
|
|
|
@@ -8548,7 +8554,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
8548
8554
|
{},
|
|
8549
8555
|
{ returnAfterWrite: true }
|
|
8550
8556
|
);
|
|
8551
|
-
expect(method.postTipMessage).
|
|
8557
|
+
expect(method.postTipMessage).not.toHaveBeenCalled();
|
|
8552
8558
|
});
|
|
8553
8559
|
});
|
|
8554
8560
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkD,MAAM,qBAAqB,CAAC;AAyBlG,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAkC/E,OAAO,KAAK,EAEV,sBAAsB,EAEvB,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkD,MAAM,qBAAqB,CAAC;AAyBlG,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAkC/E,OAAO,KAAK,EAEV,sBAAsB,EAEvB,MAAM,6BAA6B,CAAC;AAoFrC,wBAAgB,wCAAwC,CACtD,UAAU,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,EAC5C,MAAM,EAAE,sBAAsB,EAC9B,0BAA0B,UAAQ,QAiCnC;AAsVD,eAAO,MAAM,oCAAoC,WACvC,WAAW,GAAG,UAAU,eACnB,MAAM,GAAG,SAAS,YAKhC,CAAC;AAEF,eAAO,MAAM,iCAAiC,0BACrB,MAAM,uBACR,MAAM,iBACZ,MAAM,eACR,MAAM,SAsBpB,CAAC;AAUF,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,wBAAwB,CAAC,sBAAsB,CAAC;IAC5F,OAAO,CAAC,8BAA8B,CAAC,CAAS;IAEhD,OAAO,CAAC,sBAAsB,CAAC,CAAS;IAExC,OAAO,CAAC,oCAAoC,CAAS;IAErD,qBAAqB;IAIrB,OAAO,CAAC,yBAAyB,CAA4B;IAE7D,OAAO,CAAC,2BAA2B,CAAS;IAE5C,OAAO,CAAC,iCAAiC,CAAS;IAElD,OAAO,CAAC,iCAAiC,CAA6B;IAEtE,OAAO,CAAC,6BAA6B,CAAC,CAAW;IAEjD,OAAO,CAAC,6BAA6B,CAAS;IAE9C,OAAO,CAAC,iCAAiC,CAA6B;IAEtE,OAAO,CAAC,kCAAkC,CAAC,CAAW;IAEtD,IAAI;IA0LJ,OAAO,CAAC,8BAA8B;IAwBhC,GAAG;;;;;YAKK,aAAa;YAyJb,4BAA4B;YAkB5B,0BAA0B;YAY1B,8BAA8B;YAK9B,+BAA+B;YAqG/B,gCAAgC;YAiIhC,qCAAqC;YAmJrC,gCAAgC;YAgBhC,uCAAuC;YA+HvC,8BAA8B;IA8B5C,OAAO,CAAC,8BAA8B;IA0BtC,OAAO,CAAC,kCAAkC;IAc1C,OAAO,CAAC,gCAAgC;IAsDxC,OAAO,CAAC,6BAA6B;YAsBvB,2BAA2B;IAWzC,OAAO,CAAC,yBAAyB;IAKjC,OAAO,CAAC,oCAAoC;IAY5C,OAAO,CAAC,4BAA4B;IAUpC,OAAO,CAAC,kCAAkC;IAS1C,OAAO,CAAC,8BAA8B;YAMxB,iCAAiC;YAOjC,iCAAiC;YAmBjC,iCAAiC;IAM/C,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,mCAAmC;IAe3C,OAAO,CAAC,iCAAiC;IAWzC,OAAO,CAAC,2BAA2B;IAsBnC,OAAO,CAAC,yBAAyB;IAiBjC,OAAO,CAAC,wBAAwB;YAkBlB,iCAAiC;YA6CjC,uCAAuC;YA0CvC,+BAA+B;IA6E7C,OAAO,CAAC,6BAA6B;YAMvB,8BAA8B;YA+C9B,kCAAkC;IA+BhD,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,yBAAyB;YAcnB,4BAA4B;IAkBpC,6BAA6B;YAkBrB,+BAA+B;IAkD7C,OAAO,CAAC,6BAA6B;YAkCvB,6BAA6B;YA0B7B,0CAA0C;YA6B1C,uBAAuB;YAiCvB,8BAA8B;YA0E9B,6BAA6B;IAuE3C,OAAO,CAAC,mCAAmC;YAI7B,0BAA0B;IAaxC,OAAO,CAAC,4BAA4B;IAyGpC,OAAO,CAAC,6BAA6B;IAcrC,OAAO,CAAC,qCAAqC;IAyB7C,OAAO,CAAC,kCAAkC;YAgB5B,uCAAuC;YAwPvC,gCAAgC;YAehC,yBAAyB;IASvC,OAAO,CAAC,2BAA2B;YAMrB,8BAA8B;IAQ5C,OAAO,CAAC,0BAA0B;YAkBpB,mCAAmC;YAWnC,qCAAqC;YAiDrC,yBAAyB;YA8DzB,8BAA8B;IAU5C,OAAO,CAAC,kCAAkC;YAQ5B,cAAc;YAuCd,6BAA6B;YAW7B,0BAA0B;YAS1B,6BAA6B;YAwB7B,gBAAgB;IAiB9B,OAAO,CAAC,qBAAqB;CAM9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FirmwarePreparedResourceArchive.d.ts","sourceRoot":"","sources":["../../../src/api/firmware/FirmwarePreparedResourceArchive.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,4CAA4C,CAAC;AAY7F,MAAM,MAAM,6BAA6B,GAAG;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;CACrB,CAAC;
|
|
1
|
+
{"version":3,"file":"FirmwarePreparedResourceArchive.d.ts","sourceRoot":"","sources":["../../../src/api/firmware/FirmwarePreparedResourceArchive.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,4CAA4C,CAAC;AAY7F,MAAM,MAAM,6BAA6B,GAAG;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;CACrB,CAAC;AAmCF,eAAO,MAAM,mCAAmC;kBAIhC,0BAA0B;YAChC,sBAAsB,GAAG,SAAS;MACxC,QAAQ,6BAA6B,EAAE,CAkI1C,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EDeviceType, EFirmwareType } from '@onekeyfe/hd-shared';
|
|
2
|
-
import type { AssetsMap, ConnectSettings, DeviceTypeMap, Features, IDeviceBLEFirmwareStatus, IDeviceFirmwareStatus, ITransportStatus, IVersionArray } from '../types';
|
|
2
|
+
import type { AssetsMap, ConnectSettings, DeviceTypeMap, Features, IDeviceBLEFirmwareStatus, IDeviceFirmwareStatus, IFirmwareReleaseInfo, ITransportStatus, IVersionArray } from '../types';
|
|
3
3
|
export declare const FIRMWARE_FIELDS: readonly ["firmware", "firmware-v1", "firmware-v2", "firmware-v8", "firmware-btc-v8"];
|
|
4
4
|
export type IFirmwareField = (typeof FIRMWARE_FIELDS)[number];
|
|
5
5
|
export type ProtocolV1MessageSchema = 'v1CurrentSchema' | 'v1LegacySchema';
|
|
@@ -30,7 +30,7 @@ export default class DataManager {
|
|
|
30
30
|
"zh-CN": string;
|
|
31
31
|
"en-US": string;
|
|
32
32
|
}[];
|
|
33
|
-
static getFirmwareLatestRelease: (features: Features, firmwareType: EFirmwareType) =>
|
|
33
|
+
static getFirmwareLatestRelease: (features: Features, firmwareType: EFirmwareType) => IFirmwareReleaseInfo | undefined;
|
|
34
34
|
static getBLEFirmwareStatus: (features: Features) => IDeviceBLEFirmwareStatus;
|
|
35
35
|
static getBleFirmwareChangelog: (features: Features) => {
|
|
36
36
|
"zh-CN": string;
|
|
@@ -52,7 +52,7 @@ export default class DataManager {
|
|
|
52
52
|
requireResources?: boolean;
|
|
53
53
|
resourceDeviceType?: EDeviceType.Pro2 | EDeviceType.Neo;
|
|
54
54
|
}): Promise<void>;
|
|
55
|
-
static getProtocolV2ResourceSource(
|
|
55
|
+
static getProtocolV2ResourceSource(release: IFirmwareReleaseInfo | undefined): import("../types").IProtocolV2ResourceSource | undefined;
|
|
56
56
|
static getProtobufMessages(schema?: ProtobufMessageSchema): JSON;
|
|
57
57
|
static getSettings(key?: undefined): ConnectSettings;
|
|
58
58
|
static getSettings<T extends keyof ConnectSettings>(key: T): ConnectSettings[T];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataManager.d.ts","sourceRoot":"","sources":["../../src/data-manager/DataManager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,aAAa,EAA6B,MAAM,qBAAqB,CAAC;AAmB5F,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,aAAa,EACb,QAAQ,EACR,wBAAwB,EACxB,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EAEd,MAAM,UAAU,CAAC;AAMlB,eAAO,MAAM,eAAe,uFAMlB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AAC3E,MAAM,MAAM,qBAAqB,GAAG,uBAAuB,GAAG,UAAU,CAAC;AAsBzE,MAAM,CAAC,OAAO,OAAO,WAAW;IAC9B,MAAM,CAAC,SAAS,EAAE,aAAa,GAAG;QAChC,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,aAAa,CAAC,MAAM,aAAa,CAAC,CAAC,GAAG,SAAS,CAAC;KAC1E,CA+BC;IAEF,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAQ;IAEvC,MAAM,CAAC,QAAQ,EAAE,eAAe,CAAC;IAEjC,MAAM,CAAC,QAAQ,EAAE;SAAG,MAAM,IAAI,qBAAqB,GAAG,IAAI;KAAE,CAI1D;IAEF,MAAM,CAAC,kBAAkB,SAAK;IAE9B,MAAM,CAAC,8BAA8B,EAAE,KAAK,GAAG,SAAS,CAAC;IAEzD,OAAO,CAAC,MAAM,CAAC,iCAAiC,CAAoB;IAEpE,MAAM,CAAC,iBAAiB,aACZ,QAAQ,gBACJ,aAAa,KAC1B,qBAAqB,CAyBtB;IAMF,MAAM,CAAC,4BAA4B;kBAKvB,QAAQ;;sBAEJ,aAAa;6BAqB3B;IAMF,MAAM,CAAC,kBAAkB,aAAc,QAAQ,gBAAgB,aAAa,wBAe1E;IAEF,MAAM,CAAC,qBAAqB,aAAc,QAAQ,gBAAgB,aAAa,wBAmB7E;IAEF,MAAM,CAAC,0BAA0B,aACrB,QAAQ,gBACJ,aAAa,KAC1B,aAAa,GAAG,SAAS,CAa1B;IAEF,MAAM,CAAC,mCAAmC,aAC9B,QAAQ,gBACJ,aAAa,KAC1B,aAAa,GAAG,SAAS,CAgB1B;IAEF,MAAM,CAAC,oBAAoB,aAAc,QAAQ,gBAAgB,aAAa;;;QAuB5E;IAEF,MAAM,CAAC,wBAAwB,aAAc,QAAQ,gBAAgB,aAAa,
|
|
1
|
+
{"version":3,"file":"DataManager.d.ts","sourceRoot":"","sources":["../../src/data-manager/DataManager.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -259,7 +259,7 @@ type IFirmwareReleaseInfo = {
|
|
|
259
259
|
upgradeType?: 'payload-package-set' | string;
|
|
260
260
|
components?: Record<string, IProtocolV2FirmwareComponent>;
|
|
261
261
|
installOrder?: string[];
|
|
262
|
-
/**
|
|
262
|
+
/** Protocol V2 resources matched to this firmware release. */
|
|
263
263
|
resources?: IProtocolV2Resources;
|
|
264
264
|
bootloaderChangelog?: {
|
|
265
265
|
[k in ILocale]: string;
|
|
@@ -4735,7 +4735,7 @@ declare class DataManager {
|
|
|
4735
4735
|
requireResources?: boolean;
|
|
4736
4736
|
resourceDeviceType?: EDeviceType.Pro2 | EDeviceType.Neo;
|
|
4737
4737
|
}): Promise<void>;
|
|
4738
|
-
static getProtocolV2ResourceSource(
|
|
4738
|
+
static getProtocolV2ResourceSource(release: IFirmwareReleaseInfo | undefined): IProtocolV2ResourceSource | undefined;
|
|
4739
4739
|
static getProtobufMessages(schema?: ProtobufMessageSchema): JSON;
|
|
4740
4740
|
static getSettings(key?: undefined): ConnectSettings;
|
|
4741
4741
|
static getSettings<T extends keyof ConnectSettings>(key: T): ConnectSettings[T];
|
package/dist/index.js
CHANGED
|
@@ -40850,24 +40850,23 @@ class DataManager {
|
|
|
40850
40850
|
});
|
|
40851
40851
|
return enrichedData;
|
|
40852
40852
|
}
|
|
40853
|
-
static enrichProtocolV2FirmwareReleaseInfo(deviceData,
|
|
40853
|
+
static enrichProtocolV2FirmwareReleaseInfo(deviceData, onResourcesError) {
|
|
40854
40854
|
const enrichedData = this.enrichFirmwareReleaseInfo(deviceData);
|
|
40855
|
-
const
|
|
40856
|
-
const releases = releaseScopedData['firmware-v1'];
|
|
40855
|
+
const releases = enrichedData['firmware-v1'];
|
|
40857
40856
|
if (!Array.isArray(releases)) {
|
|
40858
|
-
return
|
|
40857
|
+
return enrichedData;
|
|
40859
40858
|
}
|
|
40860
|
-
|
|
40859
|
+
const latestRelease = findLatestRelease(releases);
|
|
40860
|
+
return Object.assign(Object.assign({}, enrichedData), { 'firmware-v1': releases.map(release => {
|
|
40861
40861
|
const { resources: rawResources } = release, releaseWithoutResources = __rest(release, ["resources"]);
|
|
40862
40862
|
try {
|
|
40863
40863
|
const resources = parseProtocolV2Resources(rawResources);
|
|
40864
|
-
return resources
|
|
40865
|
-
? Object.assign(Object.assign({}, releaseWithoutResources), { resources }) : releaseWithoutResources;
|
|
40864
|
+
return Object.assign(Object.assign({}, releaseWithoutResources), (resources ? { resources } : undefined));
|
|
40866
40865
|
}
|
|
40867
40866
|
catch (error) {
|
|
40868
|
-
|
|
40869
|
-
|
|
40870
|
-
|
|
40867
|
+
if (release === latestRelease) {
|
|
40868
|
+
onResourcesError(error instanceof Error ? error : new Error(String(error)));
|
|
40869
|
+
}
|
|
40871
40870
|
return releaseWithoutResources;
|
|
40872
40871
|
}
|
|
40873
40872
|
}) });
|
|
@@ -40933,13 +40932,13 @@ class DataManager {
|
|
|
40933
40932
|
});
|
|
40934
40933
|
}
|
|
40935
40934
|
static applyRemoteConfig(data) {
|
|
40936
|
-
const pro2Config = this.enrichProtocolV2FirmwareReleaseInfo(data.pro2,
|
|
40937
|
-
|
|
40938
|
-
(
|
|
40935
|
+
const pro2Config = this.enrichProtocolV2FirmwareReleaseInfo(data.pro2, error => {
|
|
40936
|
+
this.protocolV2ResourcesConfigError = error;
|
|
40937
|
+
Log$k.warn('[DataConfig] Ignoring invalid Pro2 release resources config:', error);
|
|
40939
40938
|
});
|
|
40940
|
-
const neoConfig = this.enrichProtocolV2FirmwareReleaseInfo(data.neo,
|
|
40941
|
-
|
|
40942
|
-
(
|
|
40939
|
+
const neoConfig = this.enrichProtocolV2FirmwareReleaseInfo(data.neo, error => {
|
|
40940
|
+
this.protocolV2NeoResourcesConfigError = error;
|
|
40941
|
+
Log$k.warn('[DataConfig] Ignoring invalid Neo release resources config:', error);
|
|
40943
40942
|
});
|
|
40944
40943
|
this.deviceMap = {
|
|
40945
40944
|
[hdShared.EDeviceType.Classic]: this.enrichFirmwareReleaseInfo(data.classic),
|
|
@@ -41003,9 +41002,9 @@ class DataManager {
|
|
|
41003
41002
|
this.lastCheckTimestamp = getTimeStamp();
|
|
41004
41003
|
});
|
|
41005
41004
|
}
|
|
41006
|
-
static getProtocolV2ResourceSource(
|
|
41007
|
-
var _b
|
|
41008
|
-
return (
|
|
41005
|
+
static getProtocolV2ResourceSource(release) {
|
|
41006
|
+
var _b;
|
|
41007
|
+
return (_b = release === null || release === void 0 ? void 0 : release.resources) === null || _b === void 0 ? void 0 : _b.source;
|
|
41009
41008
|
}
|
|
41010
41009
|
static getProtobufMessages(schema = 'v1CurrentSchema') {
|
|
41011
41010
|
return this.messages[schema];
|
|
@@ -47855,7 +47854,7 @@ class CheckAllFirmwareRelease extends BaseMethod {
|
|
|
47855
47854
|
release,
|
|
47856
47855
|
deviceType: state.identity.deviceType,
|
|
47857
47856
|
});
|
|
47858
|
-
const resourceSource = DataManager.getProtocolV2ResourceSource(
|
|
47857
|
+
const resourceSource = DataManager.getProtocolV2ResourceSource(release);
|
|
47859
47858
|
const resourceStatus = 'unknown';
|
|
47860
47859
|
const detectedComponentTargets = validatedForceUpdateTargets.includes('firmware')
|
|
47861
47860
|
? plan.components.flatMap(component => component.updateTarget ? [component.updateTarget] : [])
|
|
@@ -50251,6 +50250,9 @@ const readVerifiedPreparedResourceArchive = ({ preparedPlan, reader, }) => __awa
|
|
|
50251
50250
|
}
|
|
50252
50251
|
return [];
|
|
50253
50252
|
}
|
|
50253
|
+
if (!reader) {
|
|
50254
|
+
return resourceArchiveError('Firmware artifact reader is required for prepared resource archives', 'FirmwareArtifactReaderInvalid');
|
|
50255
|
+
}
|
|
50254
50256
|
if (resourceArtifacts.length !== 1) {
|
|
50255
50257
|
return resourceArchiveError('Firmware prepared plan must contain exactly one materialized resource ZIP', 'FirmwareArtifactsNotPrepared');
|
|
50256
50258
|
}
|
|
@@ -52945,7 +52947,8 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52945
52947
|
if (deviceType !== hdShared.EDeviceType.Pro2 && deviceType !== hdShared.EDeviceType.Neo) {
|
|
52946
52948
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource archive requires a Pro2 or Neo device');
|
|
52947
52949
|
}
|
|
52948
|
-
const
|
|
52950
|
+
const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
|
|
52951
|
+
const source = DataManager.getProtocolV2ResourceSource(release);
|
|
52949
52952
|
const expectedSha256 = normalizeProtocolV2Hex(source === null || source === void 0 ? void 0 : source.archiveSha256);
|
|
52950
52953
|
if (!(source === null || source === void 0 ? void 0 : source.archiveUrl) ||
|
|
52951
52954
|
!Number.isSafeInteger(source.archiveSize) ||
|
|
@@ -53276,6 +53279,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53276
53279
|
});
|
|
53277
53280
|
}
|
|
53278
53281
|
executeProtocolV2TransferPhase({ installSources, resourceSources, }) {
|
|
53282
|
+
var _a;
|
|
53279
53283
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53280
53284
|
let totalSize = installSources.reduce((total, item) => total + item.source.size, 0);
|
|
53281
53285
|
const resourcesToSync = [];
|
|
@@ -53330,9 +53334,14 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53330
53334
|
target_id: item.targetId,
|
|
53331
53335
|
path: item.path,
|
|
53332
53336
|
}));
|
|
53333
|
-
|
|
53334
|
-
|
|
53335
|
-
|
|
53337
|
+
try {
|
|
53338
|
+
yield this.protocolV2StartFirmwareUpdate({ targets });
|
|
53339
|
+
yield hdShared.wait(PROTOCOL_V2_INSTALL_STATUS_INITIAL_DELAY);
|
|
53340
|
+
yield this.waitForProtocolV2FirmwareUpdateComplete(targets, true);
|
|
53341
|
+
}
|
|
53342
|
+
finally {
|
|
53343
|
+
(_a = this.device) === null || _a === void 0 ? void 0 : _a.clearCancelableAction();
|
|
53344
|
+
}
|
|
53336
53345
|
});
|
|
53337
53346
|
}
|
|
53338
53347
|
protocolV2SourceUpdateProcess({ source, filePath, processedSize, totalSize, }) {
|
|
@@ -53506,14 +53515,13 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53506
53515
|
const expectedPaths = new Map(targets.map(target => [target.target_id, target.path]));
|
|
53507
53516
|
const startTime = Date.now();
|
|
53508
53517
|
let lastError;
|
|
53509
|
-
let shouldReconnect =
|
|
53518
|
+
let shouldReconnect = false;
|
|
53510
53519
|
let deviceInfo;
|
|
53511
53520
|
let missingTargetStatusSince;
|
|
53512
53521
|
let missingTargetStatusKey;
|
|
53513
53522
|
let normalModeWithoutInstallEvidenceSince;
|
|
53514
53523
|
let installEvidenceObserved = false;
|
|
53515
53524
|
let currentInstallStatusObserved = false;
|
|
53516
|
-
let firmwareUpdatingTipPosted = false;
|
|
53517
53525
|
const resetMissingTargetStatusGrace = () => {
|
|
53518
53526
|
missingTargetStatusSince = undefined;
|
|
53519
53527
|
missingTargetStatusKey = undefined;
|
|
@@ -53543,18 +53551,14 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53543
53551
|
const statusTargets = statusResponse.type === 'DeviceFirmwareUpdateStatus'
|
|
53544
53552
|
? ((_a = statusResponse.message.records) !== null && _a !== void 0 ? _a : [])
|
|
53545
53553
|
: [];
|
|
53546
|
-
const
|
|
53554
|
+
const hasInProgressTarget = statusTargets.some(target => {
|
|
53547
53555
|
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
53548
53556
|
return (targetId !== undefined &&
|
|
53549
53557
|
expectedTargetIds.has(targetId) &&
|
|
53550
53558
|
isProtocolV2TargetStatusInProgress(target.status));
|
|
53551
53559
|
});
|
|
53552
|
-
if (
|
|
53560
|
+
if (hasInProgressTarget) {
|
|
53553
53561
|
currentInstallStatusObserved = true;
|
|
53554
|
-
if (!firmwareUpdatingTipPosted) {
|
|
53555
|
-
this.postTipMessage(exports.FirmwareUpdateTipMessage.FirmwareUpdating);
|
|
53556
|
-
firmwareUpdatingTipPosted = true;
|
|
53557
|
-
}
|
|
53558
53562
|
}
|
|
53559
53563
|
const hasMatchingTargetStatus = statusTargets.some(target => {
|
|
53560
53564
|
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
@@ -53607,9 +53611,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53607
53611
|
}
|
|
53608
53612
|
else if (now - missingTargetStatusSince >=
|
|
53609
53613
|
PROTOCOL_V2_MISSING_TARGET_STATUS_GRACE_TIMEOUT) {
|
|
53610
|
-
if (requireCurrentInstallStatus && !currentInstallStatusObserved) {
|
|
53611
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareError, 'Protocol V2 firmware installation was not confirmed on the device');
|
|
53612
|
-
}
|
|
53613
53614
|
const reportedTargetIds = statusTargets
|
|
53614
53615
|
.map(target => normalizeProtocolV2TargetId(target.target_id))
|
|
53615
53616
|
.filter((targetId) => targetId !== undefined);
|
|
@@ -53889,8 +53890,10 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53889
53890
|
this.protocolV2LastRuntimeProbeFeatures = undefined;
|
|
53890
53891
|
const commands = this.device.getCommands();
|
|
53891
53892
|
yield commands.typedCall('DeviceFirmwareUpdateStage', 'Success', { targets });
|
|
53893
|
+
this.device.setCancelableAction(() => commands.cancelDevice());
|
|
53894
|
+
const interaction = this.device.createProtocolV2UiPhaseMetadata('button', 'start');
|
|
53895
|
+
this.postMessage(createUiMessage(UI_REQUEST.REQUEST_BUTTON, Object.assign({ device: this.device.toMessageObject(), source: 'method-lifecycle', reason: 'firmware-update', completion: 'operation-completed', deviceOnly: true, operation: this.name }, (interaction ? { interaction } : {}))));
|
|
53892
53896
|
yield commands.call('DeviceFirmwareUpdateRequest', {}, { returnAfterWrite: true });
|
|
53893
|
-
this.postTipMessage(exports.FirmwareUpdateTipMessage.ConfirmOnDevice);
|
|
53894
53897
|
});
|
|
53895
53898
|
}
|
|
53896
53899
|
protocolV2Reboot(rebootType) {
|
|
@@ -54392,7 +54395,7 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
54392
54395
|
});
|
|
54393
54396
|
this.path = `${WALLPAPER_DIRECTORY}/${normalizeFileName(fileName, this.encoded.data)}`;
|
|
54394
54397
|
this.params = { jpegBase64, fileName, chunkSize };
|
|
54395
|
-
this.unlockPolicy = '
|
|
54398
|
+
this.unlockPolicy = 'none';
|
|
54396
54399
|
this.skipForceUpdateCheck = true;
|
|
54397
54400
|
this.useDevicePassphraseState = false;
|
|
54398
54401
|
}
|
|
@@ -54540,7 +54543,7 @@ class DeviceUploadNft extends BaseMethod {
|
|
|
54540
54543
|
paceMs,
|
|
54541
54544
|
timeoutMs,
|
|
54542
54545
|
};
|
|
54543
|
-
this.unlockPolicy = '
|
|
54546
|
+
this.unlockPolicy = 'none';
|
|
54544
54547
|
this.skipForceUpdateCheck = true;
|
|
54545
54548
|
this.useDevicePassphraseState = false;
|
|
54546
54549
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-core",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.129",
|
|
4
4
|
"description": "Core processes and APIs for communicating with OneKey hardware devices.",
|
|
5
5
|
"author": "OneKey",
|
|
6
6
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@onekeyfe/hd-shared": "1.2.0-alpha.
|
|
29
|
-
"@onekeyfe/hd-transport": "1.2.0-alpha.
|
|
28
|
+
"@onekeyfe/hd-shared": "1.2.0-alpha.129",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.2.0-alpha.129",
|
|
30
30
|
"axios": "1.15.2",
|
|
31
31
|
"bignumber.js": "^9.0.2",
|
|
32
32
|
"buffer": "^6.0.3",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"@types/w3c-web-usb": "^1.0.10",
|
|
47
47
|
"@types/web-bluetooth": "^0.0.21"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "d996758fef2d61a868b1989efcce1f04c8ef5e22"
|
|
50
50
|
}
|
|
@@ -411,7 +411,7 @@ export default class CheckAllFirmwareRelease extends BaseMethod {
|
|
|
411
411
|
release,
|
|
412
412
|
deviceType: state.identity.deviceType,
|
|
413
413
|
});
|
|
414
|
-
const resourceSource = DataManager.getProtocolV2ResourceSource(
|
|
414
|
+
const resourceSource = DataManager.getProtocolV2ResourceSource(release);
|
|
415
415
|
const resourceStatus = 'unknown' as const;
|
|
416
416
|
const detectedComponentTargets = validatedForceUpdateTargets.includes('firmware')
|
|
417
417
|
? plan.components.flatMap(component =>
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from '@onekeyfe/hd-transport';
|
|
10
10
|
import { sha256 } from '@noble/hashes/sha256';
|
|
11
11
|
|
|
12
|
-
import { FirmwareUpdateTipMessage, UI_REQUEST } from '../events/ui-request';
|
|
12
|
+
import { FirmwareUpdateTipMessage, UI_REQUEST, createUiMessage } from '../events/ui-request';
|
|
13
13
|
import { validateParams } from './helpers/paramsValidator';
|
|
14
14
|
import {
|
|
15
15
|
LoggerNames,
|
|
@@ -71,6 +71,7 @@ import type {
|
|
|
71
71
|
IProtocolV2FirmwareComponent,
|
|
72
72
|
IProtocolV2ResourceManifestFile,
|
|
73
73
|
IVersionArray,
|
|
74
|
+
KnownDevice,
|
|
74
75
|
} from '../types';
|
|
75
76
|
import type { FirmwareByteSource } from './firmware/FirmwareArtifactSource';
|
|
76
77
|
import type {
|
|
@@ -1891,7 +1892,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1891
1892
|
'Protocol V2 resource archive requires a Pro2 or Neo device'
|
|
1892
1893
|
);
|
|
1893
1894
|
}
|
|
1894
|
-
const
|
|
1895
|
+
const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
|
|
1896
|
+
const source = DataManager.getProtocolV2ResourceSource(release);
|
|
1895
1897
|
const expectedSha256 = normalizeProtocolV2Hex(source?.archiveSha256);
|
|
1896
1898
|
if (
|
|
1897
1899
|
!source?.archiveUrl ||
|
|
@@ -2379,9 +2381,13 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2379
2381
|
target_id: item.targetId,
|
|
2380
2382
|
path: item.path,
|
|
2381
2383
|
}));
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2384
|
+
try {
|
|
2385
|
+
await this.protocolV2StartFirmwareUpdate({ targets });
|
|
2386
|
+
await wait(PROTOCOL_V2_INSTALL_STATUS_INITIAL_DELAY);
|
|
2387
|
+
await this.waitForProtocolV2FirmwareUpdateComplete(targets, true);
|
|
2388
|
+
} finally {
|
|
2389
|
+
this.device?.clearCancelableAction();
|
|
2390
|
+
}
|
|
2385
2391
|
}
|
|
2386
2392
|
|
|
2387
2393
|
private async protocolV2SourceUpdateProcess({
|
|
@@ -2641,14 +2647,15 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2641
2647
|
const expectedPaths = new Map(targets.map(target => [target.target_id, target.path]));
|
|
2642
2648
|
const startTime = Date.now();
|
|
2643
2649
|
let lastError: unknown;
|
|
2644
|
-
|
|
2650
|
+
// DeviceFirmwareUpdateRequest leaves the current loader link usable for status polling.
|
|
2651
|
+
// Reconnecting here probes DeviceInfo, which loaders reject while installation is active.
|
|
2652
|
+
let shouldReconnect = false;
|
|
2645
2653
|
let deviceInfo: ProtocolV2DeviceInfo | undefined;
|
|
2646
2654
|
let missingTargetStatusSince: number | undefined;
|
|
2647
2655
|
let missingTargetStatusKey: string | undefined;
|
|
2648
2656
|
let normalModeWithoutInstallEvidenceSince: number | undefined;
|
|
2649
2657
|
let installEvidenceObserved = false;
|
|
2650
2658
|
let currentInstallStatusObserved = false;
|
|
2651
|
-
let firmwareUpdatingTipPosted = false;
|
|
2652
2659
|
const resetMissingTargetStatusGrace = () => {
|
|
2653
2660
|
missingTargetStatusSince = undefined;
|
|
2654
2661
|
missingTargetStatusKey = undefined;
|
|
@@ -2689,7 +2696,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2689
2696
|
statusResponse.type === 'DeviceFirmwareUpdateStatus'
|
|
2690
2697
|
? ((statusResponse.message.records ?? []) as ProtocolV2FirmwareUpdateStatusTarget[])
|
|
2691
2698
|
: [];
|
|
2692
|
-
const
|
|
2699
|
+
const hasInProgressTarget = statusTargets.some(target => {
|
|
2693
2700
|
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
2694
2701
|
return (
|
|
2695
2702
|
targetId !== undefined &&
|
|
@@ -2697,12 +2704,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2697
2704
|
isProtocolV2TargetStatusInProgress(target.status)
|
|
2698
2705
|
);
|
|
2699
2706
|
});
|
|
2700
|
-
if (
|
|
2707
|
+
if (hasInProgressTarget) {
|
|
2701
2708
|
currentInstallStatusObserved = true;
|
|
2702
|
-
if (!firmwareUpdatingTipPosted) {
|
|
2703
|
-
this.postTipMessage(FirmwareUpdateTipMessage.FirmwareUpdating);
|
|
2704
|
-
firmwareUpdatingTipPosted = true;
|
|
2705
|
-
}
|
|
2706
2709
|
}
|
|
2707
2710
|
const hasMatchingTargetStatus = statusTargets.some(target => {
|
|
2708
2711
|
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
@@ -2776,12 +2779,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2776
2779
|
now - missingTargetStatusSince >=
|
|
2777
2780
|
PROTOCOL_V2_MISSING_TARGET_STATUS_GRACE_TIMEOUT
|
|
2778
2781
|
) {
|
|
2779
|
-
if (requireCurrentInstallStatus && !currentInstallStatusObserved) {
|
|
2780
|
-
throw ERRORS.TypedError(
|
|
2781
|
-
HardwareErrorCode.FirmwareError,
|
|
2782
|
-
'Protocol V2 firmware installation was not confirmed on the device'
|
|
2783
|
-
);
|
|
2784
|
-
}
|
|
2785
2782
|
const reportedTargetIds = statusTargets
|
|
2786
2783
|
.map(target => normalizeProtocolV2TargetId(target.target_id))
|
|
2787
2784
|
.filter((targetId): targetId is number => targetId !== undefined);
|
|
@@ -3152,8 +3149,20 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
3152
3149
|
this.protocolV2LastRuntimeProbeFeatures = undefined;
|
|
3153
3150
|
const commands = this.device.getCommands();
|
|
3154
3151
|
await commands.typedCall('DeviceFirmwareUpdateStage', 'Success', { targets });
|
|
3152
|
+
this.device.setCancelableAction(() => commands.cancelDevice());
|
|
3153
|
+
const interaction = this.device.createProtocolV2UiPhaseMetadata('button', 'start');
|
|
3154
|
+
this.postMessage(
|
|
3155
|
+
createUiMessage(UI_REQUEST.REQUEST_BUTTON, {
|
|
3156
|
+
device: this.device.toMessageObject() as KnownDevice,
|
|
3157
|
+
source: 'method-lifecycle',
|
|
3158
|
+
reason: 'firmware-update',
|
|
3159
|
+
completion: 'operation-completed',
|
|
3160
|
+
deviceOnly: true,
|
|
3161
|
+
operation: this.name,
|
|
3162
|
+
...(interaction ? { interaction } : {}),
|
|
3163
|
+
})
|
|
3164
|
+
);
|
|
3155
3165
|
await commands.call('DeviceFirmwareUpdateRequest', {}, { returnAfterWrite: true });
|
|
3156
|
-
this.postTipMessage(FirmwareUpdateTipMessage.ConfirmOnDevice);
|
|
3157
3166
|
}
|
|
3158
3167
|
|
|
3159
3168
|
private async protocolV2Reboot(rebootType: DeviceRebootType) {
|
|
@@ -26,7 +26,10 @@ export type VerifiedPreparedResourceEntry = {
|
|
|
26
26
|
|
|
27
27
|
const resourceArchiveError = (
|
|
28
28
|
message: string,
|
|
29
|
-
firmwareUpdateCode:
|
|
29
|
+
firmwareUpdateCode:
|
|
30
|
+
| 'FirmwareArtifactsNotPrepared'
|
|
31
|
+
| 'FirmwareArtifactReceiptMismatch'
|
|
32
|
+
| 'FirmwareArtifactReaderInvalid'
|
|
30
33
|
): never => {
|
|
31
34
|
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, message, { firmwareUpdateCode });
|
|
32
35
|
};
|
|
@@ -73,6 +76,12 @@ export const readVerifiedPreparedResourceArchive = async ({
|
|
|
73
76
|
}
|
|
74
77
|
return [];
|
|
75
78
|
}
|
|
79
|
+
if (!reader) {
|
|
80
|
+
return resourceArchiveError(
|
|
81
|
+
'Firmware artifact reader is required for prepared resource archives',
|
|
82
|
+
'FirmwareArtifactReaderInvalid'
|
|
83
|
+
);
|
|
84
|
+
}
|
|
76
85
|
if (resourceArtifacts.length !== 1) {
|
|
77
86
|
return resourceArchiveError(
|
|
78
87
|
'Firmware prepared plan must contain exactly one materialized resource ZIP',
|
|
@@ -129,7 +129,7 @@ export default class DeviceUploadNft extends BaseMethod<DeviceUploadNftParams> {
|
|
|
129
129
|
paceMs,
|
|
130
130
|
timeoutMs,
|
|
131
131
|
};
|
|
132
|
-
this.unlockPolicy = '
|
|
132
|
+
this.unlockPolicy = 'none';
|
|
133
133
|
this.skipForceUpdateCheck = true;
|
|
134
134
|
this.useDevicePassphraseState = false;
|
|
135
135
|
}
|
|
@@ -76,7 +76,7 @@ export default class DeviceUploadWallpaper extends BaseMethod<DeviceUploadWallpa
|
|
|
76
76
|
});
|
|
77
77
|
this.path = `${WALLPAPER_DIRECTORY}/${normalizeFileName(fileName, this.encoded.data)}`;
|
|
78
78
|
this.params = { jpegBase64, fileName, chunkSize };
|
|
79
|
-
this.unlockPolicy = '
|
|
79
|
+
this.unlockPolicy = 'none';
|
|
80
80
|
this.skipForceUpdateCheck = true;
|
|
81
81
|
this.useDevicePassphraseState = false;
|
|
82
82
|
}
|
|
@@ -26,6 +26,7 @@ import type {
|
|
|
26
26
|
Features,
|
|
27
27
|
IDeviceBLEFirmwareStatus,
|
|
28
28
|
IDeviceFirmwareStatus,
|
|
29
|
+
IFirmwareReleaseInfo,
|
|
29
30
|
ITransportStatus,
|
|
30
31
|
IVersionArray,
|
|
31
32
|
RemoteConfigResponse,
|
|
@@ -408,35 +409,29 @@ export default class DataManager {
|
|
|
408
409
|
|
|
409
410
|
private static enrichProtocolV2FirmwareReleaseInfo(
|
|
410
411
|
deviceData: DeviceTypeMap[keyof DeviceTypeMap] | undefined,
|
|
411
|
-
|
|
412
|
-
onResourcesConfigError: (error: Error) => void
|
|
412
|
+
onResourcesError: (error: Error) => void
|
|
413
413
|
): NonNullable<DeviceTypeMap[keyof DeviceTypeMap]> {
|
|
414
414
|
const enrichedData = this.enrichFirmwareReleaseInfo(deviceData);
|
|
415
|
-
const
|
|
416
|
-
enrichedData as typeof enrichedData & {
|
|
417
|
-
resources?: unknown;
|
|
418
|
-
};
|
|
419
|
-
const releases = releaseScopedData['firmware-v1'];
|
|
415
|
+
const releases = enrichedData['firmware-v1'];
|
|
420
416
|
if (!Array.isArray(releases)) {
|
|
421
|
-
return
|
|
417
|
+
return enrichedData;
|
|
422
418
|
}
|
|
419
|
+
const latestRelease = findLatestRelease(releases);
|
|
423
420
|
|
|
424
421
|
return {
|
|
425
|
-
...
|
|
422
|
+
...enrichedData,
|
|
426
423
|
'firmware-v1': releases.map(release => {
|
|
427
424
|
const { resources: rawResources, ...releaseWithoutResources } = release;
|
|
428
425
|
try {
|
|
429
426
|
const resources = parseProtocolV2Resources(rawResources);
|
|
430
|
-
return
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
}
|
|
435
|
-
: releaseWithoutResources;
|
|
427
|
+
return {
|
|
428
|
+
...releaseWithoutResources,
|
|
429
|
+
...(resources ? { resources } : undefined),
|
|
430
|
+
};
|
|
436
431
|
} catch (error) {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
432
|
+
if (release === latestRelease) {
|
|
433
|
+
onResourcesError(error instanceof Error ? error : new Error(String(error)));
|
|
434
|
+
}
|
|
440
435
|
return releaseWithoutResources;
|
|
441
436
|
}
|
|
442
437
|
}),
|
|
@@ -507,11 +502,15 @@ export default class DataManager {
|
|
|
507
502
|
}
|
|
508
503
|
|
|
509
504
|
private static applyRemoteConfig(data: RemoteConfigResponse) {
|
|
510
|
-
const pro2Config = this.enrichProtocolV2FirmwareReleaseInfo(data.pro2,
|
|
511
|
-
|
|
505
|
+
const pro2Config = this.enrichProtocolV2FirmwareReleaseInfo(data.pro2, error => {
|
|
506
|
+
// Firmware resource metadata is not required for base communication. If the
|
|
507
|
+
// The selected release is incomplete, so disable its resource update only.
|
|
508
|
+
this.protocolV2ResourcesConfigError = error;
|
|
509
|
+
Log.warn('[DataConfig] Ignoring invalid Pro2 release resources config:', error);
|
|
512
510
|
});
|
|
513
|
-
const neoConfig = this.enrichProtocolV2FirmwareReleaseInfo(data.neo,
|
|
514
|
-
this.protocolV2NeoResourcesConfigError
|
|
511
|
+
const neoConfig = this.enrichProtocolV2FirmwareReleaseInfo(data.neo, error => {
|
|
512
|
+
this.protocolV2NeoResourcesConfigError = error;
|
|
513
|
+
Log.warn('[DataConfig] Ignoring invalid Neo release resources config:', error);
|
|
515
514
|
});
|
|
516
515
|
this.deviceMap = {
|
|
517
516
|
[EDeviceType.Classic]: this.enrichFirmwareReleaseInfo(data.classic),
|
|
@@ -599,8 +598,8 @@ export default class DataManager {
|
|
|
599
598
|
this.lastCheckTimestamp = getTimeStamp();
|
|
600
599
|
}
|
|
601
600
|
|
|
602
|
-
static getProtocolV2ResourceSource(
|
|
603
|
-
return
|
|
601
|
+
static getProtocolV2ResourceSource(release: IFirmwareReleaseInfo | undefined) {
|
|
602
|
+
return release?.resources?.source;
|
|
604
603
|
}
|
|
605
604
|
|
|
606
605
|
static getProtobufMessages(schema: ProtobufMessageSchema = 'v1CurrentSchema'): JSON {
|
package/src/types/settings.ts
CHANGED
|
@@ -116,7 +116,7 @@ export type IFirmwareReleaseInfo = {
|
|
|
116
116
|
upgradeType?: 'payload-package-set' | string;
|
|
117
117
|
components?: Record<string, IProtocolV2FirmwareComponent>;
|
|
118
118
|
installOrder?: string[];
|
|
119
|
-
/**
|
|
119
|
+
/** Protocol V2 resources matched to this firmware release. */
|
|
120
120
|
resources?: IProtocolV2Resources;
|
|
121
121
|
bootloaderChangelog?: {
|
|
122
122
|
[k in ILocale]: string;
|