@onekeyfe/hd-core 1.2.0-alpha.56 → 1.2.0-alpha.58
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__/AllNetworkGetAddressBase.tracing.test.ts +84 -2
- package/__tests__/DeviceCommands.test.ts +17 -6
- package/__tests__/core-initialization.test.ts +23 -0
- package/__tests__/device-connector-protocol.test.ts +81 -0
- package/__tests__/device-settings.test.ts +39 -18
- package/__tests__/protocol-v2-resources.test.ts +24 -0
- package/__tests__/protocol-v2.test.ts +46 -1
- package/__tests__/protocolV2FileWrite.test.ts +113 -0
- package/dist/api/FirmwareUpdateV4.d.ts +0 -1
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
- package/dist/api/device/DeviceSettings.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +4 -2
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/helpers/protocolV2FileWrite.d.ts +7 -0
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/data-manager/DataManager.d.ts +1 -0
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/data-manager/TransportManager.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/device/DeviceConnector.d.ts +2 -1
- package/dist/device/DeviceConnector.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +448 -336
- package/package.json +4 -4
- package/src/api/FirmwareUpdateV4.ts +39 -69
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +3 -1
- package/src/api/device/DeviceSettings.ts +5 -4
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +12 -1
- package/src/api/helpers/protocolV2FileWrite.ts +192 -73
- package/src/core/index.ts +9 -6
- package/src/data-manager/DataManager.ts +25 -4
- package/src/data-manager/TransportManager.ts +6 -0
- package/src/device/DeviceCommands.ts +20 -2
- package/src/device/DeviceConnector.ts +33 -13
|
@@ -91,11 +91,93 @@ describe('AllNetworkGetAddressBase tracing', () => {
|
|
|
91
91
|
0
|
|
92
92
|
);
|
|
93
93
|
|
|
94
|
-
expect(checkPassphraseStateSafety).toHaveBeenCalledWith(
|
|
94
|
+
expect(checkPassphraseStateSafety).toHaveBeenCalledWith(
|
|
95
|
+
'hidden-state',
|
|
96
|
+
false,
|
|
97
|
+
undefined,
|
|
98
|
+
false
|
|
99
|
+
);
|
|
95
100
|
expect(calls).toEqual(['resume-hidden-session', 'run-chain-method']);
|
|
96
101
|
expect(typedCall).not.toHaveBeenCalled();
|
|
97
102
|
});
|
|
98
103
|
|
|
104
|
+
test('resumes a Protocol V2 Cardano hidden wallet with the Cardano seed domain', async () => {
|
|
105
|
+
const calls: string[] = [];
|
|
106
|
+
const checkPassphraseStateSafety = jest.fn().mockImplementation(() => {
|
|
107
|
+
calls.push('resume-cardano-session');
|
|
108
|
+
return Promise.resolve(true);
|
|
109
|
+
});
|
|
110
|
+
const innerMethod = {
|
|
111
|
+
checkSafetyLevelOnTestNet: jest.fn().mockResolvedValue(false),
|
|
112
|
+
connectId: 'connect-id',
|
|
113
|
+
deviceId: 'device-id',
|
|
114
|
+
getVersionRange: jest.fn().mockReturnValue({}),
|
|
115
|
+
assertProtocolSupported: jest.fn(),
|
|
116
|
+
init: jest.fn(),
|
|
117
|
+
name: 'cardanoGetAddress',
|
|
118
|
+
responseID: 45,
|
|
119
|
+
unlockPolicy: 'unlock-before-run',
|
|
120
|
+
run: jest.fn().mockImplementation(() => {
|
|
121
|
+
calls.push('run-cardano-method');
|
|
122
|
+
return Promise.resolve([{ address: 'addr1hidden' }]);
|
|
123
|
+
}),
|
|
124
|
+
setDevice: jest.fn(),
|
|
125
|
+
strictCheckDeviceSupport: false,
|
|
126
|
+
};
|
|
127
|
+
(findMethod as jest.Mock).mockReturnValue(innerMethod);
|
|
128
|
+
const method = new TestAllNetworkMethod({
|
|
129
|
+
id: 5,
|
|
130
|
+
payload: {
|
|
131
|
+
method: 'allNetworkGetAddress',
|
|
132
|
+
connectId: 'connect-id',
|
|
133
|
+
deviceId: 'device-id',
|
|
134
|
+
passphraseState: 'hidden-state',
|
|
135
|
+
bundle: [],
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
method.protocolV2UnlockContext = { preflightCompleted: true };
|
|
139
|
+
const typedCall = jest.fn();
|
|
140
|
+
method.device = {
|
|
141
|
+
checkPassphraseStateSafety,
|
|
142
|
+
commands: {
|
|
143
|
+
typedCall,
|
|
144
|
+
},
|
|
145
|
+
getCurrentFirmwareType: jest.fn(),
|
|
146
|
+
getProtocol: jest.fn().mockReturnValue('V2'),
|
|
147
|
+
getCurrentFirmwareVersionString: jest.fn().mockReturnValue('1.0.0'),
|
|
148
|
+
getCurrentMethodVersionRange: jest
|
|
149
|
+
.fn()
|
|
150
|
+
.mockImplementation((getRange: (type: string) => unknown) => getRange('pro2')),
|
|
151
|
+
instanceId: 'device-instance',
|
|
152
|
+
isProtocolV2: jest.fn().mockReturnValue(true),
|
|
153
|
+
isBootloader: jest.fn().mockReturnValue(false),
|
|
154
|
+
isRomloader: jest.fn().mockReturnValue(false),
|
|
155
|
+
off: jest.fn(),
|
|
156
|
+
on: jest.fn(),
|
|
157
|
+
state: { status: { unlocked: true } },
|
|
158
|
+
updateProtocolV2Status: jest.fn(),
|
|
159
|
+
} as any;
|
|
160
|
+
|
|
161
|
+
await method.callMethod(
|
|
162
|
+
'cardanoGetAddress',
|
|
163
|
+
{
|
|
164
|
+
bundle: [
|
|
165
|
+
{
|
|
166
|
+
_originRequestParams: {
|
|
167
|
+
network: 'ada',
|
|
168
|
+
path: "m/1852'/1815'/0'/0/0",
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
},
|
|
173
|
+
0
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
expect(checkPassphraseStateSafety).toHaveBeenCalledWith('hidden-state', false, undefined, true);
|
|
177
|
+
expect(calls).toEqual(['resume-cardano-session', 'run-cardano-method']);
|
|
178
|
+
expect(typedCall).not.toHaveBeenCalled();
|
|
179
|
+
});
|
|
180
|
+
|
|
99
181
|
test('resumes a Protocol V2 standard wallet before running a nested chain method', async () => {
|
|
100
182
|
const calls: string[] = [];
|
|
101
183
|
const checkPassphraseStateSafety = jest.fn().mockImplementation(() => {
|
|
@@ -168,7 +250,7 @@ describe('AllNetworkGetAddressBase tracing', () => {
|
|
|
168
250
|
0
|
|
169
251
|
);
|
|
170
252
|
|
|
171
|
-
expect(checkPassphraseStateSafety).toHaveBeenCalledWith(undefined, true, undefined);
|
|
253
|
+
expect(checkPassphraseStateSafety).toHaveBeenCalledWith(undefined, true, undefined, false);
|
|
172
254
|
expect(calls).toEqual(['resume-standard-session', 'run-chain-method']);
|
|
173
255
|
expect(typedCall).not.toHaveBeenCalled();
|
|
174
256
|
});
|
|
@@ -363,9 +363,14 @@ describe('DeviceCommands failure mapping', () => {
|
|
|
363
363
|
}
|
|
364
364
|
);
|
|
365
365
|
|
|
366
|
-
it.each([
|
|
367
|
-
'
|
|
368
|
-
|
|
366
|
+
it.each([
|
|
367
|
+
['SignTx', 'Rejected by the user'],
|
|
368
|
+
['EthereumSignTypedDataOneKey', ''],
|
|
369
|
+
['SolanaSignTx', 'Localized cancellation message'],
|
|
370
|
+
['GetAddress', 'Address confirmation rejected'],
|
|
371
|
+
] as const)(
|
|
372
|
+
'maps Protocol V2 cancellation subcode 1 for %s regardless of message',
|
|
373
|
+
async (callType, message) => {
|
|
369
374
|
const commands = createCommands();
|
|
370
375
|
|
|
371
376
|
await expect(
|
|
@@ -378,7 +383,7 @@ describe('DeviceCommands failure mapping', () => {
|
|
|
378
383
|
message,
|
|
379
384
|
},
|
|
380
385
|
} as any,
|
|
381
|
-
|
|
386
|
+
callType
|
|
382
387
|
)
|
|
383
388
|
).rejects.toMatchObject({
|
|
384
389
|
errorCode: HardwareErrorCode.ActionCancelled,
|
|
@@ -401,6 +406,7 @@ describe('DeviceCommands failure mapping', () => {
|
|
|
401
406
|
type: 'Failure',
|
|
402
407
|
message: {
|
|
403
408
|
code: 'Failure_ProcessError',
|
|
409
|
+
subcode: 1,
|
|
404
410
|
message: 'Cancelled on device',
|
|
405
411
|
},
|
|
406
412
|
} as any,
|
|
@@ -411,7 +417,7 @@ describe('DeviceCommands failure mapping', () => {
|
|
|
411
417
|
});
|
|
412
418
|
});
|
|
413
419
|
|
|
414
|
-
it('
|
|
420
|
+
it('maps the DeviceError subcode 1 exception to DeviceBusy', async () => {
|
|
415
421
|
const commands = createCommands();
|
|
416
422
|
|
|
417
423
|
await expect(
|
|
@@ -427,7 +433,12 @@ describe('DeviceCommands failure mapping', () => {
|
|
|
427
433
|
'DeviceSettingsPageShow'
|
|
428
434
|
)
|
|
429
435
|
).rejects.toMatchObject({
|
|
430
|
-
errorCode: HardwareErrorCode.
|
|
436
|
+
errorCode: HardwareErrorCode.DeviceBusy,
|
|
437
|
+
params: {
|
|
438
|
+
failureCode: 'Failure_ProcessError',
|
|
439
|
+
subcode: 1,
|
|
440
|
+
firmwareMessage: 'Another process error',
|
|
441
|
+
},
|
|
431
442
|
});
|
|
432
443
|
});
|
|
433
444
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { DataManager } from '../src/data-manager';
|
|
2
|
+
import { init } from '../src/core';
|
|
3
|
+
|
|
4
|
+
import type { ConnectSettings } from '../src/types';
|
|
5
|
+
|
|
6
|
+
jest.mock('../src/data/config', () => ({
|
|
7
|
+
getSDKVersion: jest.fn(() => '1.0.0-test'),
|
|
8
|
+
DEFAULT_DOMAIN: 'https://jssdk.onekey.so/1.0.0-test/',
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
describe('Core initialization', () => {
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
jest.restoreAllMocks();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('does not create a partially initialized core when settings loading fails', async () => {
|
|
17
|
+
jest.spyOn(DataManager, 'load').mockRejectedValue(new Error('settings load failed'));
|
|
18
|
+
|
|
19
|
+
await expect(init({} as ConnectSettings, class TestTransport {})).rejects.toThrow(
|
|
20
|
+
'settings load failed'
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
|
+
|
|
3
|
+
import DeviceConnector from '../src/device/DeviceConnector';
|
|
4
|
+
|
|
5
|
+
jest.mock('../src/data-manager/TransportManager', () => ({
|
|
6
|
+
__esModule: true,
|
|
7
|
+
default: {
|
|
8
|
+
load: jest.fn(),
|
|
9
|
+
getTransport: jest.fn(),
|
|
10
|
+
},
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
jest.mock('../src/data-manager', () => ({
|
|
14
|
+
DataManager: {
|
|
15
|
+
getSettings: jest.fn(() => 'desktop-web-ble'),
|
|
16
|
+
isBleConnect: jest.fn(() => true),
|
|
17
|
+
},
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
jest.mock('../src/device/DevicePool', () => ({
|
|
21
|
+
DevicePool: {
|
|
22
|
+
setConnector: jest.fn(),
|
|
23
|
+
},
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
const transportManagerMock: {
|
|
27
|
+
default: {
|
|
28
|
+
getTransport: jest.Mock;
|
|
29
|
+
};
|
|
30
|
+
} = jest.requireMock('../src/data-manager/TransportManager');
|
|
31
|
+
|
|
32
|
+
describe('DeviceConnector protocol validation', () => {
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
jest.clearAllMocks();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('reports an explicit transport error when connector initialization ran too early', async () => {
|
|
38
|
+
transportManagerMock.default.getTransport.mockReturnValue(undefined);
|
|
39
|
+
const connector = new DeviceConnector();
|
|
40
|
+
|
|
41
|
+
await expect(connector.enumerate()).rejects.toMatchObject({
|
|
42
|
+
errorCode: HardwareErrorCode.TransportNotConfigured,
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('uses the actively probed protocol returned by acquire when the cache was cleared', async () => {
|
|
47
|
+
const acquire = jest.fn().mockResolvedValue({
|
|
48
|
+
id: 'pro2-id',
|
|
49
|
+
path: 'pro2-id',
|
|
50
|
+
protocolType: 'V2',
|
|
51
|
+
});
|
|
52
|
+
transportManagerMock.default.getTransport.mockReturnValue({
|
|
53
|
+
acquire,
|
|
54
|
+
getProtocolType: jest.fn(() => undefined),
|
|
55
|
+
});
|
|
56
|
+
const connector = new DeviceConnector();
|
|
57
|
+
|
|
58
|
+
await expect(connector.acquire('pro2-id', undefined, undefined, 'V2')).resolves.toEqual(
|
|
59
|
+
expect.objectContaining({ protocolType: 'V2' })
|
|
60
|
+
);
|
|
61
|
+
expect(acquire).toHaveBeenCalledWith(
|
|
62
|
+
expect.objectContaining({ uuid: 'pro2-id', expectedProtocol: 'V2' })
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('still rejects a real mismatch reported by the active protocol probe', async () => {
|
|
67
|
+
transportManagerMock.default.getTransport.mockReturnValue({
|
|
68
|
+
acquire: jest.fn().mockResolvedValue({
|
|
69
|
+
id: 'classic-id',
|
|
70
|
+
path: 'classic-id',
|
|
71
|
+
protocolType: 'V1',
|
|
72
|
+
}),
|
|
73
|
+
getProtocolType: jest.fn(() => 'V1'),
|
|
74
|
+
});
|
|
75
|
+
const connector = new DeviceConnector();
|
|
76
|
+
|
|
77
|
+
await expect(connector.acquire('classic-id', undefined, undefined, 'V2')).rejects.toThrow(
|
|
78
|
+
'Device protocol mismatch: expected V2, detected V1'
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -115,8 +115,8 @@ describe('DeviceSettings protocol routing', () => {
|
|
|
115
115
|
);
|
|
116
116
|
});
|
|
117
117
|
|
|
118
|
-
it('uses DeviceSettingsSet and
|
|
119
|
-
const { device, typedCall, updateState } = createDevice({ protocol: 'V2' });
|
|
118
|
+
it('uses DeviceSettingsSet and reloads Protocol V2 status and settings from the device', async () => {
|
|
119
|
+
const { device, typedCall, updateState, getDeviceState } = createDevice({ protocol: 'V2' });
|
|
120
120
|
const method = new DeviceSettings({
|
|
121
121
|
id: 2,
|
|
122
122
|
payload: {
|
|
@@ -141,21 +141,10 @@ describe('DeviceSettings protocol routing', () => {
|
|
|
141
141
|
haptic_feedback: true,
|
|
142
142
|
},
|
|
143
143
|
});
|
|
144
|
-
expect(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
language: 'ja',
|
|
149
|
-
bleEnabled: true,
|
|
150
|
-
autoLockDelayMs: 60_000,
|
|
151
|
-
hapticFeedback: true,
|
|
152
|
-
},
|
|
153
|
-
},
|
|
154
|
-
'settings-write'
|
|
155
|
-
);
|
|
156
|
-
expect(typedCall.mock.calls.map(call => call[0])).not.toEqual(
|
|
157
|
-
expect.arrayContaining(['DeviceInfoGet', 'DeviceStatusGet', 'DeviceSettingsGet'])
|
|
158
|
-
);
|
|
144
|
+
expect(getDeviceState).toHaveBeenCalledWith({
|
|
145
|
+
refreshSections: ['status', 'settings'],
|
|
146
|
+
});
|
|
147
|
+
expect(updateState).not.toHaveBeenCalled();
|
|
159
148
|
});
|
|
160
149
|
|
|
161
150
|
it('uses the Pro2 passphrase page as a device-side toggle and verifies the target state', async () => {
|
|
@@ -183,7 +172,39 @@ describe('DeviceSettings protocol routing', () => {
|
|
|
183
172
|
});
|
|
184
173
|
expect(typedCall).not.toHaveBeenCalledWith('DeviceSettingsSet', 'Success', expect.anything());
|
|
185
174
|
expect(getDeviceState).toHaveBeenNthCalledWith(1, { refreshSections: ['status'] });
|
|
186
|
-
expect(getDeviceState).toHaveBeenNthCalledWith(2, {
|
|
175
|
+
expect(getDeviceState).toHaveBeenNthCalledWith(2, {
|
|
176
|
+
refreshSections: ['status', 'settings'],
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('reloads Protocol V2 status and settings after changing air-gap mode', async () => {
|
|
181
|
+
const { device, typedCall, getDeviceState } = createDevice({ protocol: 'V2' });
|
|
182
|
+
getDeviceState
|
|
183
|
+
.mockResolvedValueOnce({
|
|
184
|
+
settings: { airgapMode: false },
|
|
185
|
+
})
|
|
186
|
+
.mockResolvedValueOnce({
|
|
187
|
+
status: { unlocked: true },
|
|
188
|
+
settings: { airgapMode: true },
|
|
189
|
+
});
|
|
190
|
+
const method = new DeviceSettings({
|
|
191
|
+
id: 4,
|
|
192
|
+
payload: {
|
|
193
|
+
method: 'deviceSettings',
|
|
194
|
+
airgapMode: true,
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
method.init();
|
|
198
|
+
(method as any).device = device;
|
|
199
|
+
|
|
200
|
+
await expect(method.run()).resolves.toEqual({ message: 'Success' });
|
|
201
|
+
expect(typedCall).toHaveBeenCalledWith('DeviceSettingsPageShow', 'Success', {
|
|
202
|
+
page: DeviceSettingsPage.DeviceAirgap,
|
|
203
|
+
});
|
|
204
|
+
expect(getDeviceState).toHaveBeenNthCalledWith(1, { refreshSections: ['settings'] });
|
|
205
|
+
expect(getDeviceState).toHaveBeenNthCalledWith(2, {
|
|
206
|
+
refreshSections: ['status', 'settings'],
|
|
207
|
+
});
|
|
187
208
|
});
|
|
188
209
|
|
|
189
210
|
it('does not open a Pro2 settings page when the hardware already matches the target', async () => {
|
|
@@ -269,6 +269,30 @@ describe('Pro2 resource configuration', () => {
|
|
|
269
269
|
expect(DataManager.getProtocolV2BootResources()).toEqual(bootResources);
|
|
270
270
|
});
|
|
271
271
|
|
|
272
|
+
test('keeps base SDK initialization available when remote Pro2 resources are invalid', async () => {
|
|
273
|
+
const remoteConfig = createRemoteConfig();
|
|
274
|
+
(remoteConfig.pro2 as { resources?: unknown }).resources = { stable: [] };
|
|
275
|
+
const configFetcher = jest.fn().mockResolvedValue(remoteConfig);
|
|
276
|
+
|
|
277
|
+
await expect(DataManager.load(createSettings(configFetcher))).resolves.toBe(true);
|
|
278
|
+
|
|
279
|
+
expect(DataManager.getProtocolV2Resources()).toBeUndefined();
|
|
280
|
+
expect(DataManager.getProtocolV2BootResources()).toBeUndefined();
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
test('still blocks firmware mutation when the refreshed Pro2 resources are invalid', async () => {
|
|
284
|
+
const remoteConfig = createRemoteConfig();
|
|
285
|
+
(remoteConfig.pro2 as { resources?: unknown }).resources = { stable: [] };
|
|
286
|
+
const settings = createSettings(jest.fn().mockResolvedValue(remoteConfig));
|
|
287
|
+
DataManager.settings = settings;
|
|
288
|
+
|
|
289
|
+
await expect(DataManager.forceReloadData()).rejects.toMatchObject({
|
|
290
|
+
errorCode: HardwareErrorCode.NetworkError,
|
|
291
|
+
message: expect.stringContaining('Invalid Pro2 resources config'),
|
|
292
|
+
});
|
|
293
|
+
expect(DataManager.lastCheckTimestamp).toBe(0);
|
|
294
|
+
});
|
|
295
|
+
|
|
272
296
|
test('does not advance the cache timestamp when refresh fails', async () => {
|
|
273
297
|
jest.spyOn(axios, 'get').mockRejectedValue(new Error('offline'));
|
|
274
298
|
const settings = createSettings(jest.fn().mockResolvedValue(null));
|
|
@@ -4092,6 +4092,38 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
4092
4092
|
expect(reconnectProtocolV2Device).toHaveBeenCalledTimes(1);
|
|
4093
4093
|
});
|
|
4094
4094
|
|
|
4095
|
+
test('announces bootloader success only after Protocol V2 bootloader mode is confirmed', async () => {
|
|
4096
|
+
const method = new FirmwareUpdateV4({
|
|
4097
|
+
id: 1,
|
|
4098
|
+
payload: {
|
|
4099
|
+
method: 'firmwareUpdateV4',
|
|
4100
|
+
},
|
|
4101
|
+
});
|
|
4102
|
+
(method as any).device = stubDevice({
|
|
4103
|
+
features: { bootloader_mode: false, capabilities: [] },
|
|
4104
|
+
isBootloader: () => false,
|
|
4105
|
+
isRomloader: () => false,
|
|
4106
|
+
});
|
|
4107
|
+
(method as any).protocolV2Reboot = jest.fn().mockResolvedValue({
|
|
4108
|
+
message: 'Device rebooted successfully',
|
|
4109
|
+
});
|
|
4110
|
+
|
|
4111
|
+
const tipMessages: string[] = [];
|
|
4112
|
+
method.postTipMessage = jest.fn((message: string) => {
|
|
4113
|
+
tipMessages.push(message);
|
|
4114
|
+
});
|
|
4115
|
+
let successWasAnnouncedBeforeConfirmation = false;
|
|
4116
|
+
(method as any).waitForProtocolV2BootloaderMode = jest.fn().mockImplementation(() => {
|
|
4117
|
+
successWasAnnouncedBeforeConfirmation = tipMessages.includes('GoToBootloaderSuccess');
|
|
4118
|
+
return Promise.resolve({ mode: 'bootloader' });
|
|
4119
|
+
});
|
|
4120
|
+
|
|
4121
|
+
await (method as any).enterProtocolV2BootloaderMode();
|
|
4122
|
+
|
|
4123
|
+
expect(successWasAnnouncedBeforeConfirmation).toBe(false);
|
|
4124
|
+
expect(tipMessages).toEqual(['AutoRebootToBootloader', 'GoToBootloaderSuccess']);
|
|
4125
|
+
});
|
|
4126
|
+
|
|
4095
4127
|
test('keeps Protocol V2 bootloader active before firmware transfer', async () => {
|
|
4096
4128
|
const method = new FirmwareUpdateV4({
|
|
4097
4129
|
id: 1,
|
|
@@ -4117,6 +4149,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
4117
4149
|
|
|
4118
4150
|
expect((method as any).protocolV2Reboot).not.toHaveBeenCalled();
|
|
4119
4151
|
expect(method.postTipMessage).not.toHaveBeenCalledWith('AutoRebootToBootloader');
|
|
4152
|
+
expect(method.postTipMessage).toHaveBeenCalledWith('GoToBootloaderSuccess');
|
|
4120
4153
|
});
|
|
4121
4154
|
|
|
4122
4155
|
test('keeps Protocol V2 romloader active before firmware transfer', async () => {
|
|
@@ -5913,8 +5946,9 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5913
5946
|
|
|
5914
5947
|
(method as any).device = stubDevice({
|
|
5915
5948
|
getCommands: () => ({ typedCall }),
|
|
5949
|
+
toMessageObject: () => ({ connectId: 'firmware-device' }),
|
|
5916
5950
|
});
|
|
5917
|
-
method.
|
|
5951
|
+
method.postMessage = jest.fn();
|
|
5918
5952
|
|
|
5919
5953
|
await (method as any).protocolV2CommonUpdateProcess({
|
|
5920
5954
|
payload: new Uint8Array(4097).buffer,
|
|
@@ -5929,6 +5963,17 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5929
5963
|
expect(writePayloads.map(payload => payload.overwrite)).toEqual([true, false]);
|
|
5930
5964
|
expect(writePayloads.every(payload => payload.append === false)).toBe(true);
|
|
5931
5965
|
expect(writePayloads.map(payload => payload.ui_percentage)).toEqual([0, 100]);
|
|
5966
|
+
expect(method.postMessage).toHaveBeenLastCalledWith({
|
|
5967
|
+
event: 'UI_EVENT',
|
|
5968
|
+
type: UI_REQUEST.FIRMWARE_PROGRESS,
|
|
5969
|
+
payload: expect.objectContaining({
|
|
5970
|
+
progress: 99,
|
|
5971
|
+
progressType: 'transferData',
|
|
5972
|
+
transferredBytes: 4097,
|
|
5973
|
+
totalBytes: 4097,
|
|
5974
|
+
elapsedMs: expect.any(Number),
|
|
5975
|
+
}),
|
|
5976
|
+
});
|
|
5932
5977
|
});
|
|
5933
5978
|
|
|
5934
5979
|
test('restarts the whole file from offset zero after an ambiguous chunk write failure', async () => {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
2
|
|
|
3
3
|
import { writeProtocolV2File } from '../src/api/helpers/protocolV2FileWrite';
|
|
4
|
+
import { DataManager } from '../src/data-manager';
|
|
5
|
+
import { LoggerNames, getLogger } from '../src/utils/logger';
|
|
4
6
|
|
|
5
7
|
jest.mock('../src/data/config', () => ({
|
|
6
8
|
getSDKVersion: jest.fn(() => '1.0.0'),
|
|
@@ -65,6 +67,24 @@ describe('writeProtocolV2File', () => {
|
|
|
65
67
|
).rejects.toMatchObject({ errorCode: HardwareErrorCode.RuntimeError });
|
|
66
68
|
});
|
|
67
69
|
|
|
70
|
+
test('拒绝非 FilesystemFile 响应', async () => {
|
|
71
|
+
const typedCall = jest.fn().mockResolvedValue({
|
|
72
|
+
type: 'CallMethodError',
|
|
73
|
+
message: { error: 'unexpected response' },
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
await expect(
|
|
77
|
+
writeProtocolV2File({
|
|
78
|
+
commands: { typedCall } as any,
|
|
79
|
+
path: 'vol1:/wallpapers/test.bin',
|
|
80
|
+
data: new Uint8Array([1]),
|
|
81
|
+
})
|
|
82
|
+
).rejects.toMatchObject({
|
|
83
|
+
errorCode: HardwareErrorCode.RuntimeError,
|
|
84
|
+
message: 'FilesystemFileWrite received unexpected response CallMethodError',
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
68
88
|
test('BLE 响应超时时原偏移重试且不重复上报进度', async () => {
|
|
69
89
|
const timeoutError = Object.assign(new Error('Lowlevel response timeout'), {
|
|
70
90
|
errorCode: HardwareErrorCode.BleTimeoutError,
|
|
@@ -90,6 +110,31 @@ describe('writeProtocolV2File', () => {
|
|
|
90
110
|
expect(onProgress).toHaveBeenCalledTimes(1);
|
|
91
111
|
});
|
|
92
112
|
|
|
113
|
+
test('支持固件上传的响应写入选项和全局设备进度', async () => {
|
|
114
|
+
const typedCall = jest.fn().mockResolvedValue({ message: { processed_byte: 3 } });
|
|
115
|
+
const getUiPercentage = jest.fn().mockReturnValue(42);
|
|
116
|
+
|
|
117
|
+
await writeProtocolV2File({
|
|
118
|
+
commands: { typedCall } as any,
|
|
119
|
+
path: 'vol0:/firmware.bin',
|
|
120
|
+
data: new Uint8Array([1, 2, 3]),
|
|
121
|
+
writeWithResponse: true,
|
|
122
|
+
getUiPercentage,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
expect(getUiPercentage).toHaveBeenCalledWith({
|
|
126
|
+
offset: 0,
|
|
127
|
+
chunkLength: 3,
|
|
128
|
+
totalSize: 3,
|
|
129
|
+
});
|
|
130
|
+
expect(typedCall).toHaveBeenCalledWith(
|
|
131
|
+
'FilesystemFileWrite',
|
|
132
|
+
'FilesystemFile',
|
|
133
|
+
expect.objectContaining({ ui_percentage: 42 }),
|
|
134
|
+
{ writeWithResponse: true }
|
|
135
|
+
);
|
|
136
|
+
});
|
|
137
|
+
|
|
93
138
|
test('按确认分片的时间窗口记录实时传输速率', async () => {
|
|
94
139
|
const data = new Uint8Array(4097);
|
|
95
140
|
const typedCall = jest.fn().mockResolvedValue({ message: {} });
|
|
@@ -128,4 +173,72 @@ describe('writeProtocolV2File', () => {
|
|
|
128
173
|
})
|
|
129
174
|
);
|
|
130
175
|
});
|
|
176
|
+
|
|
177
|
+
test('通过 Core Log 每十秒输出一次 BLE 传输关键指标', async () => {
|
|
178
|
+
const log = getLogger(LoggerNames.Method);
|
|
179
|
+
const logSpy = jest.spyOn(log, 'log').mockImplementation(() => undefined);
|
|
180
|
+
const getSettingsSpy = jest
|
|
181
|
+
.spyOn(DataManager, 'getSettings')
|
|
182
|
+
.mockReturnValue('react-native' as any);
|
|
183
|
+
const isBleConnectSpy = jest.spyOn(DataManager, 'isBleConnect').mockReturnValue(true);
|
|
184
|
+
const data = new Uint8Array(5400);
|
|
185
|
+
const typedCall = jest.fn().mockResolvedValue({ message: {} });
|
|
186
|
+
const dateNowSpy = jest
|
|
187
|
+
.spyOn(Date, 'now')
|
|
188
|
+
.mockReturnValueOnce(1_000)
|
|
189
|
+
.mockReturnValueOnce(5_000)
|
|
190
|
+
.mockReturnValueOnce(11_000)
|
|
191
|
+
.mockReturnValueOnce(15_000);
|
|
192
|
+
|
|
193
|
+
try {
|
|
194
|
+
await writeProtocolV2File({
|
|
195
|
+
commands: { typedCall } as any,
|
|
196
|
+
path: 'vol1:/wallpapers/test.bin',
|
|
197
|
+
data,
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
expect(logSpy).toHaveBeenCalledTimes(2);
|
|
201
|
+
expect(logSpy).toHaveBeenNthCalledWith(
|
|
202
|
+
1,
|
|
203
|
+
'[FileWrite] metrics transport=BLE status=progress bytes=3600/5400 elapsed=10.00s speed=0.35 KiB/s'
|
|
204
|
+
);
|
|
205
|
+
expect(logSpy).toHaveBeenNthCalledWith(
|
|
206
|
+
2,
|
|
207
|
+
'[FileWrite] metrics transport=BLE status=completed bytes=5400/5400 elapsed=14.00s speed=0.44 KiB/s'
|
|
208
|
+
);
|
|
209
|
+
} finally {
|
|
210
|
+
dateNowSpy.mockRestore();
|
|
211
|
+
getSettingsSpy.mockRestore();
|
|
212
|
+
isBleConnectSpy.mockRestore();
|
|
213
|
+
logSpy.mockRestore();
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
test('写入失败时通过 Core Log 输出已传输字节和平均速率', async () => {
|
|
218
|
+
const log = getLogger(LoggerNames.Method);
|
|
219
|
+
const logSpy = jest.spyOn(log, 'log').mockImplementation(() => undefined);
|
|
220
|
+
const typedCall = jest.fn().mockRejectedValue(new Error('write failed'));
|
|
221
|
+
const dateNowSpy = jest
|
|
222
|
+
.spyOn(Date, 'now')
|
|
223
|
+
.mockReturnValueOnce(1_000)
|
|
224
|
+
.mockReturnValueOnce(2_000);
|
|
225
|
+
|
|
226
|
+
try {
|
|
227
|
+
await expect(
|
|
228
|
+
writeProtocolV2File({
|
|
229
|
+
commands: { typedCall } as any,
|
|
230
|
+
path: 'vol1:/wallpapers/test.bin',
|
|
231
|
+
data: new Uint8Array(4000),
|
|
232
|
+
})
|
|
233
|
+
).rejects.toThrow('write failed');
|
|
234
|
+
|
|
235
|
+
expect(logSpy).toHaveBeenNthCalledWith(
|
|
236
|
+
1,
|
|
237
|
+
'[FileWrite] metrics transport=unknown status=failed bytes=0/4000 elapsed=1.00s speed=0.00 KiB/s'
|
|
238
|
+
);
|
|
239
|
+
} finally {
|
|
240
|
+
dateNowSpy.mockRestore();
|
|
241
|
+
logSpy.mockRestore();
|
|
242
|
+
}
|
|
243
|
+
});
|
|
131
244
|
});
|
|
@@ -55,7 +55,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
55
55
|
private protocolV2CommonUpdateProcess;
|
|
56
56
|
private protocolV2WriteWholeFile;
|
|
57
57
|
private getProtocolV2FirmwareTransferTransport;
|
|
58
|
-
private fileWriteChunk;
|
|
59
58
|
private recoverProtocolV2FileTransfer;
|
|
60
59
|
private acquireProtocolV2BleDevice;
|
|
61
60
|
private protocolV2StartFirmwareUpdate;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAkB/E,OAAO,KAAK,EAAE,sBAAsB,EAA0B,MAAM,6BAA6B,CAAC;AAkUlG,eAAO,MAAM,oCAAoC,WACvC,WAAW,GAAG,UAAU,eACnB,MAAM,GAAG,SAAS,YAKhC,CAAC;AAEF,eAAO,MAAM,iCAAiC,0BACrB,MAAM,uBACR,MAAM,SAa5B,CAAC;AAUF,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,wBAAwB,CAAC,sBAAsB,CAAC;IAC5F,OAAO,CAAC,8BAA8B,CAAC,CAAS;IAEhD,qBAAqB;IAIrB,IAAI;IA6DJ,OAAO,CAAC,8BAA8B;IAiBhC,GAAG;;;;;YAKK,aAAa;YAwGb,2BAA2B;IAWzC,OAAO,CAAC,yBAAyB;IAKjC,OAAO,CAAC,kCAAkC;IAO1C,OAAO,CAAC,8BAA8B;YAMxB,iCAAiC;YAOjC,iCAAiC;YAOjC,iCAAiC;IAM/C,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,4BAA4B;IASpC,OAAO,CAAC,2BAA2B;IAsBnC,OAAO,CAAC,yBAAyB;IAiBjC,OAAO,CAAC,wBAAwB;YAkBlB,iCAAiC;YAmCjC,+BAA+B;IAqD7C,OAAO,CAAC,qCAAqC;YAuB/B,8BAA8B;IAyB5C,OAAO,CAAC,wCAAwC;YAgBlC,gCAAgC;YAqChC,0BAA0B;YAe1B,6BAA6B;IAkC3C,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,yBAAyB;IAU3B,6BAA6B;YA6BrB,+BAA+B;IAkD7C,OAAO,CAAC,6BAA6B;YAkCvB,uBAAuB;IA4GrC,OAAO,CAAC,mCAAmC;YAI7B,0BAA0B;IAaxC,OAAO,CAAC,4BAA4B;IAgEpC,OAAO,CAAC,6BAA6B;YAcvB,uCAAuC;YAoJvC,gCAAgC;YAchC,yBAAyB;YAQzB,8BAA8B;IAQ5C,OAAO,CAAC,0BAA0B;YAiBpB,qCAAqC;YAgDrC,yBAAyB;YA8DzB,8BAA8B;IAU5C,OAAO,CAAC,kCAAkC;YAI5B,6BAA6B;YAwB7B,wBAAwB;IAyDtC,OAAO,CAAC,sCAAsC;YAchC,6BAA6B;YAW7B,0BAA0B;YAS1B,6BAA6B;YAmB7B,gBAAgB;IAiB9B,OAAO,CAAC,qBAAqB;CAM9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AllNetworkGetAddressBase.d.ts","sourceRoot":"","sources":["../../../src/api/allnetwork/AllNetworkGetAddressBase.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAe3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EACV,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,QAAQ,EACT,MAAM,sCAAsC,CAAC;AAI9C,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,uBAAuB,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,GAAG,CAAC;IAClG,kBAAkB,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,EAAE,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC,CAAC;AAEzF,MAAM,MAAM,gBAAgB,GAAG;KAC5B,CAAC,IAAI,YAAY,GAAG,aAAa;CACnC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAOrD,CAAC;AAiMF,KAAK,YAAY,GAAG;IAClB,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,oBAAoB,EAAE,uBAAuB,CAAC;IAC9C,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,wBAAyB,SAAQ,UAAU,CACvE;IACE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,EAAE,CACJ;IACC,qBAAqB;IAIrB,eAAe,EAAE,eAAe,GAAG,IAAI,CAAQ;IAE/C,IAAI;IAkBJ,kBAAkB,CAAC,EACjB,OAAO,EACP,OAAO,EACP,aAAa,GACd,EAAE;QACD,OAAO,EAAE,QAAQ,CAAC;QAClB,OAAO,EAAE,uBAAuB,CAAC;QACjC,aAAa,EAAE,MAAM,CAAC;KACvB,GAAG,YAAY;IAqBV,UAAU,CACd,UAAU,EAAE,MAAM,OAAO,EACzB,MAAM,EAAE,GAAG,GAAG;QACZ,MAAM,EAAE,CAAC,GAAG,GAAG;YAAE,oBAAoB,EAAE,oBAAoB,CAAA;SAAE,CAAC,EAAE,CAAC;KAClE,EACD,eAAe,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"AllNetworkGetAddressBase.d.ts","sourceRoot":"","sources":["../../../src/api/allnetwork/AllNetworkGetAddressBase.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAe3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EACV,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,QAAQ,EACT,MAAM,sCAAsC,CAAC;AAI9C,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,uBAAuB,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,GAAG,CAAC;IAClG,kBAAkB,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,EAAE,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC,CAAC;AAEzF,MAAM,MAAM,gBAAgB,GAAG;KAC5B,CAAC,IAAI,YAAY,GAAG,aAAa;CACnC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAOrD,CAAC;AAiMF,KAAK,YAAY,GAAG;IAClB,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,oBAAoB,EAAE,uBAAuB,CAAC;IAC9C,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,wBAAyB,SAAQ,UAAU,CACvE;IACE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,EAAE,CACJ;IACC,qBAAqB;IAIrB,eAAe,EAAE,eAAe,GAAG,IAAI,CAAQ;IAE/C,IAAI;IAkBJ,kBAAkB,CAAC,EACjB,OAAO,EACP,OAAO,EACP,aAAa,GACd,EAAE;QACD,OAAO,EAAE,QAAQ,CAAC;QAClB,OAAO,EAAE,uBAAuB,CAAC;QACjC,aAAa,EAAE,MAAM,CAAC;KACvB,GAAG,YAAY;IAqBV,UAAU,CACd,UAAU,EAAE,MAAM,OAAO,EACzB,MAAM,EAAE,GAAG,GAAG;QACZ,MAAM,EAAE,CAAC,GAAG,GAAG;YAAE,oBAAoB,EAAE,oBAAoB,CAAA;SAAE,CAAC,EAAE,CAAC;KAClE,EACD,eAAe,EAAE,MAAM;IAsIzB,QAAQ,CAAC,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAE9E,GAAG;CAyBV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeviceSettings.d.ts","sourceRoot":"","sources":["../../../src/api/device/DeviceSettings.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"DeviceSettings.d.ts","sourceRoot":"","sources":["../../../src/api/device/DeviceSettings.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAe3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAuD5D,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,UAAU,CAAC,aAAa,CAAC;IACnE,qBAAqB;IAIrB,IAAI;IAwEJ,eAAe;;;;;;;IAWT,GAAG;CAgIV"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { BaseMethod } from '../BaseMethod';
|
|
3
|
-
import type { IFirmwareUpdateProgressType, IFirmwareUpdateTipMessage } from '../../events/ui-request';
|
|
3
|
+
import type { FirmwareProgress, IFirmwareUpdateProgressType, IFirmwareUpdateTipMessage } from '../../events/ui-request';
|
|
4
4
|
import type { PROTO } from '../../constants';
|
|
5
5
|
import type { RebootType } from '@onekeyfe/hd-transport';
|
|
6
6
|
import type { Deferred } from '@onekeyfe/hd-shared';
|
|
7
7
|
import type { TypedResponseMessage } from '../../device/DeviceCommands';
|
|
8
|
+
type FirmwareTransferMetrics = Pick<FirmwareProgress['payload'], 'transferredBytes' | 'totalBytes' | 'rateBytesPerSecond' | 'elapsedMs'>;
|
|
8
9
|
export declare class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
|
|
9
10
|
checkPromise: Deferred<any> | null;
|
|
10
11
|
init(): void;
|
|
@@ -12,7 +13,7 @@ export declare class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params>
|
|
|
12
13
|
isBleReconnect(): boolean;
|
|
13
14
|
postTipMessage: (message: IFirmwareUpdateTipMessage) => void;
|
|
14
15
|
postProcessingMessage: (type: 'firmware' | 'ble' | 'bootloader' | 'resource') => void;
|
|
15
|
-
postProgressMessage: (progress: number, progressType: IFirmwareUpdateProgressType) => void;
|
|
16
|
+
postProgressMessage: (progress: number, progressType: IFirmwareUpdateProgressType, metrics?: FirmwareTransferMetrics) => void;
|
|
16
17
|
protected _promptDeviceInBootloaderForWebDevice(): Promise<unknown>;
|
|
17
18
|
protected _promptDeviceForSwitchFirmwareWebDevice(): Promise<unknown>;
|
|
18
19
|
checkDeviceToBootloader(connectId: string | undefined): void;
|
|
@@ -30,4 +31,5 @@ export declare class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params>
|
|
|
30
31
|
emmcFileWriteWithRetry(filePath: string, chunkLength: number, offset: number, chunk: ArrayBuffer | Buffer, overwrite: boolean, progress: number | null): Promise<TypedResponseMessage<"EmmcFile"> | undefined>;
|
|
31
32
|
reboot(rebootType: RebootType): Promise<import("@onekeyfe/hd-transport").Success>;
|
|
32
33
|
}
|
|
34
|
+
export {};
|
|
33
35
|
//# sourceMappingURL=FirmwareUpdateBaseMethod.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FirmwareUpdateBaseMethod.d.ts","sourceRoot":"","sources":["../../../src/api/firmware/FirmwareUpdateBaseMethod.ts"],"names":[],"mappings":";AAaA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,KAAK,EACV,2BAA2B,EAC3B,yBAAyB,EAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"FirmwareUpdateBaseMethod.d.ts","sourceRoot":"","sources":["../../../src/api/firmware/FirmwareUpdateBaseMethod.ts"],"names":[],"mappings":";AAaA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,KAAK,EACV,gBAAgB,EAChB,2BAA2B,EAC3B,yBAAyB,EAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAMxE,KAAK,uBAAuB,GAAG,IAAI,CACjC,gBAAgB,CAAC,SAAS,CAAC,EAC3B,kBAAkB,GAAG,YAAY,GAAG,oBAAoB,GAAG,WAAW,CACvE,CAAC;AAWF,qBAAa,wBAAwB,CAAC,MAAM,CAAE,SAAQ,UAAU,CAAC,MAAM,CAAC;IACtE,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAQ;IAE1C,IAAI,IAAI,IAAI;IAEZ,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IAInB,cAAc,IAAI,OAAO;IASzB,cAAc,YAAa,yBAAyB,UASlD;IAMF,qBAAqB,SAAU,UAAU,GAAG,KAAK,GAAG,YAAY,GAAG,UAAU,UAM3E;IAMF,mBAAmB,aACP,MAAM,gBACF,2BAA2B,YAC/B,uBAAuB,UAUjC;cAEc,qCAAqC;cAkBrC,uCAAuC;IAkBvD,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS;YA2FvC,4BAA4B;IAyBpC,mBAAmB;IA8CnB,uBAAuB,CAAC,EAAE,IAAI,EAAE,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;IA6BlD,8BAA8B,CAAC,IAAI,EAAE,MAAM;IAW3C,uBAAuB,CAAC,EAC5B,OAAO,EACP,QAAQ,EACR,aAAa,EACb,SAAS,GACV,EAAE,KAAK,CAAC,cAAc,GAAG;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;IA4CK,sBAAsB,CAC1B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,WAAW,GAAG,MAAM,EAC3B,SAAS,EAAE,OAAO,EAClB,QAAQ,EAAE,MAAM,GAAG,IAAI;IAgFnB,MAAM,CAAC,UAAU,EAAE,UAAU;CAsBpC"}
|