@onekeyfe/hd-core 1.2.0-alpha.171 → 1.2.0-alpha.172
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__/firmware-update/firmware-update-v4-install-poll.test.ts +32 -3
- package/__tests__/pro2Wallpaper.test.ts +0 -66
- package/__tests__/protocol-v2.test.ts +50 -35
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +1 -2
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
- package/dist/index.d.ts +1 -4
- package/dist/index.js +25 -191
- package/dist/utils/pro2Wallpaper.d.ts +1 -3
- package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/FirmwareUpdateV4.ts +31 -35
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +2 -12
- package/src/utils/pro2Wallpaper.ts +1 -197
|
@@ -73,7 +73,7 @@ describe('FirmwareUpdateV4 install polling', () => {
|
|
|
73
73
|
);
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
-
test('writes the BLE Request and
|
|
76
|
+
test('writes the BLE Request and completes only from target status polling', async () => {
|
|
77
77
|
const method = new FirmwareUpdateV4({
|
|
78
78
|
id: 1,
|
|
79
79
|
payload: {
|
|
@@ -85,7 +85,30 @@ describe('FirmwareUpdateV4 install polling', () => {
|
|
|
85
85
|
const typedCall = jest
|
|
86
86
|
.fn()
|
|
87
87
|
.mockResolvedValueOnce({ type: 'Success', message: {} })
|
|
88
|
-
.mockResolvedValueOnce({
|
|
88
|
+
.mockResolvedValueOnce({
|
|
89
|
+
type: 'DeviceFirmwareUpdateStatus',
|
|
90
|
+
message: {
|
|
91
|
+
records: [
|
|
92
|
+
{
|
|
93
|
+
target_id: 6,
|
|
94
|
+
status: 'FW_MGMT_UPDATER_TASK_STATUS_IN_PROGRESS',
|
|
95
|
+
path: 'vol0:/coprocessor.bin',
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
})
|
|
100
|
+
.mockResolvedValueOnce({
|
|
101
|
+
type: 'DeviceFirmwareUpdateStatus',
|
|
102
|
+
message: {
|
|
103
|
+
records: [
|
|
104
|
+
{
|
|
105
|
+
target_id: 6,
|
|
106
|
+
status: 'FW_MGMT_UPDATER_TASK_STATUS_FINISHED',
|
|
107
|
+
path: 'vol0:/coprocessor.bin',
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
});
|
|
89
112
|
const call = jest.fn().mockResolvedValue({
|
|
90
113
|
type: 'WriteCompleted',
|
|
91
114
|
message: {},
|
|
@@ -96,6 +119,7 @@ describe('FirmwareUpdateV4 install polling', () => {
|
|
|
96
119
|
createProtocolV2UiPhaseMetadata: jest.fn().mockReturnValue(undefined),
|
|
97
120
|
toMessageObject: jest.fn().mockReturnValue({ connectId: 'pro2-ble' }),
|
|
98
121
|
setCancelableAction: jest.fn(),
|
|
122
|
+
clearCancelableAction: jest.fn(),
|
|
99
123
|
} as unknown as Device;
|
|
100
124
|
method.postMessage = jest.fn();
|
|
101
125
|
method.postProgressMessage = jest.fn();
|
|
@@ -116,13 +140,18 @@ describe('FirmwareUpdateV4 install polling', () => {
|
|
|
116
140
|
expect(call).toHaveBeenCalledWith(
|
|
117
141
|
'DeviceFirmwareUpdateRequest',
|
|
118
142
|
{},
|
|
119
|
-
{
|
|
143
|
+
expect.objectContaining({
|
|
144
|
+
returnAfterWrite: true,
|
|
145
|
+
expectedTypes: ['Success'],
|
|
146
|
+
onResponseAfterWrite: expect.any(Function),
|
|
147
|
+
})
|
|
120
148
|
);
|
|
121
149
|
expect(method.postProgressMessage).not.toHaveBeenCalled();
|
|
122
150
|
|
|
123
151
|
await firmwareUpdate.waitForProtocolV2FirmwareUpdateComplete(targets, true);
|
|
124
152
|
|
|
125
153
|
expect(typedCall.mock.calls[1]?.[0]).toBe('DeviceFirmwareUpdateStatusGet');
|
|
154
|
+
expect(typedCall.mock.calls[1]?.[1]).toBe('DeviceFirmwareUpdateStatus');
|
|
126
155
|
expect(method.postProgressMessage).toHaveBeenCalledWith(100, 'installingFirmware');
|
|
127
156
|
});
|
|
128
157
|
|
|
@@ -1,48 +1,5 @@
|
|
|
1
1
|
import { encodePro2Wallpaper } from '../src/utils/pro2Wallpaper';
|
|
2
2
|
|
|
3
|
-
// The test decoder mirrors LZ4's bit-packed token and offset format.
|
|
4
|
-
/* eslint-disable no-bitwise */
|
|
5
|
-
|
|
6
|
-
function decodeLz4Block(data: Uint8Array, expectedLength: number) {
|
|
7
|
-
const output = new Uint8Array(expectedLength);
|
|
8
|
-
let inputOffset = 0;
|
|
9
|
-
let outputOffset = 0;
|
|
10
|
-
|
|
11
|
-
const readLength = (initialLength: number) => {
|
|
12
|
-
let length = initialLength;
|
|
13
|
-
if (length === 0x0f) {
|
|
14
|
-
let extension = 0xff;
|
|
15
|
-
while (extension === 0xff) {
|
|
16
|
-
extension = data[inputOffset];
|
|
17
|
-
inputOffset += 1;
|
|
18
|
-
length += extension;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
return length;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
while (inputOffset < data.byteLength) {
|
|
25
|
-
const token = data[inputOffset];
|
|
26
|
-
inputOffset += 1;
|
|
27
|
-
const literalLength = readLength(token >> 4);
|
|
28
|
-
output.set(data.subarray(inputOffset, inputOffset + literalLength), outputOffset);
|
|
29
|
-
inputOffset += literalLength;
|
|
30
|
-
outputOffset += literalLength;
|
|
31
|
-
if (inputOffset >= data.byteLength) break;
|
|
32
|
-
|
|
33
|
-
const matchOffset = data[inputOffset] | (data[inputOffset + 1] << 8);
|
|
34
|
-
inputOffset += 2;
|
|
35
|
-
const matchLength = readLength(token & 0x0f) + 4;
|
|
36
|
-
for (let index = 0; index < matchLength; index += 1) {
|
|
37
|
-
output[outputOffset] = output[outputOffset - matchOffset];
|
|
38
|
-
outputOffset += 1;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
expect(outputOffset).toBe(expectedLength);
|
|
43
|
-
return output;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
3
|
describe('encodePro2Wallpaper', () => {
|
|
47
4
|
test('encodes opaque pixels as aligned LVGL v9 RGB565 data', () => {
|
|
48
5
|
const result = encodePro2Wallpaper({
|
|
@@ -71,29 +28,6 @@ describe('encodePro2Wallpaper', () => {
|
|
|
71
28
|
expect(Array.from(result.data.slice(12))).toEqual([0x1f, 0x00, 0xff, 0xff, 128, 255]);
|
|
72
29
|
});
|
|
73
30
|
|
|
74
|
-
test('encodes an I8 palette and pixel indices as an LVGL LZ4 block', () => {
|
|
75
|
-
const result = encodePro2Wallpaper({
|
|
76
|
-
width: 2,
|
|
77
|
-
height: 1,
|
|
78
|
-
rgba: new Uint8Array([255, 0, 0, 255, 0, 255, 0, 255]),
|
|
79
|
-
encoding: 'i8-lz4',
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
expect(result.colorFormat).toBe('I8');
|
|
83
|
-
expect(Array.from(result.data.slice(0, 12))).toEqual([
|
|
84
|
-
0x19, 0x0a, 0x08, 0, 2, 0, 1, 0, 2, 0, 0, 0,
|
|
85
|
-
]);
|
|
86
|
-
const view = new DataView(result.data.buffer, result.data.byteOffset, result.data.byteLength);
|
|
87
|
-
expect(view.getUint32(12, true)).toBe(2);
|
|
88
|
-
expect(view.getUint32(16, true)).toBe(result.data.byteLength - 24);
|
|
89
|
-
expect(view.getUint32(20, true)).toBe(1026);
|
|
90
|
-
|
|
91
|
-
const rawData = decodeLz4Block(result.data.slice(24), 1026);
|
|
92
|
-
expect(Array.from(rawData.slice(210 * 4, 210 * 4 + 4))).toEqual([0, 0, 255, 255]);
|
|
93
|
-
expect(Array.from(rawData.slice(36 * 4, 36 * 4 + 4))).toEqual([0, 255, 0, 255]);
|
|
94
|
-
expect(Array.from(rawData.slice(-2))).toEqual([210, 36]);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
31
|
test('rejects invalid dimensions and RGBA byte length', () => {
|
|
98
32
|
expect(() => encodePro2Wallpaper({ width: 0, height: 1, rgba: new Uint8Array() })).toThrow(
|
|
99
33
|
'width'
|
|
@@ -194,13 +194,7 @@ describe('DeviceUploadWallpaper', () => {
|
|
|
194
194
|
refreshProtocolV2SettingsAfterMutation: jest.fn().mockResolvedValue({}),
|
|
195
195
|
});
|
|
196
196
|
|
|
197
|
-
|
|
198
|
-
jest.restoreAllMocks();
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
test('uses I8 with LZ4 when uploading a Pro2 wallpaper over BLE', async () => {
|
|
202
|
-
jest.spyOn(DataManager, 'getSettings').mockReturnValue('lowlevel');
|
|
203
|
-
jest.spyOn(DataManager, 'isBleConnect').mockReturnValue(true);
|
|
197
|
+
test('encodes, uploads and applies a Pro2 wallpaper', async () => {
|
|
204
198
|
const typedCall = jest.fn().mockImplementation((request, _response, params) => {
|
|
205
199
|
if (request === 'FilesystemDirMake') return { message: { message: 'directory ready' } };
|
|
206
200
|
if (request === 'FilesystemFileWrite') {
|
|
@@ -243,7 +237,7 @@ describe('DeviceUploadWallpaper', () => {
|
|
|
243
237
|
});
|
|
244
238
|
expect(device.refreshProtocolV2SettingsAfterMutation).toHaveBeenCalledTimes(1);
|
|
245
239
|
expect(typedCall.mock.calls.some(call => call[0] === 'SetWallpaper')).toBe(false);
|
|
246
|
-
expect(result).toMatchObject({ colorFormat: '
|
|
240
|
+
expect(result).toMatchObject({ colorFormat: 'RGB565', message: 'wallpaper applied' });
|
|
247
241
|
const fileWriteCallCount = typedCall.mock.calls.filter(
|
|
248
242
|
call => call[0] === 'FilesystemFileWrite'
|
|
249
243
|
).length;
|
|
@@ -281,8 +275,6 @@ describe('DeviceUploadWallpaper', () => {
|
|
|
281
275
|
});
|
|
282
276
|
|
|
283
277
|
test('returns success when wallpaper read-back fails after apply', async () => {
|
|
284
|
-
jest.spyOn(DataManager, 'getSettings').mockReturnValue('desktop-webusb');
|
|
285
|
-
jest.spyOn(DataManager, 'isBleConnect').mockReturnValue(false);
|
|
286
278
|
const typedCall = jest.fn().mockImplementation((request, _response, params) => {
|
|
287
279
|
if (request === 'FilesystemDirMake') return { message: {} };
|
|
288
280
|
if (request === 'FilesystemFileWrite') {
|
|
@@ -308,10 +300,7 @@ describe('DeviceUploadWallpaper', () => {
|
|
|
308
300
|
(method as any).device = device;
|
|
309
301
|
method.init();
|
|
310
302
|
|
|
311
|
-
await expect(method.run()).resolves.toMatchObject({
|
|
312
|
-
colorFormat: 'RGB565',
|
|
313
|
-
message: 'wallpaper applied',
|
|
314
|
-
});
|
|
303
|
+
await expect(method.run()).resolves.toMatchObject({ message: 'wallpaper applied' });
|
|
315
304
|
expect(device.refreshProtocolV2SettingsAfterMutation).toHaveBeenCalledTimes(1);
|
|
316
305
|
});
|
|
317
306
|
|
|
@@ -328,19 +317,6 @@ describe('DeviceUploadWallpaper', () => {
|
|
|
328
317
|
expect(() => method.init()).toThrow('fileName');
|
|
329
318
|
});
|
|
330
319
|
|
|
331
|
-
test('rejects unsupported wallpaper encodings before device communication', () => {
|
|
332
|
-
const method = new DeviceUploadWallpaper({
|
|
333
|
-
id: 1,
|
|
334
|
-
payload: {
|
|
335
|
-
method: 'deviceUploadWallpaper',
|
|
336
|
-
jpegBase64: createJpegBase64(604, 1024),
|
|
337
|
-
encoding: 'gzip',
|
|
338
|
-
} as any,
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
expect(() => method.init()).toThrow('encoding');
|
|
342
|
-
});
|
|
343
|
-
|
|
344
320
|
test('rejects unsupported firmware before creating or writing files', async () => {
|
|
345
321
|
const typedCall = jest.fn();
|
|
346
322
|
const method = new DeviceUploadWallpaper({
|
|
@@ -4978,7 +4954,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
4978
4954
|
expect(commands.mainId).toBe('usb-path');
|
|
4979
4955
|
});
|
|
4980
4956
|
|
|
4981
|
-
test('
|
|
4957
|
+
test('reacquires the same BLE peripheral by id without scanning during install recovery', async () => {
|
|
4982
4958
|
const method = new FirmwareUpdateV4({
|
|
4983
4959
|
id: 1,
|
|
4984
4960
|
payload: {
|
|
@@ -5000,7 +4976,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5000
4976
|
|
|
5001
4977
|
await (method as any).reconnectProtocolV2Device({ skipProtocolProbe: true });
|
|
5002
4978
|
|
|
5003
|
-
expect(enumerate).
|
|
4979
|
+
expect(enumerate).not.toHaveBeenCalled();
|
|
5004
4980
|
expect(acquire).toHaveBeenCalledWith('ble-id', null, true, 'V2', undefined, undefined, true);
|
|
5005
4981
|
expect(commands.disposed).toBe(false);
|
|
5006
4982
|
expect(commands.mainId).toBe('ble-id');
|
|
@@ -5571,7 +5547,11 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5571
5547
|
expect(call).toHaveBeenCalledWith(
|
|
5572
5548
|
'DeviceFirmwareUpdateRequest',
|
|
5573
5549
|
{},
|
|
5574
|
-
{
|
|
5550
|
+
expect.objectContaining({
|
|
5551
|
+
returnAfterWrite: true,
|
|
5552
|
+
expectedTypes: ['Success'],
|
|
5553
|
+
onResponseAfterWrite: expect.any(Function),
|
|
5554
|
+
})
|
|
5575
5555
|
);
|
|
5576
5556
|
expect(typedCall).not.toHaveBeenCalledWith('DeviceFirmwareUpdateRequest', 'Success', {});
|
|
5577
5557
|
expect((method as any).protocolV2InstallNeedsBleReconnect).toBe(true);
|
|
@@ -5679,7 +5659,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5679
5659
|
expect(method.postProgressMessage).toHaveBeenCalledWith(100, 'installingFirmware');
|
|
5680
5660
|
});
|
|
5681
5661
|
|
|
5682
|
-
test('keeps polling after
|
|
5662
|
+
test('keeps polling after an empty status response until the target finishes', async () => {
|
|
5683
5663
|
const method = new FirmwareUpdateV4({
|
|
5684
5664
|
id: 1,
|
|
5685
5665
|
payload: {
|
|
@@ -5688,7 +5668,10 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5688
5668
|
});
|
|
5689
5669
|
const typedCall = jest
|
|
5690
5670
|
.fn()
|
|
5691
|
-
.mockResolvedValueOnce({
|
|
5671
|
+
.mockResolvedValueOnce({
|
|
5672
|
+
type: 'DeviceFirmwareUpdateStatus',
|
|
5673
|
+
message: { records: [] },
|
|
5674
|
+
})
|
|
5692
5675
|
.mockResolvedValueOnce({
|
|
5693
5676
|
type: 'DeviceFirmwareUpdateStatus',
|
|
5694
5677
|
message: { records: [] },
|
|
@@ -5830,6 +5813,38 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5830
5813
|
expect(method.postProgressMessage).toHaveBeenCalledWith(100, 'installingFirmware');
|
|
5831
5814
|
});
|
|
5832
5815
|
|
|
5816
|
+
test('does not count a stale finished target when only another target was live', () => {
|
|
5817
|
+
const method = new FirmwareUpdateV4({
|
|
5818
|
+
id: 1,
|
|
5819
|
+
payload: {
|
|
5820
|
+
method: 'firmwareUpdateV4',
|
|
5821
|
+
},
|
|
5822
|
+
});
|
|
5823
|
+
const assertProtocolV2TargetStatus = (method as any).assertProtocolV2TargetStatus.bind(method);
|
|
5824
|
+
const expectedTargetIds = new Set([3, 4]);
|
|
5825
|
+
const expectedPaths = new Map([
|
|
5826
|
+
[3, 'vol0:/bootloader.bin'],
|
|
5827
|
+
[4, 'vol0:/application_p1.bin'],
|
|
5828
|
+
]);
|
|
5829
|
+
const liveTargetIds = new Set([4]);
|
|
5830
|
+
method.postProgressMessage = jest.fn();
|
|
5831
|
+
|
|
5832
|
+
const completed = assertProtocolV2TargetStatus(
|
|
5833
|
+
[
|
|
5834
|
+
{ target_id: 3, status: 2, path: 'vol0:/bootloader.bin' },
|
|
5835
|
+
{ target_id: 4, status: 2, path: 'vol0:/application_p1.bin' },
|
|
5836
|
+
],
|
|
5837
|
+
expectedTargetIds,
|
|
5838
|
+
expectedPaths,
|
|
5839
|
+
liveTargetIds
|
|
5840
|
+
);
|
|
5841
|
+
|
|
5842
|
+
expect(completed).toBe(false);
|
|
5843
|
+
expect((method as any).protocolV2CompletedTargetIds).toEqual(new Set([4]));
|
|
5844
|
+
expect(method.postProgressMessage).toHaveBeenCalledWith(50, 'installingFirmware');
|
|
5845
|
+
expect(method.postProgressMessage).not.toHaveBeenCalledWith(100, 'installingFirmware');
|
|
5846
|
+
});
|
|
5847
|
+
|
|
5833
5848
|
test('ignores stale failed records until the current install starts', async () => {
|
|
5834
5849
|
const method = new FirmwareUpdateV4({
|
|
5835
5850
|
id: 1,
|
|
@@ -6119,7 +6134,6 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6119
6134
|
});
|
|
6120
6135
|
const typedCall = jest
|
|
6121
6136
|
.fn()
|
|
6122
|
-
.mockResolvedValueOnce({ type: 'Success', message: {} })
|
|
6123
6137
|
.mockRejectedValueOnce(new Error('Pro2 is rebooting'))
|
|
6124
6138
|
.mockResolvedValueOnce({
|
|
6125
6139
|
type: 'DeviceFirmwareUpdateStatus',
|
|
@@ -6136,6 +6150,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6136
6150
|
(method as any).device = stubDevice({
|
|
6137
6151
|
getCommands: () => ({ typedCall }),
|
|
6138
6152
|
});
|
|
6153
|
+
(method as any).protocolV2InstallRequestConfirmed = true;
|
|
6139
6154
|
(method as any).reconnectProtocolV2Device = jest.fn().mockResolvedValue(undefined);
|
|
6140
6155
|
(method as any).verifyProtocolV2ReconnectIdentity = jest.fn().mockResolvedValue(deviceInfo);
|
|
6141
6156
|
(method as any).probeProtocolV2NormalMode = jest.fn().mockResolvedValue(true);
|
|
@@ -6566,7 +6581,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6566
6581
|
expect(reconnectProtocolV2Device).not.toHaveBeenCalled();
|
|
6567
6582
|
expect(typedCall).toHaveBeenCalledWith(
|
|
6568
6583
|
'DeviceFirmwareUpdateStatusGet',
|
|
6569
|
-
|
|
6584
|
+
'DeviceFirmwareUpdateStatus',
|
|
6570
6585
|
expect.anything(),
|
|
6571
6586
|
expect.anything()
|
|
6572
6587
|
);
|
|
@@ -6848,7 +6863,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6848
6863
|
});
|
|
6849
6864
|
expect(typedCall).toHaveBeenCalledWith(
|
|
6850
6865
|
'DeviceFirmwareUpdateStatusGet',
|
|
6851
|
-
|
|
6866
|
+
'DeviceFirmwareUpdateStatus',
|
|
6852
6867
|
{
|
|
6853
6868
|
fields: {
|
|
6854
6869
|
status: true,
|
|
@@ -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;AA0BlG,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AA+B/E,OAAO,KAAK,EAEV,sBAAsB,EAEvB,MAAM,6BAA6B,CAAC;AAoErC,wBAAgB,wCAAwC,CACtD,UAAU,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,EAC5C,MAAM,EAAE,sBAAsB,EAC9B,0BAA0B,UAAQ,QAiCnC;AAuSD,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,4BAA4B,CAAqB;IAEzD,OAAO,CAAC,6BAA6B,CAAC,CAAW;IAEjD,OAAO,CAAC,+BAA+B,CAAC,CAAuB;IAE/D,OAAO,CAAC,iCAAiC,CAA6B;IAEtE,OAAO,CAAC,kCAAkC,CAAS;IAEnD,OAAO,CAAC,iCAAiC,CAAS;IAElD,OAAO,CAAC,kCAAkC,CAAC,CAAW;IAEtD,OAAO,CAAC,8BAA8B,CAAC,CAAS;IAEhD,OAAO,CAAC,gCAAgC,CAAK;IAE7C,IAAI;IA6LJ,OAAO,CAAC,8BAA8B;IAwBhC,GAAG;;;;;YAKK,aAAa;YA0Ib,4BAA4B;YAkB5B,0BAA0B;YAY1B,8BAA8B;YAK9B,+BAA+B;YAqG/B,4BAA4B;YA+C5B,0CAA0C;YAkB1C,qCAAqC;YAoFrC,gCAAgC;YAgBhC,uCAAuC;YAmDvC,8BAA8B;IA8B5C,OAAO,CAAC,8BAA8B;IA0BtC,OAAO,CAAC,kCAAkC;IAc1C,OAAO,CAAC,gCAAgC;YAuD1B,2BAA2B;IAmBzC,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;IAmF7C,OAAO,CAAC,6BAA6B;IAMrC,OAAO,CAAC,gCAAgC;YAM1B,8BAA8B;YAmD9B,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;YAwE9B,6BAA6B;IA8E3C,OAAO,CAAC,mCAAmC;YAI7B,0BAA0B;IAaxC,OAAO,CAAC,8BAA8B;IAiBtC,OAAO,CAAC,4BAA4B;
|
|
1
|
+
{"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkD,MAAM,qBAAqB,CAAC;AA0BlG,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AA+B/E,OAAO,KAAK,EAEV,sBAAsB,EAEvB,MAAM,6BAA6B,CAAC;AAoErC,wBAAgB,wCAAwC,CACtD,UAAU,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,EAC5C,MAAM,EAAE,sBAAsB,EAC9B,0BAA0B,UAAQ,QAiCnC;AAuSD,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,4BAA4B,CAAqB;IAEzD,OAAO,CAAC,6BAA6B,CAAC,CAAW;IAEjD,OAAO,CAAC,+BAA+B,CAAC,CAAuB;IAE/D,OAAO,CAAC,iCAAiC,CAA6B;IAEtE,OAAO,CAAC,kCAAkC,CAAS;IAEnD,OAAO,CAAC,iCAAiC,CAAS;IAElD,OAAO,CAAC,kCAAkC,CAAC,CAAW;IAEtD,OAAO,CAAC,8BAA8B,CAAC,CAAS;IAEhD,OAAO,CAAC,gCAAgC,CAAK;IAE7C,IAAI;IA6LJ,OAAO,CAAC,8BAA8B;IAwBhC,GAAG;;;;;YAKK,aAAa;YA0Ib,4BAA4B;YAkB5B,0BAA0B;YAY1B,8BAA8B;YAK9B,+BAA+B;YAqG/B,4BAA4B;YA+C5B,0CAA0C;YAkB1C,qCAAqC;YAoFrC,gCAAgC;YAgBhC,uCAAuC;YAmDvC,8BAA8B;IA8B5C,OAAO,CAAC,8BAA8B;IA0BtC,OAAO,CAAC,kCAAkC;IAc1C,OAAO,CAAC,gCAAgC;YAuD1B,2BAA2B;IAmBzC,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;IAmF7C,OAAO,CAAC,6BAA6B;IAMrC,OAAO,CAAC,gCAAgC;YAM1B,8BAA8B;YAmD9B,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;YAwE9B,6BAA6B;IA8E3C,OAAO,CAAC,mCAAmC;YAI7B,0BAA0B;IAaxC,OAAO,CAAC,8BAA8B;IAiBtC,OAAO,CAAC,4BAA4B;IA6IpC,OAAO,CAAC,6BAA6B;IAcrC,OAAO,CAAC,qCAAqC;IAyB7C,OAAO,CAAC,kCAAkC;IAgB1C,OAAO,CAAC,8CAA8C;YAIxC,uCAAuC;YA2NvC,gCAAgC;YAehC,yBAAyB;IASvC,OAAO,CAAC,2BAA2B;YAMrB,8BAA8B;IAQ5C,OAAO,CAAC,0BAA0B;YAkBpB,mCAAmC;YAWnC,qCAAqC;YAmDrC,yBAAyB;YAgGzB,8BAA8B;IAU5C,OAAO,CAAC,kCAAkC;YAQ5B,cAAc;YAuCd,6BAA6B;YAW7B,0BAA0B;YAoB1B,6BAA6B;YA4E7B,gBAAgB;IAiB9B,OAAO,CAAC,qBAAqB;CAM9B"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { BaseMethod } from '../BaseMethod';
|
|
2
|
-
import { type Pro2WallpaperColorFormat
|
|
2
|
+
import { type Pro2WallpaperColorFormat } from '../../utils/pro2Wallpaper';
|
|
3
3
|
export type DeviceUploadWallpaperParams = {
|
|
4
4
|
jpegBase64: string;
|
|
5
5
|
fileName?: string;
|
|
6
6
|
chunkSize?: number;
|
|
7
|
-
encoding?: Pro2WallpaperEncoding;
|
|
8
7
|
};
|
|
9
8
|
export type DeviceUploadWallpaperResponse = {
|
|
10
9
|
path: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeviceUploadWallpaper.d.ts","sourceRoot":"","sources":["../../../src/api/protocol-v2/DeviceUploadWallpaper.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"DeviceUploadWallpaper.d.ts","sourceRoot":"","sources":["../../../src/api/protocol-v2/DeviceUploadWallpaper.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAO3C,OAAO,EAGL,KAAK,wBAAwB,EAE9B,MAAM,2BAA2B,CAAC;AAEnC,MAAM,MAAM,2BAA2B,GAAG;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,wBAAwB,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAmBF,MAAM,CAAC,OAAO,OAAO,qBAAsB,SAAQ,UAAU,CAAC,2BAA2B,CAAC;IACxF,qBAAqB;IAIrB,OAAO,CAAC,OAAO,CAAC,CAA8D;IAE9E,OAAO,CAAC,cAAc,CAAS;IAE/B,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,IAAI,CAAM;IAElB,IAAI;YA2BU,kBAAkB;YAgBlB,eAAe;YAaf,MAAM;IAwBd,GAAG,IAAI,OAAO,CAAC,6BAA6B,CAAC;CAyBpD"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1113,13 +1113,11 @@ declare const switchTransport: ({ env, Transport, plugin, }: {
|
|
|
1113
1113
|
|
|
1114
1114
|
declare const PRO2_WALLPAPER_WIDTH = 604;
|
|
1115
1115
|
declare const PRO2_WALLPAPER_HEIGHT = 1024;
|
|
1116
|
-
type Pro2WallpaperColorFormat = 'RGB565' | 'RGB565A8'
|
|
1117
|
-
type Pro2WallpaperEncoding = 'rgb565' | 'i8-lz4';
|
|
1116
|
+
type Pro2WallpaperColorFormat = 'RGB565' | 'RGB565A8';
|
|
1118
1117
|
declare function encodePro2Wallpaper(options: {
|
|
1119
1118
|
width: number;
|
|
1120
1119
|
height: number;
|
|
1121
1120
|
rgba: Uint8Array | ArrayBuffer;
|
|
1122
|
-
encoding?: Pro2WallpaperEncoding;
|
|
1123
1121
|
}): {
|
|
1124
1122
|
data: Uint8Array;
|
|
1125
1123
|
colorFormat: Pro2WallpaperColorFormat;
|
|
@@ -1129,7 +1127,6 @@ type DeviceUploadWallpaperParams = {
|
|
|
1129
1127
|
jpegBase64: string;
|
|
1130
1128
|
fileName?: string;
|
|
1131
1129
|
chunkSize?: number;
|
|
1132
|
-
encoding?: Pro2WallpaperEncoding;
|
|
1133
1130
|
};
|
|
1134
1131
|
type DeviceUploadWallpaperResponse = {
|
|
1135
1132
|
path: string;
|
package/dist/index.js
CHANGED
|
@@ -42476,18 +42476,6 @@ const PRO2_WALLPAPER_WIDTH = 604;
|
|
|
42476
42476
|
const PRO2_WALLPAPER_HEIGHT = 1024;
|
|
42477
42477
|
const COLOR_FORMAT_RGB565 = 0x12;
|
|
42478
42478
|
const COLOR_FORMAT_RGB565A8 = 0x14;
|
|
42479
|
-
const COLOR_FORMAT_I8 = 0x0a;
|
|
42480
|
-
const IMAGE_FLAG_COMPRESSED = 0x0008;
|
|
42481
|
-
const IMAGE_COMPRESSION_LZ4 = 0x00000002;
|
|
42482
|
-
const I8_PALETTE_SIZE = 256 * 4;
|
|
42483
|
-
const I8_RED_LEVELS = 6;
|
|
42484
|
-
const I8_GREEN_LEVELS = 7;
|
|
42485
|
-
const I8_BLUE_LEVELS = 6;
|
|
42486
|
-
const LZ4_MIN_MATCH = 4;
|
|
42487
|
-
const LZ4_LAST_LITERALS = 5;
|
|
42488
|
-
const LZ4_MATCH_FIND_LIMIT = 12;
|
|
42489
|
-
const LZ4_HASH_BITS = 16;
|
|
42490
|
-
const LZ4_HASH_MULTIPLIER = -1640531535;
|
|
42491
42479
|
const RED_THRESHOLD = [
|
|
42492
42480
|
1, 7, 3, 5, 0, 8, 2, 6, 7, 1, 5, 3, 8, 0, 6, 2, 3, 5, 0, 8, 2, 6, 1, 7, 5, 3, 8, 0, 6, 2, 7, 1, 0,
|
|
42493
42481
|
8, 2, 6, 1, 7, 3, 5, 8, 0, 6, 2, 7, 1, 5, 3, 2, 6, 1, 7, 3, 5, 0, 8, 6, 2, 7, 1, 5, 3, 8, 0,
|
|
@@ -42509,149 +42497,6 @@ function asBytes(rgba) {
|
|
|
42509
42497
|
function align(value, boundary) {
|
|
42510
42498
|
return Math.ceil(value / boundary) * boundary;
|
|
42511
42499
|
}
|
|
42512
|
-
function writeLz4Length(output, offset, length) {
|
|
42513
|
-
let cursor = offset;
|
|
42514
|
-
let remaining = length;
|
|
42515
|
-
while (remaining >= 0xff) {
|
|
42516
|
-
output[cursor] = 0xff;
|
|
42517
|
-
cursor += 1;
|
|
42518
|
-
remaining -= 0xff;
|
|
42519
|
-
}
|
|
42520
|
-
output[cursor] = remaining;
|
|
42521
|
-
return cursor + 1;
|
|
42522
|
-
}
|
|
42523
|
-
function readUint32LittleEndian(data, offset) {
|
|
42524
|
-
return (data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24));
|
|
42525
|
-
}
|
|
42526
|
-
function getLz4Hash(sequence) {
|
|
42527
|
-
return (Math.imul(sequence, LZ4_HASH_MULTIPLIER) >>> (32 - LZ4_HASH_BITS)) & 0xffff;
|
|
42528
|
-
}
|
|
42529
|
-
function compressLz4Block(input) {
|
|
42530
|
-
const output = new Uint8Array(input.byteLength + Math.floor(input.byteLength / 0xff) + 16);
|
|
42531
|
-
const hashTable = new Int32Array(1 << LZ4_HASH_BITS);
|
|
42532
|
-
hashTable.fill(-1);
|
|
42533
|
-
let anchor = 0;
|
|
42534
|
-
let inputOffset = 0;
|
|
42535
|
-
let outputOffset = 0;
|
|
42536
|
-
const matchFindEnd = input.byteLength - LZ4_MATCH_FIND_LIMIT;
|
|
42537
|
-
const matchCopyEnd = input.byteLength - LZ4_LAST_LITERALS;
|
|
42538
|
-
while (inputOffset <= matchFindEnd) {
|
|
42539
|
-
const sequence = readUint32LittleEndian(input, inputOffset);
|
|
42540
|
-
const hash = getLz4Hash(sequence);
|
|
42541
|
-
const reference = hashTable[hash];
|
|
42542
|
-
hashTable[hash] = inputOffset;
|
|
42543
|
-
const matchOffset = inputOffset - reference;
|
|
42544
|
-
const hasMatch = reference >= 0 &&
|
|
42545
|
-
matchOffset <= 0xffff &&
|
|
42546
|
-
readUint32LittleEndian(input, reference) === sequence;
|
|
42547
|
-
if (hasMatch) {
|
|
42548
|
-
let matchLength = LZ4_MIN_MATCH;
|
|
42549
|
-
while (inputOffset + matchLength < matchCopyEnd &&
|
|
42550
|
-
input[reference + matchLength] === input[inputOffset + matchLength]) {
|
|
42551
|
-
matchLength += 1;
|
|
42552
|
-
}
|
|
42553
|
-
const literalLength = inputOffset - anchor;
|
|
42554
|
-
const encodedMatchLength = matchLength - LZ4_MIN_MATCH;
|
|
42555
|
-
const tokenOffset = outputOffset;
|
|
42556
|
-
outputOffset += 1;
|
|
42557
|
-
output[tokenOffset] =
|
|
42558
|
-
(Math.min(literalLength, 0x0f) << 4) | Math.min(encodedMatchLength, 0x0f);
|
|
42559
|
-
if (literalLength >= 0x0f) {
|
|
42560
|
-
outputOffset = writeLz4Length(output, outputOffset, literalLength - 0x0f);
|
|
42561
|
-
}
|
|
42562
|
-
output.set(input.subarray(anchor, inputOffset), outputOffset);
|
|
42563
|
-
outputOffset += literalLength;
|
|
42564
|
-
output[outputOffset] = matchOffset & 0xff;
|
|
42565
|
-
output[outputOffset + 1] = matchOffset >> 8;
|
|
42566
|
-
outputOffset += 2;
|
|
42567
|
-
if (encodedMatchLength >= 0x0f) {
|
|
42568
|
-
outputOffset = writeLz4Length(output, outputOffset, encodedMatchLength - 0x0f);
|
|
42569
|
-
}
|
|
42570
|
-
const matchStart = inputOffset;
|
|
42571
|
-
inputOffset += matchLength;
|
|
42572
|
-
anchor = inputOffset;
|
|
42573
|
-
for (let cursor = Math.max(matchStart + 1, inputOffset - 2); cursor < inputOffset; cursor += 1) {
|
|
42574
|
-
if (cursor <= matchFindEnd) {
|
|
42575
|
-
hashTable[getLz4Hash(readUint32LittleEndian(input, cursor))] = cursor;
|
|
42576
|
-
}
|
|
42577
|
-
}
|
|
42578
|
-
}
|
|
42579
|
-
else {
|
|
42580
|
-
inputOffset += 1;
|
|
42581
|
-
}
|
|
42582
|
-
}
|
|
42583
|
-
const literalLength = input.byteLength - anchor;
|
|
42584
|
-
const tokenOffset = outputOffset;
|
|
42585
|
-
outputOffset += 1;
|
|
42586
|
-
output[tokenOffset] = Math.min(literalLength, 0x0f) << 4;
|
|
42587
|
-
if (literalLength >= 0x0f) {
|
|
42588
|
-
outputOffset = writeLz4Length(output, outputOffset, literalLength - 0x0f);
|
|
42589
|
-
}
|
|
42590
|
-
output.set(input.subarray(anchor), outputOffset);
|
|
42591
|
-
outputOffset += literalLength;
|
|
42592
|
-
return output.slice(0, outputOffset);
|
|
42593
|
-
}
|
|
42594
|
-
function quantizeChannel(value, levels) {
|
|
42595
|
-
return Math.floor((value * (levels - 1) + 0x7f) / 0xff);
|
|
42596
|
-
}
|
|
42597
|
-
function expandChannel(value, levels) {
|
|
42598
|
-
return Math.floor((value * 0xff + Math.floor((levels - 1) / 2)) / (levels - 1));
|
|
42599
|
-
}
|
|
42600
|
-
function encodePro2I8Lz4(options) {
|
|
42601
|
-
const { width, height } = options;
|
|
42602
|
-
if (!Number.isInteger(width) || width <= 0 || width > 0xffff) {
|
|
42603
|
-
throw invalidParameter$2('Wallpaper width must be an integer between 1 and 65535.');
|
|
42604
|
-
}
|
|
42605
|
-
if (!Number.isInteger(height) || height <= 0 || height > 0xffff) {
|
|
42606
|
-
throw invalidParameter$2('Wallpaper height must be an integer between 1 and 65535.');
|
|
42607
|
-
}
|
|
42608
|
-
const rgba = asBytes(options.rgba);
|
|
42609
|
-
const expectedLength = width * height * 4;
|
|
42610
|
-
if (rgba.byteLength !== expectedLength) {
|
|
42611
|
-
throw invalidParameter$2(`Wallpaper RGBA data length must be ${expectedLength} bytes, received ${rgba.byteLength}.`);
|
|
42612
|
-
}
|
|
42613
|
-
const stride = width;
|
|
42614
|
-
const rawData = new Uint8Array(I8_PALETTE_SIZE + stride * height);
|
|
42615
|
-
for (let red = 0; red < I8_RED_LEVELS; red += 1) {
|
|
42616
|
-
for (let green = 0; green < I8_GREEN_LEVELS; green += 1) {
|
|
42617
|
-
for (let blue = 0; blue < I8_BLUE_LEVELS; blue += 1) {
|
|
42618
|
-
const paletteIndex = (red * I8_GREEN_LEVELS + green) * I8_BLUE_LEVELS + blue;
|
|
42619
|
-
const paletteOffset = paletteIndex * 4;
|
|
42620
|
-
rawData[paletteOffset] = expandChannel(blue, I8_BLUE_LEVELS);
|
|
42621
|
-
rawData[paletteOffset + 1] = expandChannel(green, I8_GREEN_LEVELS);
|
|
42622
|
-
rawData[paletteOffset + 2] = expandChannel(red, I8_RED_LEVELS);
|
|
42623
|
-
rawData[paletteOffset + 3] = 0xff;
|
|
42624
|
-
}
|
|
42625
|
-
}
|
|
42626
|
-
}
|
|
42627
|
-
for (let pixel = 0; pixel < width * height; pixel += 1) {
|
|
42628
|
-
const sourceOffset = pixel * 4;
|
|
42629
|
-
const alpha = rgba[sourceOffset + 3];
|
|
42630
|
-
const red = Math.round((rgba[sourceOffset] * alpha) / 0xff);
|
|
42631
|
-
const green = Math.round((rgba[sourceOffset + 1] * alpha) / 0xff);
|
|
42632
|
-
const blue = Math.round((rgba[sourceOffset + 2] * alpha) / 0xff);
|
|
42633
|
-
const paletteIndex = (quantizeChannel(red, I8_RED_LEVELS) * I8_GREEN_LEVELS +
|
|
42634
|
-
quantizeChannel(green, I8_GREEN_LEVELS)) *
|
|
42635
|
-
I8_BLUE_LEVELS +
|
|
42636
|
-
quantizeChannel(blue, I8_BLUE_LEVELS);
|
|
42637
|
-
rawData[I8_PALETTE_SIZE + pixel] = paletteIndex;
|
|
42638
|
-
}
|
|
42639
|
-
const compressed = compressLz4Block(rawData);
|
|
42640
|
-
const data = new Uint8Array(24 + compressed.byteLength);
|
|
42641
|
-
const view = new DataView(data.buffer);
|
|
42642
|
-
data[0] = 0x19;
|
|
42643
|
-
data[1] = COLOR_FORMAT_I8;
|
|
42644
|
-
view.setUint16(2, IMAGE_FLAG_COMPRESSED, true);
|
|
42645
|
-
view.setUint16(4, width, true);
|
|
42646
|
-
view.setUint16(6, height, true);
|
|
42647
|
-
view.setUint16(8, stride, true);
|
|
42648
|
-
view.setUint16(10, 0, true);
|
|
42649
|
-
view.setUint32(12, IMAGE_COMPRESSION_LZ4, true);
|
|
42650
|
-
view.setUint32(16, compressed.byteLength, true);
|
|
42651
|
-
view.setUint32(20, rawData.byteLength, true);
|
|
42652
|
-
data.set(compressed, 24);
|
|
42653
|
-
return { data, colorFormat: 'I8' };
|
|
42654
|
-
}
|
|
42655
42500
|
function encodePro2Image(options) {
|
|
42656
42501
|
var _a;
|
|
42657
42502
|
const { width, height } = options;
|
|
@@ -42719,9 +42564,6 @@ function encodePro2Image(options) {
|
|
|
42719
42564
|
return { data, colorFormat };
|
|
42720
42565
|
}
|
|
42721
42566
|
function encodePro2Wallpaper(options) {
|
|
42722
|
-
if (options.encoding === 'i8-lz4') {
|
|
42723
|
-
return encodePro2I8Lz4(options);
|
|
42724
|
-
}
|
|
42725
42567
|
return encodePro2Image(options);
|
|
42726
42568
|
}
|
|
42727
42569
|
|
|
@@ -53483,7 +53325,11 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53483
53325
|
}
|
|
53484
53326
|
seenTargetIds.add(targetId);
|
|
53485
53327
|
}
|
|
53486
|
-
const completedTargets = matchingTargets.filter(target =>
|
|
53328
|
+
const completedTargets = matchingTargets.filter(target => {
|
|
53329
|
+
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
53330
|
+
return (isProtocolV2TargetStatusFinished(target.status) &&
|
|
53331
|
+
(!liveTargetIds || (targetId !== undefined && liveTargetIds.has(targetId))));
|
|
53332
|
+
});
|
|
53487
53333
|
const completedTargetIds = new Set();
|
|
53488
53334
|
completedTargets.forEach(target => {
|
|
53489
53335
|
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
@@ -53592,26 +53438,17 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53592
53438
|
}
|
|
53593
53439
|
const currentDeviceInfo = deviceInfo;
|
|
53594
53440
|
try {
|
|
53595
|
-
const statusResponse = yield this.device.getCommands().typedCall('DeviceFirmwareUpdateStatusGet',
|
|
53441
|
+
const statusResponse = yield this.device.getCommands().typedCall('DeviceFirmwareUpdateStatusGet', 'DeviceFirmwareUpdateStatus', {
|
|
53596
53442
|
fields: {
|
|
53597
53443
|
status: true,
|
|
53598
53444
|
payload_version: true,
|
|
53599
53445
|
path: true,
|
|
53600
53446
|
},
|
|
53601
53447
|
}, { timeoutMs: PROTOCOL_V2_FIRMWARE_STATUS_RESPONSE_TIMEOUT });
|
|
53602
|
-
if (
|
|
53603
|
-
if (this.isBleReconnect()) {
|
|
53604
|
-
Log$7.log('[FirmwareUpdateV4] BLE firmware install completed by terminal Success response');
|
|
53605
|
-
this.recordProtocolV2AuthoritativeInstallCompletion(expectedTargetIds);
|
|
53606
|
-
this.postProgressMessage(100, 'installingFirmware');
|
|
53607
|
-
return;
|
|
53608
|
-
}
|
|
53448
|
+
if (this.protocolV2InstallRequestConfirmed) {
|
|
53609
53449
|
installEvidenceObserved = true;
|
|
53610
|
-
lastError = new Error('Protocol V2 firmware install acknowledged; waiting for target status');
|
|
53611
53450
|
}
|
|
53612
|
-
const statusTargets = statusResponse.
|
|
53613
|
-
? ((_a = statusResponse.message.records) !== null && _a !== void 0 ? _a : [])
|
|
53614
|
-
: [];
|
|
53451
|
+
const statusTargets = ((_a = statusResponse.message.records) !== null && _a !== void 0 ? _a : []);
|
|
53615
53452
|
this.collectProtocolV2LiveTargetIds(statusTargets, expectedTargetIds, liveTargetIds);
|
|
53616
53453
|
if (liveTargetIds.size > 0) {
|
|
53617
53454
|
currentInstallStatusObserved = true;
|
|
@@ -53650,9 +53487,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53650
53487
|
}
|
|
53651
53488
|
}
|
|
53652
53489
|
if (statusTargets.length === 0) {
|
|
53653
|
-
|
|
53654
|
-
lastError = new Error('Protocol V2 firmware update is waiting for user confirmation or target status');
|
|
53655
|
-
}
|
|
53490
|
+
lastError = new Error('Protocol V2 firmware update is waiting for user confirmation or target status');
|
|
53656
53491
|
}
|
|
53657
53492
|
else {
|
|
53658
53493
|
const missingTargetIds = this.getProtocolV2MissingTargetIds(statusTargets, expectedTargetIds);
|
|
@@ -53947,7 +53782,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53947
53782
|
});
|
|
53948
53783
|
}
|
|
53949
53784
|
acquireProtocolV2BleDevice(skipProtocolProbe = false) {
|
|
53950
|
-
var _a;
|
|
53951
53785
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53952
53786
|
const connector = this.device.deviceConnector;
|
|
53953
53787
|
const expectedId = this.device.originalDescriptor.id;
|
|
@@ -53955,14 +53789,9 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53955
53789
|
yield (connector === null || connector === void 0 ? void 0 : connector.acquire(expectedId, null, true, PROTOCOL_V2_CONNECT_PROTOCOL));
|
|
53956
53790
|
return;
|
|
53957
53791
|
}
|
|
53958
|
-
|
|
53959
|
-
const reconnectDescriptor = (_a = deviceDiff === null || deviceDiff === void 0 ? void 0 : deviceDiff.descriptors) === null || _a === void 0 ? void 0 : _a.find(descriptor => descriptor.id === expectedId);
|
|
53960
|
-
if (!reconnectDescriptor) {
|
|
53961
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotFound);
|
|
53962
|
-
}
|
|
53963
|
-
yield (connector === null || connector === void 0 ? void 0 : connector.acquire(reconnectDescriptor.id, null, true, PROTOCOL_V2_CONNECT_PROTOCOL, undefined, undefined, skipProtocolProbe));
|
|
53792
|
+
yield (connector === null || connector === void 0 ? void 0 : connector.acquire(expectedId, null, true, PROTOCOL_V2_CONNECT_PROTOCOL, undefined, undefined, skipProtocolProbe));
|
|
53964
53793
|
this.device.commands.disposed = false;
|
|
53965
|
-
this.device.getCommands().mainId =
|
|
53794
|
+
this.device.getCommands().mainId = expectedId;
|
|
53966
53795
|
});
|
|
53967
53796
|
}
|
|
53968
53797
|
protocolV2StartFirmwareUpdate({ targets, }) {
|
|
@@ -53977,7 +53806,18 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53977
53806
|
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 } : {}))));
|
|
53978
53807
|
if (this.isBleReconnect()) {
|
|
53979
53808
|
try {
|
|
53980
|
-
yield commands.call('DeviceFirmwareUpdateRequest', {}, {
|
|
53809
|
+
yield commands.call('DeviceFirmwareUpdateRequest', {}, {
|
|
53810
|
+
returnAfterWrite: true,
|
|
53811
|
+
expectedTypes: ['Success'],
|
|
53812
|
+
onResponseAfterWrite: response => {
|
|
53813
|
+
if (response.type !== 'Success')
|
|
53814
|
+
return;
|
|
53815
|
+
this.protocolV2InstallRequestConfirmed = true;
|
|
53816
|
+
this.device.clearCancelableAction();
|
|
53817
|
+
this.postProgressMessage(1, 'installingFirmware');
|
|
53818
|
+
Log$7.log('[FirmwareUpdateV4] BLE firmware install confirmed by device response');
|
|
53819
|
+
},
|
|
53820
|
+
});
|
|
53981
53821
|
Log$7.log('[FirmwareUpdateV4] BLE firmware install request written; continue with status polling');
|
|
53982
53822
|
}
|
|
53983
53823
|
catch (error) {
|
|
@@ -54493,15 +54333,10 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
54493
54333
|
return ['V2'];
|
|
54494
54334
|
}
|
|
54495
54335
|
init() {
|
|
54496
|
-
const { jpegBase64, fileName, chunkSize
|
|
54336
|
+
const { jpegBase64, fileName, chunkSize } = this.payload;
|
|
54497
54337
|
if (chunkSize !== undefined && (!Number.isInteger(chunkSize) || chunkSize <= 0)) {
|
|
54498
54338
|
throw invalidParameter$1('Parameter [chunkSize] must be a positive integer.');
|
|
54499
54339
|
}
|
|
54500
|
-
if (encoding !== undefined && encoding !== 'rgb565' && encoding !== 'i8-lz4') {
|
|
54501
|
-
throw invalidParameter$1('Parameter [encoding] must be either rgb565 or i8-lz4.');
|
|
54502
|
-
}
|
|
54503
|
-
const env = DataManager.getSettings('env');
|
|
54504
|
-
const resolvedEncoding = encoding !== null && encoding !== void 0 ? encoding : (env && DataManager.isBleConnect(env) ? 'i8-lz4' : 'rgb565');
|
|
54505
54340
|
const decoded = decodeJpegBase64ToRgba({
|
|
54506
54341
|
jpegBase64,
|
|
54507
54342
|
parameterName: 'jpegBase64',
|
|
@@ -54512,10 +54347,9 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
54512
54347
|
width: PRO2_WALLPAPER_WIDTH,
|
|
54513
54348
|
height: PRO2_WALLPAPER_HEIGHT,
|
|
54514
54349
|
rgba: decoded.data,
|
|
54515
|
-
encoding: resolvedEncoding,
|
|
54516
54350
|
});
|
|
54517
54351
|
this.path = `${WALLPAPER_DIRECTORY}/${normalizeFileName(fileName, this.encoded.data)}`;
|
|
54518
|
-
this.params = { jpegBase64, fileName, chunkSize
|
|
54352
|
+
this.params = { jpegBase64, fileName, chunkSize };
|
|
54519
54353
|
this.unlockPolicy = 'unlock-before-run';
|
|
54520
54354
|
this.protocolV2PreUnlockPinType = hdTransport.DeviceSessionPinType.Any;
|
|
54521
54355
|
this.skipForceUpdateCheck = true;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export declare const PRO2_WALLPAPER_WIDTH = 604;
|
|
2
2
|
export declare const PRO2_WALLPAPER_HEIGHT = 1024;
|
|
3
|
-
export type Pro2WallpaperColorFormat = 'RGB565' | 'RGB565A8'
|
|
4
|
-
export type Pro2WallpaperEncoding = 'rgb565' | 'i8-lz4';
|
|
3
|
+
export type Pro2WallpaperColorFormat = 'RGB565' | 'RGB565A8';
|
|
5
4
|
export type Pro2ImageAlphaMode = 'preserve' | 'black-background';
|
|
6
5
|
export declare function encodePro2Image(options: {
|
|
7
6
|
width: number;
|
|
@@ -16,7 +15,6 @@ export declare function encodePro2Wallpaper(options: {
|
|
|
16
15
|
width: number;
|
|
17
16
|
height: number;
|
|
18
17
|
rgba: Uint8Array | ArrayBuffer;
|
|
19
|
-
encoding?: Pro2WallpaperEncoding;
|
|
20
18
|
}): {
|
|
21
19
|
data: Uint8Array;
|
|
22
20
|
colorFormat: Pro2WallpaperColorFormat;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pro2Wallpaper.d.ts","sourceRoot":"","sources":["../../src/utils/pro2Wallpaper.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C,MAAM,MAAM,wBAAwB,GAAG,QAAQ,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"pro2Wallpaper.d.ts","sourceRoot":"","sources":["../../src/utils/pro2Wallpaper.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C,MAAM,MAAM,wBAAwB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE7D,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,kBAAkB,CAAC;AA8BjE,wBAAgB,eAAe,CAAC,OAAO,EAAE;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,UAAU,GAAG,WAAW,CAAC;IAC/B,SAAS,CAAC,EAAE,kBAAkB,CAAC;CAChC,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,WAAW,EAAE,wBAAwB,CAAA;CAAE,CA4E9D;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,UAAU,GAAG,WAAW,CAAC;CAChC,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,WAAW,EAAE,wBAAwB,CAAA;CAAE,CAE9D"}
|
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.172",
|
|
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.172",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.2.0-alpha.172",
|
|
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": "4c6c4a4fcc52bcdd0b3ec9c36454b2074fa17a8c"
|
|
50
50
|
}
|
|
@@ -2316,9 +2316,13 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2316
2316
|
}
|
|
2317
2317
|
seenTargetIds.add(targetId);
|
|
2318
2318
|
}
|
|
2319
|
-
const completedTargets = matchingTargets.filter(target =>
|
|
2320
|
-
|
|
2321
|
-
|
|
2319
|
+
const completedTargets = matchingTargets.filter(target => {
|
|
2320
|
+
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
2321
|
+
return (
|
|
2322
|
+
isProtocolV2TargetStatusFinished(target.status) &&
|
|
2323
|
+
(!liveTargetIds || (targetId !== undefined && liveTargetIds.has(targetId)))
|
|
2324
|
+
);
|
|
2325
|
+
});
|
|
2322
2326
|
const completedTargetIds = new Set<number>();
|
|
2323
2327
|
completedTargets.forEach(target => {
|
|
2324
2328
|
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
@@ -2465,7 +2469,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2465
2469
|
try {
|
|
2466
2470
|
const statusResponse = await this.device.getCommands().typedCall(
|
|
2467
2471
|
'DeviceFirmwareUpdateStatusGet',
|
|
2468
|
-
|
|
2472
|
+
'DeviceFirmwareUpdateStatus',
|
|
2469
2473
|
{
|
|
2470
2474
|
fields: {
|
|
2471
2475
|
status: true,
|
|
@@ -2475,24 +2479,11 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2475
2479
|
},
|
|
2476
2480
|
{ timeoutMs: PROTOCOL_V2_FIRMWARE_STATUS_RESPONSE_TIMEOUT }
|
|
2477
2481
|
);
|
|
2478
|
-
if (
|
|
2479
|
-
if (this.isBleReconnect()) {
|
|
2480
|
-
Log.log(
|
|
2481
|
-
'[FirmwareUpdateV4] BLE firmware install completed by terminal Success response'
|
|
2482
|
-
);
|
|
2483
|
-
this.recordProtocolV2AuthoritativeInstallCompletion(expectedTargetIds);
|
|
2484
|
-
this.postProgressMessage(100, 'installingFirmware');
|
|
2485
|
-
return;
|
|
2486
|
-
}
|
|
2482
|
+
if (this.protocolV2InstallRequestConfirmed) {
|
|
2487
2483
|
installEvidenceObserved = true;
|
|
2488
|
-
lastError = new Error(
|
|
2489
|
-
'Protocol V2 firmware install acknowledged; waiting for target status'
|
|
2490
|
-
);
|
|
2491
2484
|
}
|
|
2492
|
-
const statusTargets =
|
|
2493
|
-
|
|
2494
|
-
? ((statusResponse.message.records ?? []) as ProtocolV2FirmwareUpdateStatusTarget[])
|
|
2495
|
-
: [];
|
|
2485
|
+
const statusTargets = (statusResponse.message.records ??
|
|
2486
|
+
[]) as ProtocolV2FirmwareUpdateStatusTarget[];
|
|
2496
2487
|
this.collectProtocolV2LiveTargetIds(statusTargets, expectedTargetIds, liveTargetIds);
|
|
2497
2488
|
if (liveTargetIds.size > 0) {
|
|
2498
2489
|
currentInstallStatusObserved = true;
|
|
@@ -2552,11 +2543,9 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2552
2543
|
}
|
|
2553
2544
|
|
|
2554
2545
|
if (statusTargets.length === 0) {
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
);
|
|
2559
|
-
}
|
|
2546
|
+
lastError = new Error(
|
|
2547
|
+
'Protocol V2 firmware update is waiting for user confirmation or target status'
|
|
2548
|
+
);
|
|
2560
2549
|
} else {
|
|
2561
2550
|
const missingTargetIds = this.getProtocolV2MissingTargetIds(
|
|
2562
2551
|
statusTargets,
|
|
@@ -2952,15 +2941,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2952
2941
|
await connector?.acquire(expectedId, null, true, PROTOCOL_V2_CONNECT_PROTOCOL);
|
|
2953
2942
|
return;
|
|
2954
2943
|
}
|
|
2955
|
-
const deviceDiff = await connector?.enumerate();
|
|
2956
|
-
const reconnectDescriptor = deviceDiff?.descriptors?.find(
|
|
2957
|
-
descriptor => descriptor.id === expectedId
|
|
2958
|
-
);
|
|
2959
|
-
if (!reconnectDescriptor) {
|
|
2960
|
-
throw ERRORS.TypedError(HardwareErrorCode.DeviceNotFound);
|
|
2961
|
-
}
|
|
2962
2944
|
await connector?.acquire(
|
|
2963
|
-
|
|
2945
|
+
expectedId,
|
|
2964
2946
|
null,
|
|
2965
2947
|
true,
|
|
2966
2948
|
PROTOCOL_V2_CONNECT_PROTOCOL,
|
|
@@ -2969,7 +2951,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2969
2951
|
skipProtocolProbe
|
|
2970
2952
|
);
|
|
2971
2953
|
this.device.commands.disposed = false;
|
|
2972
|
-
this.device.getCommands().mainId =
|
|
2954
|
+
this.device.getCommands().mainId = expectedId;
|
|
2973
2955
|
}
|
|
2974
2956
|
|
|
2975
2957
|
private async protocolV2StartFirmwareUpdate({
|
|
@@ -2998,7 +2980,21 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2998
2980
|
|
|
2999
2981
|
if (this.isBleReconnect()) {
|
|
3000
2982
|
try {
|
|
3001
|
-
await commands.call(
|
|
2983
|
+
await commands.call(
|
|
2984
|
+
'DeviceFirmwareUpdateRequest',
|
|
2985
|
+
{},
|
|
2986
|
+
{
|
|
2987
|
+
returnAfterWrite: true,
|
|
2988
|
+
expectedTypes: ['Success'],
|
|
2989
|
+
onResponseAfterWrite: response => {
|
|
2990
|
+
if (response.type !== 'Success') return;
|
|
2991
|
+
this.protocolV2InstallRequestConfirmed = true;
|
|
2992
|
+
this.device.clearCancelableAction();
|
|
2993
|
+
this.postProgressMessage(1, 'installingFirmware');
|
|
2994
|
+
Log.log('[FirmwareUpdateV4] BLE firmware install confirmed by device response');
|
|
2995
|
+
},
|
|
2996
|
+
}
|
|
2997
|
+
);
|
|
3002
2998
|
Log.log(
|
|
3003
2999
|
'[FirmwareUpdateV4] BLE firmware install request written; continue with status polling'
|
|
3004
3000
|
);
|
|
@@ -7,7 +7,6 @@ import { BaseMethod } from '../BaseMethod';
|
|
|
7
7
|
import { decodeJpegBase64ToRgba } from '../helpers/base64Data';
|
|
8
8
|
import { invalidParameter } from '../helpers/filesystemValidation';
|
|
9
9
|
import { writeProtocolV2File } from '../helpers/protocolV2FileWrite';
|
|
10
|
-
import { DataManager } from '../../data-manager';
|
|
11
10
|
import { UI_REQUEST, createUiMessage } from '../../events/ui-request';
|
|
12
11
|
import { supportsProtocolV2Message } from '../../protocols/protocol-v2/features';
|
|
13
12
|
import { LoggerNames, getLogger } from '../../utils';
|
|
@@ -15,7 +14,6 @@ import {
|
|
|
15
14
|
PRO2_WALLPAPER_HEIGHT,
|
|
16
15
|
PRO2_WALLPAPER_WIDTH,
|
|
17
16
|
type Pro2WallpaperColorFormat,
|
|
18
|
-
type Pro2WallpaperEncoding,
|
|
19
17
|
encodePro2Wallpaper,
|
|
20
18
|
} from '../../utils/pro2Wallpaper';
|
|
21
19
|
|
|
@@ -23,7 +21,6 @@ export type DeviceUploadWallpaperParams = {
|
|
|
23
21
|
jpegBase64: string;
|
|
24
22
|
fileName?: string;
|
|
25
23
|
chunkSize?: number;
|
|
26
|
-
encoding?: Pro2WallpaperEncoding;
|
|
27
24
|
};
|
|
28
25
|
|
|
29
26
|
export type DeviceUploadWallpaperResponse = {
|
|
@@ -64,16 +61,10 @@ export default class DeviceUploadWallpaper extends BaseMethod<DeviceUploadWallpa
|
|
|
64
61
|
private path = '';
|
|
65
62
|
|
|
66
63
|
init() {
|
|
67
|
-
const { jpegBase64, fileName, chunkSize
|
|
64
|
+
const { jpegBase64, fileName, chunkSize } = this.payload;
|
|
68
65
|
if (chunkSize !== undefined && (!Number.isInteger(chunkSize) || chunkSize <= 0)) {
|
|
69
66
|
throw invalidParameter('Parameter [chunkSize] must be a positive integer.');
|
|
70
67
|
}
|
|
71
|
-
if (encoding !== undefined && encoding !== 'rgb565' && encoding !== 'i8-lz4') {
|
|
72
|
-
throw invalidParameter('Parameter [encoding] must be either rgb565 or i8-lz4.');
|
|
73
|
-
}
|
|
74
|
-
const env = DataManager.getSettings('env');
|
|
75
|
-
const resolvedEncoding: Pro2WallpaperEncoding =
|
|
76
|
-
encoding ?? (env && DataManager.isBleConnect(env) ? 'i8-lz4' : 'rgb565');
|
|
77
68
|
|
|
78
69
|
const decoded = decodeJpegBase64ToRgba({
|
|
79
70
|
jpegBase64,
|
|
@@ -85,10 +76,9 @@ export default class DeviceUploadWallpaper extends BaseMethod<DeviceUploadWallpa
|
|
|
85
76
|
width: PRO2_WALLPAPER_WIDTH,
|
|
86
77
|
height: PRO2_WALLPAPER_HEIGHT,
|
|
87
78
|
rgba: decoded.data,
|
|
88
|
-
encoding: resolvedEncoding,
|
|
89
79
|
});
|
|
90
80
|
this.path = `${WALLPAPER_DIRECTORY}/${normalizeFileName(fileName, this.encoded.data)}`;
|
|
91
|
-
this.params = { jpegBase64, fileName, chunkSize
|
|
81
|
+
this.params = { jpegBase64, fileName, chunkSize };
|
|
92
82
|
this.unlockPolicy = 'unlock-before-run';
|
|
93
83
|
// File writes and wallpaper apply require an unlocked device. Either PIN
|
|
94
84
|
// may authorize this device-management action.
|
|
@@ -6,26 +6,12 @@ import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
|
6
6
|
export const PRO2_WALLPAPER_WIDTH = 604;
|
|
7
7
|
export const PRO2_WALLPAPER_HEIGHT = 1024;
|
|
8
8
|
|
|
9
|
-
export type Pro2WallpaperColorFormat = 'RGB565' | 'RGB565A8'
|
|
10
|
-
|
|
11
|
-
export type Pro2WallpaperEncoding = 'rgb565' | 'i8-lz4';
|
|
9
|
+
export type Pro2WallpaperColorFormat = 'RGB565' | 'RGB565A8';
|
|
12
10
|
|
|
13
11
|
export type Pro2ImageAlphaMode = 'preserve' | 'black-background';
|
|
14
12
|
|
|
15
13
|
const COLOR_FORMAT_RGB565 = 0x12;
|
|
16
14
|
const COLOR_FORMAT_RGB565A8 = 0x14;
|
|
17
|
-
const COLOR_FORMAT_I8 = 0x0a;
|
|
18
|
-
const IMAGE_FLAG_COMPRESSED = 0x0008;
|
|
19
|
-
const IMAGE_COMPRESSION_LZ4 = 0x00000002;
|
|
20
|
-
const I8_PALETTE_SIZE = 256 * 4;
|
|
21
|
-
const I8_RED_LEVELS = 6;
|
|
22
|
-
const I8_GREEN_LEVELS = 7;
|
|
23
|
-
const I8_BLUE_LEVELS = 6;
|
|
24
|
-
const LZ4_MIN_MATCH = 4;
|
|
25
|
-
const LZ4_LAST_LITERALS = 5;
|
|
26
|
-
const LZ4_MATCH_FIND_LIMIT = 12;
|
|
27
|
-
const LZ4_HASH_BITS = 16;
|
|
28
|
-
const LZ4_HASH_MULTIPLIER = -1640531535;
|
|
29
15
|
|
|
30
16
|
const RED_THRESHOLD = [
|
|
31
17
|
1, 7, 3, 5, 0, 8, 2, 6, 7, 1, 5, 3, 8, 0, 6, 2, 3, 5, 0, 8, 2, 6, 1, 7, 5, 3, 8, 0, 6, 2, 7, 1, 0,
|
|
@@ -52,184 +38,6 @@ function align(value: number, boundary: number): number {
|
|
|
52
38
|
return Math.ceil(value / boundary) * boundary;
|
|
53
39
|
}
|
|
54
40
|
|
|
55
|
-
function writeLz4Length(output: Uint8Array, offset: number, length: number) {
|
|
56
|
-
let cursor = offset;
|
|
57
|
-
let remaining = length;
|
|
58
|
-
while (remaining >= 0xff) {
|
|
59
|
-
output[cursor] = 0xff;
|
|
60
|
-
cursor += 1;
|
|
61
|
-
remaining -= 0xff;
|
|
62
|
-
}
|
|
63
|
-
output[cursor] = remaining;
|
|
64
|
-
return cursor + 1;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function readUint32LittleEndian(data: Uint8Array, offset: number) {
|
|
68
|
-
return (
|
|
69
|
-
data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24)
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function getLz4Hash(sequence: number) {
|
|
74
|
-
return (Math.imul(sequence, LZ4_HASH_MULTIPLIER) >>> (32 - LZ4_HASH_BITS)) & 0xffff;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function compressLz4Block(input: Uint8Array) {
|
|
78
|
-
const output = new Uint8Array(input.byteLength + Math.floor(input.byteLength / 0xff) + 16);
|
|
79
|
-
const hashTable = new Int32Array(1 << LZ4_HASH_BITS);
|
|
80
|
-
hashTable.fill(-1);
|
|
81
|
-
|
|
82
|
-
let anchor = 0;
|
|
83
|
-
let inputOffset = 0;
|
|
84
|
-
let outputOffset = 0;
|
|
85
|
-
const matchFindEnd = input.byteLength - LZ4_MATCH_FIND_LIMIT;
|
|
86
|
-
const matchCopyEnd = input.byteLength - LZ4_LAST_LITERALS;
|
|
87
|
-
|
|
88
|
-
while (inputOffset <= matchFindEnd) {
|
|
89
|
-
const sequence = readUint32LittleEndian(input, inputOffset);
|
|
90
|
-
const hash = getLz4Hash(sequence);
|
|
91
|
-
const reference = hashTable[hash];
|
|
92
|
-
hashTable[hash] = inputOffset;
|
|
93
|
-
|
|
94
|
-
const matchOffset = inputOffset - reference;
|
|
95
|
-
const hasMatch =
|
|
96
|
-
reference >= 0 &&
|
|
97
|
-
matchOffset <= 0xffff &&
|
|
98
|
-
readUint32LittleEndian(input, reference) === sequence;
|
|
99
|
-
if (hasMatch) {
|
|
100
|
-
let matchLength = LZ4_MIN_MATCH;
|
|
101
|
-
while (
|
|
102
|
-
inputOffset + matchLength < matchCopyEnd &&
|
|
103
|
-
input[reference + matchLength] === input[inputOffset + matchLength]
|
|
104
|
-
) {
|
|
105
|
-
matchLength += 1;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const literalLength = inputOffset - anchor;
|
|
109
|
-
const encodedMatchLength = matchLength - LZ4_MIN_MATCH;
|
|
110
|
-
const tokenOffset = outputOffset;
|
|
111
|
-
outputOffset += 1;
|
|
112
|
-
output[tokenOffset] =
|
|
113
|
-
(Math.min(literalLength, 0x0f) << 4) | Math.min(encodedMatchLength, 0x0f);
|
|
114
|
-
|
|
115
|
-
if (literalLength >= 0x0f) {
|
|
116
|
-
outputOffset = writeLz4Length(output, outputOffset, literalLength - 0x0f);
|
|
117
|
-
}
|
|
118
|
-
output.set(input.subarray(anchor, inputOffset), outputOffset);
|
|
119
|
-
outputOffset += literalLength;
|
|
120
|
-
|
|
121
|
-
output[outputOffset] = matchOffset & 0xff;
|
|
122
|
-
output[outputOffset + 1] = matchOffset >> 8;
|
|
123
|
-
outputOffset += 2;
|
|
124
|
-
if (encodedMatchLength >= 0x0f) {
|
|
125
|
-
outputOffset = writeLz4Length(output, outputOffset, encodedMatchLength - 0x0f);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const matchStart = inputOffset;
|
|
129
|
-
inputOffset += matchLength;
|
|
130
|
-
anchor = inputOffset;
|
|
131
|
-
for (
|
|
132
|
-
let cursor = Math.max(matchStart + 1, inputOffset - 2);
|
|
133
|
-
cursor < inputOffset;
|
|
134
|
-
cursor += 1
|
|
135
|
-
) {
|
|
136
|
-
if (cursor <= matchFindEnd) {
|
|
137
|
-
hashTable[getLz4Hash(readUint32LittleEndian(input, cursor))] = cursor;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
} else {
|
|
141
|
-
inputOffset += 1;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const literalLength = input.byteLength - anchor;
|
|
146
|
-
const tokenOffset = outputOffset;
|
|
147
|
-
outputOffset += 1;
|
|
148
|
-
output[tokenOffset] = Math.min(literalLength, 0x0f) << 4;
|
|
149
|
-
if (literalLength >= 0x0f) {
|
|
150
|
-
outputOffset = writeLz4Length(output, outputOffset, literalLength - 0x0f);
|
|
151
|
-
}
|
|
152
|
-
output.set(input.subarray(anchor), outputOffset);
|
|
153
|
-
outputOffset += literalLength;
|
|
154
|
-
|
|
155
|
-
return output.slice(0, outputOffset);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function quantizeChannel(value: number, levels: number) {
|
|
159
|
-
return Math.floor((value * (levels - 1) + 0x7f) / 0xff);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
function expandChannel(value: number, levels: number) {
|
|
163
|
-
return Math.floor((value * 0xff + Math.floor((levels - 1) / 2)) / (levels - 1));
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function encodePro2I8Lz4(options: {
|
|
167
|
-
width: number;
|
|
168
|
-
height: number;
|
|
169
|
-
rgba: Uint8Array | ArrayBuffer;
|
|
170
|
-
}): { data: Uint8Array; colorFormat: Pro2WallpaperColorFormat } {
|
|
171
|
-
const { width, height } = options;
|
|
172
|
-
if (!Number.isInteger(width) || width <= 0 || width > 0xffff) {
|
|
173
|
-
throw invalidParameter('Wallpaper width must be an integer between 1 and 65535.');
|
|
174
|
-
}
|
|
175
|
-
if (!Number.isInteger(height) || height <= 0 || height > 0xffff) {
|
|
176
|
-
throw invalidParameter('Wallpaper height must be an integer between 1 and 65535.');
|
|
177
|
-
}
|
|
178
|
-
const rgba = asBytes(options.rgba);
|
|
179
|
-
const expectedLength = width * height * 4;
|
|
180
|
-
if (rgba.byteLength !== expectedLength) {
|
|
181
|
-
throw invalidParameter(
|
|
182
|
-
`Wallpaper RGBA data length must be ${expectedLength} bytes, received ${rgba.byteLength}.`
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
const stride = width;
|
|
186
|
-
const rawData = new Uint8Array(I8_PALETTE_SIZE + stride * height);
|
|
187
|
-
|
|
188
|
-
for (let red = 0; red < I8_RED_LEVELS; red += 1) {
|
|
189
|
-
for (let green = 0; green < I8_GREEN_LEVELS; green += 1) {
|
|
190
|
-
for (let blue = 0; blue < I8_BLUE_LEVELS; blue += 1) {
|
|
191
|
-
const paletteIndex = (red * I8_GREEN_LEVELS + green) * I8_BLUE_LEVELS + blue;
|
|
192
|
-
const paletteOffset = paletteIndex * 4;
|
|
193
|
-
// LVGL stores its ARGB8888 palette as B, G, R, A bytes on little-endian devices.
|
|
194
|
-
rawData[paletteOffset] = expandChannel(blue, I8_BLUE_LEVELS);
|
|
195
|
-
rawData[paletteOffset + 1] = expandChannel(green, I8_GREEN_LEVELS);
|
|
196
|
-
rawData[paletteOffset + 2] = expandChannel(red, I8_RED_LEVELS);
|
|
197
|
-
rawData[paletteOffset + 3] = 0xff;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
for (let pixel = 0; pixel < width * height; pixel += 1) {
|
|
203
|
-
const sourceOffset = pixel * 4;
|
|
204
|
-
const alpha = rgba[sourceOffset + 3];
|
|
205
|
-
const red = Math.round((rgba[sourceOffset] * alpha) / 0xff);
|
|
206
|
-
const green = Math.round((rgba[sourceOffset + 1] * alpha) / 0xff);
|
|
207
|
-
const blue = Math.round((rgba[sourceOffset + 2] * alpha) / 0xff);
|
|
208
|
-
const paletteIndex =
|
|
209
|
-
(quantizeChannel(red, I8_RED_LEVELS) * I8_GREEN_LEVELS +
|
|
210
|
-
quantizeChannel(green, I8_GREEN_LEVELS)) *
|
|
211
|
-
I8_BLUE_LEVELS +
|
|
212
|
-
quantizeChannel(blue, I8_BLUE_LEVELS);
|
|
213
|
-
rawData[I8_PALETTE_SIZE + pixel] = paletteIndex;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
const compressed = compressLz4Block(rawData);
|
|
217
|
-
const data = new Uint8Array(24 + compressed.byteLength);
|
|
218
|
-
const view = new DataView(data.buffer);
|
|
219
|
-
data[0] = 0x19;
|
|
220
|
-
data[1] = COLOR_FORMAT_I8;
|
|
221
|
-
view.setUint16(2, IMAGE_FLAG_COMPRESSED, true);
|
|
222
|
-
view.setUint16(4, width, true);
|
|
223
|
-
view.setUint16(6, height, true);
|
|
224
|
-
view.setUint16(8, stride, true);
|
|
225
|
-
view.setUint16(10, 0, true);
|
|
226
|
-
view.setUint32(12, IMAGE_COMPRESSION_LZ4, true);
|
|
227
|
-
view.setUint32(16, compressed.byteLength, true);
|
|
228
|
-
view.setUint32(20, rawData.byteLength, true);
|
|
229
|
-
data.set(compressed, 24);
|
|
230
|
-
return { data, colorFormat: 'I8' };
|
|
231
|
-
}
|
|
232
|
-
|
|
233
41
|
export function encodePro2Image(options: {
|
|
234
42
|
width: number;
|
|
235
43
|
height: number;
|
|
@@ -317,10 +125,6 @@ export function encodePro2Wallpaper(options: {
|
|
|
317
125
|
width: number;
|
|
318
126
|
height: number;
|
|
319
127
|
rgba: Uint8Array | ArrayBuffer;
|
|
320
|
-
encoding?: Pro2WallpaperEncoding;
|
|
321
128
|
}): { data: Uint8Array; colorFormat: Pro2WallpaperColorFormat } {
|
|
322
|
-
if (options.encoding === 'i8-lz4') {
|
|
323
|
-
return encodePro2I8Lz4(options);
|
|
324
|
-
}
|
|
325
129
|
return encodePro2Image(options);
|
|
326
130
|
}
|