@onekeyfe/hd-core 1.2.0-alpha.53 → 1.2.0-alpha.54
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 +0 -78
- package/__tests__/DeviceCommands.test.ts +0 -45
- package/__tests__/DeviceEventRegistration.test.ts +0 -6
- package/__tests__/check-all-firmware-release-protocol-v2.test.ts +3 -198
- package/__tests__/connectSettings.test.ts +47 -5
- package/__tests__/device-initialize-timeout.test.ts +56 -0
- package/__tests__/device-lifecycle-events.test.ts +3 -105
- package/__tests__/firmware-update/check-all-firmware-release.test.ts +175 -0
- package/__tests__/firmware-update/firmware-artifact-source.test.ts +119 -0
- package/__tests__/firmware-update/firmware-host-binding.test.ts +70 -0
- package/__tests__/firmware-update/firmware-preparation-error.test.ts +27 -0
- package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +200 -0
- package/__tests__/firmware-update/firmware-update-capabilities.test.ts +13 -0
- package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +294 -0
- package/__tests__/firmware-update/firmware-update-plan.test.ts +593 -0
- package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +213 -0
- package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +59 -31
- package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +58 -0
- package/__tests__/firmware-update/firmware-upload-source.test.ts +70 -0
- package/__tests__/get-device-state.test.ts +12 -132
- package/__tests__/homescreen.test.ts +1 -41
- package/__tests__/logBlockEvent.test.ts +1 -1
- package/__tests__/method-protocol-support.test.ts +0 -19
- package/__tests__/open-wallet-session.test.ts +33 -446
- package/__tests__/protocol-v2-unlock-policy.test.ts +35 -201
- package/__tests__/protocol-v2.test.ts +1034 -1378
- package/__tests__/protocolV2UiInteraction.test.ts +0 -63
- package/__tests__/public-pro2-api-boundary.test.ts +0 -1
- package/__tests__/search-devices.test.ts +3 -12
- package/dist/api/BaseMethod.d.ts +1 -3
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/CheckAllFirmwareRelease.d.ts +1 -2
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/FirmwareUpdate.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts +11 -0
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts +7 -3
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +25 -11
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/GetPassphraseState.d.ts.map +1 -1
- package/dist/api/OpenWalletSession.d.ts.map +1 -1
- package/dist/api/SearchDevices.d.ts.map +1 -1
- package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
- package/dist/api/device/DeviceUnlock.d.ts +2 -2
- package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts +5 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareArtifactSource.d.ts +25 -0
- package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareHostBinding.d.ts +6 -0
- package/dist/api/firmware/FirmwareHostBinding.d.ts.map +1 -0
- package/dist/api/firmware/FirmwarePreparationError.d.ts +3 -0
- package/dist/api/firmware/FirmwarePreparationError.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +9 -0
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +3 -0
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts +25 -0
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +32 -0
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -0
- package/dist/api/firmware/getBinary.d.ts +7 -0
- package/dist/api/firmware/getBinary.d.ts.map +1 -1
- package/dist/api/firmware/progressThrottle.d.ts +3 -0
- package/dist/api/firmware/progressThrottle.d.ts.map +1 -0
- package/dist/api/firmware/updateBootloader.d.ts +2 -0
- package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/uploadFirmware.d.ts +9 -1
- package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
- package/dist/api/helpers/protocolV2FileWrite.d.ts +0 -2
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
- package/dist/api/index.d.ts +0 -2
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
- package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
- package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
- package/dist/core/deviceEventRegistration.d.ts +0 -2
- package/dist/core/deviceEventRegistration.d.ts.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/data-manager/DataManager.d.ts +2 -4
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/data-manager/connectSettings.d.ts.map +1 -1
- package/dist/device/Device.d.ts +6 -29
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts +4 -4
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/device/DevicePool.d.ts.map +1 -1
- package/dist/events/device.d.ts +0 -4
- package/dist/events/device.d.ts.map +1 -1
- package/dist/events/logBlockEvent.d.ts.map +1 -1
- package/dist/events/ui-promise.d.ts +2 -4
- package/dist/events/ui-promise.d.ts.map +1 -1
- package/dist/events/ui-request.d.ts +2 -31
- package/dist/events/ui-request.d.ts.map +1 -1
- package/dist/events/ui-response.d.ts +2 -10
- package/dist/events/ui-response.d.ts.map +1 -1
- package/dist/index.d.ts +231 -214
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3497 -2559
- package/dist/inject.d.ts +1 -6
- package/dist/inject.d.ts.map +1 -1
- package/dist/lowLevelInject.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/lockedError.d.ts +2 -0
- package/dist/protocols/protocol-v2/lockedError.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/uiInteraction.d.ts +4 -7
- package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts +3 -1
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockRetry.d.ts +10 -0
- package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts +1 -5
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
- package/dist/topLevelInject.d.ts.map +1 -1
- package/dist/types/api/checkAllFirmwareRelease.d.ts +4 -2
- package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/deviceUnlock.d.ts +1 -5
- package/dist/types/api/deviceUnlock.d.ts.map +1 -1
- package/dist/types/api/deviceUpdateBootloader.d.ts +6 -0
- package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
- package/dist/types/api/export.d.ts +4 -2
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +70 -2
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdateCapabilities.d.ts +9 -0
- package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +1 -0
- package/dist/types/api/firmwareUpdatePlan.d.ts +28 -0
- package/dist/types/api/firmwareUpdatePlan.d.ts.map +1 -0
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +42 -0
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +1 -0
- package/dist/types/api/index.d.ts +10 -7
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +0 -3
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/types/device.d.ts.map +1 -1
- package/dist/types/params.d.ts +0 -1
- package/dist/types/params.d.ts.map +1 -1
- package/dist/types/settings.d.ts +13 -22
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesCompat.d.ts +1 -0
- package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts +0 -4
- package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
- package/dist/utils/homescreen.d.ts +0 -4
- package/dist/utils/homescreen.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/patch.d.ts +1 -1
- package/dist/utils/patch.d.ts.map +1 -1
- package/dist/utils/pro2Wallpaper.d.ts +0 -10
- package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/BaseMethod.ts +10 -8
- package/src/api/CheckAllFirmwareRelease.ts +57 -54
- package/src/api/FirmwareUpdate.ts +15 -7
- package/src/api/FirmwareUpdateV2.ts +316 -126
- package/src/api/FirmwareUpdateV3.ts +265 -63
- package/src/api/FirmwareUpdateV4.ts +965 -566
- package/src/api/GetPassphraseState.ts +1 -7
- package/src/api/OpenWalletSession.ts +17 -54
- package/src/api/SearchDevices.ts +1 -3
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +11 -32
- package/src/api/device/DeviceUnlock.ts +3 -8
- package/src/api/device/DeviceUpdateBootloader.ts +122 -6
- package/src/api/firmware/FirmwareArtifactSource.ts +278 -0
- package/src/api/firmware/FirmwareHostBinding.ts +100 -0
- package/src/api/firmware/FirmwarePreparationError.ts +12 -0
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +83 -16
- package/src/api/firmware/FirmwareUpdateCapabilities.ts +9 -0
- package/src/api/firmware/FirmwareUpdatePlan.ts +772 -0
- package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +415 -0
- package/src/api/firmware/progressThrottle.ts +44 -0
- package/src/api/firmware/updateBootloader.ts +19 -4
- package/src/api/firmware/uploadFirmware.ts +144 -39
- package/src/api/helpers/protocolV2FileWrite.ts +4 -11
- package/src/api/index.ts +0 -2
- package/src/api/protocol-v2/ProtocolInfoRequest.ts +1 -3
- package/src/api/protocol-v2/helpers.ts +0 -1
- package/src/core/deviceEventRegistration.ts +0 -4
- package/src/core/index.ts +83 -167
- package/src/data/messages/messages-protocol-v2.json +0 -25
- package/src/data-manager/DataManager.ts +38 -67
- package/src/data-manager/connectSettings.ts +11 -0
- package/src/device/Device.ts +42 -258
- package/src/device/DeviceCommands.ts +1 -7
- package/src/device/DevicePool.ts +2 -7
- package/src/events/device.ts +0 -4
- package/src/events/logBlockEvent.ts +0 -1
- package/src/events/ui-promise.ts +2 -4
- package/src/events/ui-request.ts +2 -36
- package/src/events/ui-response.ts +2 -12
- package/src/index.ts +5 -0
- package/src/inject.ts +24 -60
- package/src/lowLevelInject.ts +8 -7
- package/src/protocols/protocol-v2/features.ts +3 -10
- package/src/protocols/protocol-v2/lockedError.ts +10 -0
- package/src/protocols/protocol-v2/uiInteraction.ts +6 -46
- package/src/protocols/protocol-v2/unlockPolicy.ts +105 -1
- package/src/protocols/protocol-v2/unlockRetry.ts +109 -0
- package/src/protocols/protocol-v2/walletSession.ts +30 -180
- package/src/topLevelInject.ts +8 -7
- package/src/types/api/checkAllFirmwareRelease.ts +4 -2
- package/src/types/api/deviceUnlock.ts +1 -12
- package/src/types/api/deviceUpdateBootloader.ts +6 -0
- package/src/types/api/export.ts +18 -1
- package/src/types/api/firmwareUpdate.ts +76 -3
- package/src/types/api/firmwareUpdateCapabilities.ts +9 -0
- package/src/types/api/firmwareUpdatePlan.ts +38 -0
- package/src/types/api/firmwareUpdatePreparedPlan.ts +53 -0
- package/src/types/api/index.ts +14 -13
- package/src/types/api/protocolV2.ts +0 -13
- package/src/types/device.ts +0 -3
- package/src/types/params.ts +1 -7
- package/src/types/settings.ts +13 -42
- package/src/utils/deviceFeaturesCompat.ts +6 -0
- package/src/utils/deviceFeaturesUtils.ts +0 -8
- package/src/utils/homescreen.ts +6 -32
- package/src/utils/index.ts +1 -6
- package/src/utils/pro2Wallpaper.ts +8 -35
- package/__tests__/deviceUploadNft.test.ts +0 -293
- package/__tests__/pro2Nft.test.ts +0 -108
- package/__tests__/protocol-binding.test.ts +0 -89
- package/__tests__/protocol-v2-resources.test.ts +0 -284
- package/__tests__/protocol-v2-ui-lifecycle.test.ts +0 -91
- package/__tests__/uiProgressThrottle.test.ts +0 -74
- package/__tests__/uiPromiseRegistry.test.ts +0 -86
- package/dist/api/DetectDeviceConnectProtocol.d.ts +0 -7
- package/dist/api/DetectDeviceConnectProtocol.d.ts.map +0 -1
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts +0 -31
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +0 -1
- package/dist/core/uiPromiseRegistry.d.ts +0 -4
- package/dist/core/uiPromiseRegistry.d.ts.map +0 -1
- package/dist/protocols/protocol-v2/resources.d.ts +0 -30
- package/dist/protocols/protocol-v2/resources.d.ts.map +0 -1
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +0 -22
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +0 -1
- package/dist/types/api/detectDeviceConnectProtocol.d.ts +0 -4
- package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +0 -1
- package/dist/utils/pro2Nft.d.ts +0 -31
- package/dist/utils/pro2Nft.d.ts.map +0 -1
- package/dist/utils/uiProgressThrottle.d.ts +0 -3
- package/dist/utils/uiProgressThrottle.d.ts.map +0 -1
- package/src/api/DetectDeviceConnectProtocol.ts +0 -18
- package/src/api/protocol-v2/DeviceUploadNft.ts +0 -189
- package/src/core/uiPromiseRegistry.ts +0 -41
- package/src/protocols/protocol-v2/resources.ts +0 -359
- package/src/protocols/protocol-v2/unlockPolicyRunner.ts +0 -118
- package/src/types/api/detectDeviceConnectProtocol.ts +0 -7
- package/src/utils/pro2Nft.ts +0 -142
- package/src/utils/uiProgressThrottle.ts +0 -63
|
@@ -14,18 +14,46 @@ import { BaseMethod } from './BaseMethod';
|
|
|
14
14
|
import { validateParams } from './helpers/paramsValidator';
|
|
15
15
|
import { DevicePool } from '../device/DevicePool';
|
|
16
16
|
import { getBinary, getInfo, getSysResourceBinary } from './firmware/getBinary';
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
17
|
+
import { normalizeFirmwarePreparationError } from './firmware/FirmwarePreparationError';
|
|
18
|
+
import {
|
|
19
|
+
updateResources,
|
|
20
|
+
updateResourcesFromSources,
|
|
21
|
+
uploadFirmwareFromSource,
|
|
22
|
+
} from './firmware/uploadFirmware';
|
|
23
|
+
import { BOOTLOADER_POLL_INITIALIZE_TIMEOUT_MS } from './firmware/FirmwareUpdateBaseMethod';
|
|
24
|
+
import { LoggerNames, getDeviceType, getDeviceUUID, getLogger, wait } from '../utils';
|
|
25
|
+
import { resolveDeviceBootloaderMode } from '../utils/deviceFeaturesCompat';
|
|
19
26
|
import { FirmwareUpdateTipMessage, createUiMessage } from '../events/ui-request';
|
|
20
27
|
import { DeviceModelToTypes } from '../types';
|
|
21
28
|
import { DataManager } from '../data-manager';
|
|
22
29
|
import { DEVICE } from '../events';
|
|
30
|
+
import { type FirmwareByteSource, openFirmwareByteSource } from './firmware/FirmwareArtifactSource';
|
|
31
|
+
import { resolveFirmwareUpdateHostBinding } from './firmware/FirmwareHostBinding';
|
|
32
|
+
import {
|
|
33
|
+
assertFirmwareUpdatePreparedPlanBinding,
|
|
34
|
+
assertFirmwareUpdatePreparedPlanDeviceIdentity,
|
|
35
|
+
getFirmwareUpdateResourceName,
|
|
36
|
+
} from './firmware/FirmwareUpdatePreparedPlan';
|
|
23
37
|
|
|
24
38
|
import type { Features, KnownDevice } from '../types';
|
|
25
39
|
import type { FirmwareBinary } from './firmware/getBinary';
|
|
40
|
+
import type {
|
|
41
|
+
FirmwareArtifactReader,
|
|
42
|
+
FirmwareArtifactReference,
|
|
43
|
+
} from '../types/api/firmwareUpdate';
|
|
44
|
+
import type { FirmwareUpdatePreparedPlan } from '../types/api/firmwareUpdatePreparedPlan';
|
|
26
45
|
|
|
27
46
|
type Params = {
|
|
28
47
|
binary?: ArrayBuffer;
|
|
48
|
+
artifact?: FirmwareArtifactReference;
|
|
49
|
+
resourceArtifact?: FirmwareArtifactReference;
|
|
50
|
+
resourceEntries?: Array<{
|
|
51
|
+
entryName: string;
|
|
52
|
+
artifact: FirmwareArtifactReference;
|
|
53
|
+
}>;
|
|
54
|
+
artifactReader?: FirmwareArtifactReader;
|
|
55
|
+
preparedPlan?: FirmwareUpdatePreparedPlan;
|
|
56
|
+
platform?: FirmwareUpdatePreparedPlan['platform'];
|
|
29
57
|
version?: number[];
|
|
30
58
|
updateType: 'firmware' | 'ble';
|
|
31
59
|
forcedUpdateRes?: boolean;
|
|
@@ -106,6 +134,13 @@ const normalizeFirmwareBinary = (binary: unknown): FirmwareBinary | undefined =>
|
|
|
106
134
|
return normalized.buffer;
|
|
107
135
|
};
|
|
108
136
|
|
|
137
|
+
const toArrayBuffer = (binary: FirmwareBinary): ArrayBuffer => {
|
|
138
|
+
if (binary instanceof ArrayBuffer) {
|
|
139
|
+
return binary;
|
|
140
|
+
}
|
|
141
|
+
return new Uint8Array(binary.buffer, binary.byteOffset, binary.byteLength).slice().buffer;
|
|
142
|
+
};
|
|
143
|
+
|
|
109
144
|
export default class FirmwareUpdateV2 extends BaseMethod<Params> {
|
|
110
145
|
checkPromise: Deferred<any> | null = null;
|
|
111
146
|
|
|
@@ -152,6 +187,38 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
|
|
|
152
187
|
binary: payload.binary,
|
|
153
188
|
};
|
|
154
189
|
}
|
|
190
|
+
|
|
191
|
+
if ('artifact' in payload) {
|
|
192
|
+
const hostBinding = resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration);
|
|
193
|
+
const target = payload.isUpdateBootloader ? 'bootloader' : payload.updateType;
|
|
194
|
+
const resourceBindings = [
|
|
195
|
+
...(payload.resourceArtifact
|
|
196
|
+
? [{ target: 'resource' as const, artifact: payload.resourceArtifact }]
|
|
197
|
+
: []),
|
|
198
|
+
...(payload.resourceEntries ?? []).map(
|
|
199
|
+
(entry: { entryName: string; artifact: FirmwareArtifactReference }) => ({
|
|
200
|
+
target: 'resource' as const,
|
|
201
|
+
entryName: entry.entryName,
|
|
202
|
+
artifact: entry.artifact,
|
|
203
|
+
})
|
|
204
|
+
),
|
|
205
|
+
];
|
|
206
|
+
assertFirmwareUpdatePreparedPlanBinding({
|
|
207
|
+
preparedPlan: payload.preparedPlan,
|
|
208
|
+
executor: 'v2',
|
|
209
|
+
platform: payload.platform,
|
|
210
|
+
scopeTargets: [target, ...(target === 'firmware' ? (['resource'] as const) : [])],
|
|
211
|
+
bindings: [{ target, artifact: payload.artifact }, ...resourceBindings],
|
|
212
|
+
});
|
|
213
|
+
this.params = {
|
|
214
|
+
...this.params,
|
|
215
|
+
preparedPlan: payload.preparedPlan,
|
|
216
|
+
artifact: payload.artifact,
|
|
217
|
+
resourceArtifact: payload.resourceArtifact,
|
|
218
|
+
resourceEntries: payload.resourceEntries,
|
|
219
|
+
artifactReader: hostBinding.artifactReader,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
155
222
|
}
|
|
156
223
|
|
|
157
224
|
postTipMessage = (message: string) => {
|
|
@@ -187,6 +254,10 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
|
|
|
187
254
|
this.checkPromise = createDeferred();
|
|
188
255
|
const env = DataManager.getSettings('env');
|
|
189
256
|
const isBleReconnect = connectId && DataManager.isBleConnect(env);
|
|
257
|
+
// Tracks the in-flight BLE probe so interval ticks never overlap: a superseded
|
|
258
|
+
// Initialize left pending on the V1 transport is exactly what later times out
|
|
259
|
+
// and used to tear down the connection mid-firmware-upload.
|
|
260
|
+
let bleProbeInFlight = false;
|
|
190
261
|
|
|
191
262
|
Log.log('FirmwareUpdateV2 [checkDeviceToBootloader] isBleReconnect: ', isBleReconnect);
|
|
192
263
|
|
|
@@ -234,14 +305,18 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
|
|
|
234
305
|
}
|
|
235
306
|
|
|
236
307
|
if (isBleReconnect) {
|
|
308
|
+
if (bleProbeInFlight) return;
|
|
309
|
+
bleProbeInFlight = true;
|
|
237
310
|
try {
|
|
238
311
|
await this.device.deviceConnector?.acquire(
|
|
239
312
|
this.device.originalDescriptor.id,
|
|
240
313
|
null,
|
|
241
|
-
true
|
|
242
|
-
this.payload.connectProtocol ?? this.device.originalDescriptor.protocolType
|
|
314
|
+
true
|
|
243
315
|
);
|
|
244
|
-
|
|
316
|
+
// Bound each probe so a request the rebooting device never received
|
|
317
|
+
// frees the slot for the next tick instead of hanging into the
|
|
318
|
+
// 30s reboot budget.
|
|
319
|
+
await this.device.initialize({ timeoutMs: BOOTLOADER_POLL_INITIALIZE_TIMEOUT_MS });
|
|
245
320
|
if (this.device.isBootloader()) {
|
|
246
321
|
clearInterval(intervalTimer);
|
|
247
322
|
this.checkPromise?.resolve(true);
|
|
@@ -249,6 +324,8 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
|
|
|
249
324
|
} catch (e) {
|
|
250
325
|
// ignore error because of device is not connected
|
|
251
326
|
Log.log('catch Bluetooth error when device is restarting: ', e);
|
|
327
|
+
} finally {
|
|
328
|
+
bleProbeInFlight = false;
|
|
252
329
|
}
|
|
253
330
|
} else {
|
|
254
331
|
await this._checkDeviceInBootloaderMode(connectId, intervalTimer, timeoutTimer);
|
|
@@ -273,9 +350,7 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
|
|
|
273
350
|
) {
|
|
274
351
|
const deviceDiff = await this.device.deviceConnector?.enumerate();
|
|
275
352
|
const devicesDescriptor = deviceDiff?.descriptors ?? [];
|
|
276
|
-
const { deviceList } = await DevicePool.getDevices(devicesDescriptor, connectId
|
|
277
|
-
connectProtocol: this.payload.connectProtocol ?? this.device.originalDescriptor.protocolType,
|
|
278
|
-
});
|
|
353
|
+
const { deviceList } = await DevicePool.getDevices(devicesDescriptor, connectId);
|
|
279
354
|
|
|
280
355
|
if (deviceList.length === 1 && deviceList[0]?.isBootloader()) {
|
|
281
356
|
// should update current device from cache
|
|
@@ -344,151 +419,266 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
|
|
|
344
419
|
const { features, commands } = device;
|
|
345
420
|
const deviceType = device.getCurrentDeviceType();
|
|
346
421
|
|
|
422
|
+
// Protocol V2 (Pro2) uses DeviceFirmwareUpdate and must not enter this legacy flow.
|
|
423
|
+
if (device.isProtocolV2()) {
|
|
424
|
+
throw ERRORS.TypedError(
|
|
425
|
+
HardwareErrorCode.RuntimeError,
|
|
426
|
+
'Protocol V2 firmware update must use firmwareUpdateV4'
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
if (params.preparedPlan) {
|
|
430
|
+
assertFirmwareUpdatePreparedPlanDeviceIdentity({
|
|
431
|
+
preparedPlan: params.preparedPlan,
|
|
432
|
+
deviceIdentity: getDeviceUUID(features) || undefined,
|
|
433
|
+
bootloaderMode: resolveDeviceBootloaderMode(features),
|
|
434
|
+
deviceModel: String(getDeviceType(features)),
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
|
|
347
438
|
const deviceFirmwareType = device.getCurrentFirmwareType();
|
|
348
439
|
const firmwareType = params.firmwareType ?? deviceFirmwareType;
|
|
349
440
|
|
|
350
441
|
this.checkVersionForCopyTouchResource(features, firmwareType);
|
|
351
442
|
|
|
352
|
-
let
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
if (params.binary !== undefined) {
|
|
360
|
-
preparedBinary = normalizeFirmwareBinary(params.binary);
|
|
361
|
-
if (!preparedBinary) {
|
|
362
|
-
throw new Error('firmware binary is empty or invalid');
|
|
443
|
+
let preparedSource: FirmwareByteSource | undefined;
|
|
444
|
+
try {
|
|
445
|
+
const acquireFirmwareSource = async (): Promise<FirmwareByteSource> => {
|
|
446
|
+
try {
|
|
447
|
+
if (preparedSource) {
|
|
448
|
+
return preparedSource;
|
|
363
449
|
}
|
|
364
|
-
return preparedBinary;
|
|
365
|
-
}
|
|
366
450
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
requestOptions: FIRMWARE_DOWNLOAD_REQUEST_OPTIONS,
|
|
382
|
-
});
|
|
383
|
-
preparedBinary = normalizeFirmwareBinary(firmware.binary);
|
|
384
|
-
if (!preparedBinary) {
|
|
385
|
-
throw new Error('downloaded firmware binary is empty or invalid');
|
|
386
|
-
}
|
|
387
|
-
this.postTipMessage('DownloadFirmwareSuccess');
|
|
388
|
-
return preparedBinary;
|
|
389
|
-
} catch (err) {
|
|
390
|
-
throw ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateDownloadFailed, err.message ?? err);
|
|
391
|
-
}
|
|
392
|
-
};
|
|
451
|
+
if (params.binary !== undefined) {
|
|
452
|
+
const binary = normalizeFirmwareBinary(params.binary);
|
|
453
|
+
if (!binary) {
|
|
454
|
+
throw new Error('firmware binary is empty or invalid');
|
|
455
|
+
}
|
|
456
|
+
const source = await openFirmwareByteSource({
|
|
457
|
+
binary: toArrayBuffer(binary),
|
|
458
|
+
});
|
|
459
|
+
if (!source) {
|
|
460
|
+
throw new Error('firmware binary is empty or invalid');
|
|
461
|
+
}
|
|
462
|
+
preparedSource = source;
|
|
463
|
+
return source;
|
|
464
|
+
}
|
|
393
465
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
466
|
+
if (params.artifact) {
|
|
467
|
+
const source = await openFirmwareByteSource({
|
|
468
|
+
artifact: params.artifact,
|
|
469
|
+
reader: params.artifactReader,
|
|
470
|
+
});
|
|
471
|
+
if (!source) {
|
|
472
|
+
throw new Error('firmware artifact is not prepared');
|
|
473
|
+
}
|
|
474
|
+
preparedSource = source;
|
|
475
|
+
return source;
|
|
476
|
+
}
|
|
400
477
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
features,
|
|
406
|
-
forcedUpdateRes: params.forcedUpdateRes,
|
|
407
|
-
firmwareType,
|
|
408
|
-
});
|
|
409
|
-
if (resourceUrl) {
|
|
410
|
-
this.postTipMessage('DownloadLatestUiResource');
|
|
411
|
-
const resource = await getSysResourceBinary(resourceUrl);
|
|
412
|
-
this.postTipMessage('DownloadLatestUiResourceSuccess');
|
|
413
|
-
if (resource) {
|
|
414
|
-
await updateResources(
|
|
415
|
-
this.device.getCommands().typedCall.bind(this.device.getCommands()),
|
|
416
|
-
this.postMessage,
|
|
417
|
-
device,
|
|
418
|
-
resource.binary
|
|
478
|
+
if (!device.features) {
|
|
479
|
+
throw ERRORS.TypedError(
|
|
480
|
+
HardwareErrorCode.RuntimeError,
|
|
481
|
+
'no features found for this device'
|
|
419
482
|
);
|
|
420
483
|
}
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// check if the device commands has been disposed
|
|
425
|
-
this.device?.commands?.checkDisposed();
|
|
426
484
|
|
|
427
|
-
|
|
428
|
-
|
|
485
|
+
if (
|
|
486
|
+
params.artifactReader ||
|
|
487
|
+
DataManager.getSettings('firmwareManifestMode') === 'external-only'
|
|
488
|
+
) {
|
|
489
|
+
throw ERRORS.TypedError(
|
|
490
|
+
HardwareErrorCode.RuntimeError,
|
|
491
|
+
'Firmware must be prepared by the external firmware host',
|
|
492
|
+
{
|
|
493
|
+
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
494
|
+
artifactName: 'firmware',
|
|
495
|
+
}
|
|
496
|
+
);
|
|
497
|
+
}
|
|
429
498
|
|
|
430
|
-
|
|
431
|
-
|
|
499
|
+
this.postTipMessage('DownloadFirmware');
|
|
500
|
+
const firmware = await getBinary({
|
|
501
|
+
features: device.features,
|
|
502
|
+
version: params.version,
|
|
503
|
+
updateType: params.updateType,
|
|
504
|
+
isUpdateBootloader: params.isUpdateBootloader,
|
|
505
|
+
firmwareType,
|
|
506
|
+
requestOptions: FIRMWARE_DOWNLOAD_REQUEST_OPTIONS,
|
|
507
|
+
});
|
|
508
|
+
const binary = normalizeFirmwareBinary(firmware.binary);
|
|
509
|
+
if (!binary) {
|
|
510
|
+
throw new Error('downloaded firmware binary is empty or invalid');
|
|
511
|
+
}
|
|
512
|
+
const source = await openFirmwareByteSource({
|
|
513
|
+
binary: toArrayBuffer(binary),
|
|
514
|
+
});
|
|
515
|
+
if (!source) {
|
|
516
|
+
throw new Error('downloaded firmware binary is empty or invalid');
|
|
517
|
+
}
|
|
518
|
+
preparedSource = source;
|
|
519
|
+
this.postTipMessage('DownloadFirmwareSuccess');
|
|
520
|
+
return source;
|
|
521
|
+
} catch (err) {
|
|
522
|
+
throw normalizeFirmwarePreparationError(err);
|
|
523
|
+
}
|
|
524
|
+
};
|
|
432
525
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
if (bootRes.type === 'CallMethodError') {
|
|
439
|
-
throw ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateAutoEnterBootFailure);
|
|
526
|
+
if (!device.isBootloader() && features) {
|
|
527
|
+
const serialNo = device.getCurrentSerialNo();
|
|
528
|
+
// should go to bootloader mode manually
|
|
529
|
+
if (this.isEnteredManuallyBoot()) {
|
|
530
|
+
throw ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateManuallyEnterBoot);
|
|
440
531
|
}
|
|
441
|
-
this.postTipMessage('GoToBootloaderSuccess');
|
|
442
|
-
this.checkDeviceToBootloader(this.payload.connectId);
|
|
443
532
|
|
|
444
|
-
//
|
|
445
|
-
|
|
446
|
-
|
|
533
|
+
// All network-backed input must be ready before the first device mutation.
|
|
534
|
+
await acquireFirmwareSource();
|
|
535
|
+
|
|
536
|
+
// check & upgrade firmware resource
|
|
537
|
+
if (this.isSupportResourceUpdate(params.updateType)) {
|
|
538
|
+
this.postTipMessage('CheckLatestUiResource');
|
|
539
|
+
const resourceUrl = DataManager.getSysResourcesLatestRelease({
|
|
540
|
+
features,
|
|
541
|
+
forcedUpdateRes: params.forcedUpdateRes,
|
|
542
|
+
firmwareType,
|
|
543
|
+
});
|
|
544
|
+
if (resourceUrl) {
|
|
545
|
+
this.postTipMessage('DownloadLatestUiResource');
|
|
546
|
+
if (params.resourceEntries?.length) {
|
|
547
|
+
const sources: Array<{
|
|
548
|
+
entryName: string;
|
|
549
|
+
source: FirmwareByteSource;
|
|
550
|
+
}> = [];
|
|
551
|
+
try {
|
|
552
|
+
for (const entry of params.resourceEntries) {
|
|
553
|
+
const resourceName = getFirmwareUpdateResourceName(entry.entryName);
|
|
554
|
+
const source = await openFirmwareByteSource({
|
|
555
|
+
artifact: entry.artifact,
|
|
556
|
+
reader: params.artifactReader,
|
|
557
|
+
});
|
|
558
|
+
if (!source) {
|
|
559
|
+
throw new Error('Firmware resource entry is not prepared');
|
|
560
|
+
}
|
|
561
|
+
sources.push({ entryName: resourceName, source });
|
|
562
|
+
}
|
|
563
|
+
await updateResourcesFromSources(
|
|
564
|
+
this.device.getCommands().typedCall.bind(this.device.getCommands()),
|
|
565
|
+
this.postMessage,
|
|
566
|
+
device,
|
|
567
|
+
sources.map(entry => ({
|
|
568
|
+
entryName: entry.entryName,
|
|
569
|
+
source: entry.source,
|
|
570
|
+
}))
|
|
571
|
+
);
|
|
572
|
+
} finally {
|
|
573
|
+
await Promise.all(
|
|
574
|
+
sources.map(entry => entry.source.close().catch(() => undefined))
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
this.postTipMessage('DownloadLatestUiResourceSuccess');
|
|
578
|
+
} else {
|
|
579
|
+
let resourceBinary: ArrayBuffer | Buffer;
|
|
580
|
+
if (params.resourceArtifact) {
|
|
581
|
+
throw ERRORS.TypedError(
|
|
582
|
+
HardwareErrorCode.RuntimeError,
|
|
583
|
+
'Firmware resource archive must be materialized into prepared entries',
|
|
584
|
+
{
|
|
585
|
+
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
586
|
+
artifactName: 'resource',
|
|
587
|
+
}
|
|
588
|
+
);
|
|
589
|
+
} else {
|
|
590
|
+
if (
|
|
591
|
+
params.artifactReader ||
|
|
592
|
+
DataManager.getSettings('firmwareManifestMode') === 'external-only'
|
|
593
|
+
) {
|
|
594
|
+
throw ERRORS.TypedError(
|
|
595
|
+
HardwareErrorCode.RuntimeError,
|
|
596
|
+
'Firmware resource must be prepared by the external firmware host',
|
|
597
|
+
{
|
|
598
|
+
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
599
|
+
artifactName: 'resource',
|
|
600
|
+
}
|
|
601
|
+
);
|
|
602
|
+
}
|
|
603
|
+
resourceBinary = (await getSysResourceBinary(resourceUrl)).binary;
|
|
604
|
+
}
|
|
605
|
+
this.postTipMessage('DownloadLatestUiResourceSuccess');
|
|
606
|
+
await updateResources(
|
|
607
|
+
this.device.getCommands().typedCall.bind(this.device.getCommands()),
|
|
608
|
+
this.postMessage,
|
|
609
|
+
device,
|
|
610
|
+
resourceBinary
|
|
611
|
+
);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
447
614
|
}
|
|
448
|
-
delete DevicePool.devicesCache[''];
|
|
449
|
-
await this.checkPromise?.promise;
|
|
450
|
-
this.checkPromise = null;
|
|
451
615
|
|
|
452
|
-
//
|
|
616
|
+
// The request may outlive the current transport command instance.
|
|
453
617
|
this.device?.commands?.checkDisposed();
|
|
454
618
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
619
|
+
// auto go to bootloader mode
|
|
620
|
+
try {
|
|
621
|
+
this.postTipMessage('AutoRebootToBootloader');
|
|
622
|
+
const bootRes = await commands.typedCall('DeviceBackToBoot', 'Success');
|
|
623
|
+
// @ts-expect-error
|
|
624
|
+
if (bootRes.type === 'CallMethodError') {
|
|
625
|
+
throw ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateAutoEnterBootFailure);
|
|
626
|
+
}
|
|
627
|
+
this.postTipMessage('GoToBootloaderSuccess');
|
|
628
|
+
this.checkDeviceToBootloader(this.payload.connectId);
|
|
629
|
+
|
|
630
|
+
// force clean classic device cache so that the device can initialize again
|
|
631
|
+
if (DeviceModelToTypes.model_classic.includes(deviceType)) {
|
|
632
|
+
DevicePool.clearDeviceCache(serialNo);
|
|
633
|
+
}
|
|
634
|
+
delete DevicePool.devicesCache[''];
|
|
635
|
+
await this.checkPromise?.promise;
|
|
636
|
+
this.checkPromise = null;
|
|
637
|
+
|
|
638
|
+
// check if the device commands has been disposed
|
|
639
|
+
this.device?.commands?.checkDisposed();
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* Touch 1 with bootloader v2.5.0 issue: BLE chip need more time for looking up name, here change the delay time to 3000ms after rebooting.
|
|
643
|
+
*/
|
|
644
|
+
const isTouch = DeviceModelToTypes.model_touch.includes(deviceType);
|
|
645
|
+
await wait(isTouch ? 3000 : 1500);
|
|
646
|
+
} catch (e) {
|
|
647
|
+
if (e instanceof HardwareError) {
|
|
648
|
+
return Promise.reject(e);
|
|
649
|
+
}
|
|
650
|
+
console.log('auto go to bootloader mode failed: ', e);
|
|
651
|
+
return Promise.reject(
|
|
652
|
+
ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateAutoEnterBootFailure)
|
|
653
|
+
);
|
|
463
654
|
}
|
|
464
|
-
console.log('auto go to bootloader mode failed: ', e);
|
|
465
|
-
return Promise.reject(
|
|
466
|
-
ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateAutoEnterBootFailure)
|
|
467
|
-
);
|
|
468
655
|
}
|
|
469
|
-
}
|
|
470
656
|
|
|
471
|
-
|
|
472
|
-
|
|
657
|
+
// Devices already in bootloader mode still acquire through the same helper.
|
|
658
|
+
const source = await acquireFirmwareSource();
|
|
473
659
|
|
|
474
|
-
|
|
475
|
-
|
|
660
|
+
// check if the device commands has been disposed
|
|
661
|
+
this.device?.commands?.checkDisposed();
|
|
476
662
|
|
|
477
|
-
|
|
663
|
+
await this.device.acquire();
|
|
478
664
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
665
|
+
const response = await uploadFirmwareFromSource(
|
|
666
|
+
params.updateType,
|
|
667
|
+
this.device.getCommands().typedCall.bind(this.device.getCommands()),
|
|
668
|
+
this.postMessage,
|
|
669
|
+
device,
|
|
670
|
+
source,
|
|
671
|
+
true,
|
|
672
|
+
params.isUpdateBootloader
|
|
673
|
+
);
|
|
487
674
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
675
|
+
if (this.connectId) {
|
|
676
|
+
DevicePool.clearDeviceCache(this.connectId);
|
|
677
|
+
}
|
|
491
678
|
|
|
492
|
-
|
|
679
|
+
return response;
|
|
680
|
+
} finally {
|
|
681
|
+
await preparedSource?.close().catch(() => undefined);
|
|
682
|
+
}
|
|
493
683
|
}
|
|
494
684
|
}
|