@onekeyfe/hd-transport-web-device 1.2.8-alpha.51 → 1.2.8-alpha.52

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/dist/index.d.ts CHANGED
@@ -13,7 +13,6 @@ interface DeviceInfo extends OneKeyDeviceInfoBase {
13
13
  protocolType?: ProtocolType;
14
14
  }
15
15
  declare class WebUsbTransport extends ProtocolV2UsbTransportBase<string> {
16
- private readonly identityProbe;
17
16
  messages: ReturnType<typeof _onekeyfe_hd_transport__default.parseConfigure> | undefined;
18
17
  /** Protobuf schema for Protocol V2 transports. */
19
18
  messagesV2: ReturnType<typeof _onekeyfe_hd_transport__default.parseConfigure> | undefined;
@@ -30,8 +29,6 @@ declare class WebUsbTransport extends ProtocolV2UsbTransportBase<string> {
30
29
  private staleProtocolPaths;
31
30
  /** Paths currently acquired (between a successful acquire() and its release()). */
32
31
  private acquiredPaths;
33
- private identityProbeDevices;
34
- private identityProbeCleanupPaths;
35
32
  /**
36
33
  * The exact USBDevice object each cached protocol was probed against. The
37
34
  * browser returns the same object identity for a device as long as it stays
@@ -56,7 +53,7 @@ declare class WebUsbTransport extends ProtocolV2UsbTransportBase<string> {
56
53
  configurationId: number;
57
54
  endpointId: number;
58
55
  interfaceId: number;
59
- constructor(identityProbe?: boolean);
56
+ constructor();
60
57
  /**
61
58
  * Initialize WebUSB transport
62
59
  */
@@ -132,9 +129,6 @@ declare class WebUsbTransport extends ProtocolV2UsbTransportBase<string> {
132
129
  * Discovers interface/endpoint numbers from USB descriptors on first connection.
133
130
  */
134
131
  connectToDevice(path: string, first: boolean): Promise<undefined>;
135
- private assertHandleAvailable;
136
- private claimIdentityProbeHandle;
137
- private releaseIdentityProbeHandle;
138
132
  private closeOpenDevice;
139
133
  private clearEndpointHalt;
140
134
  /**
package/dist/index.js CHANGED
@@ -56,8 +56,6 @@ const PROTOCOL_V2_PROBE_TIMEOUT = 1000;
56
56
  const EXPECTED_PROTOCOL_V2_PROBE_ATTEMPTS = 2;
57
57
  let activeWebUsbTransport;
58
58
  let usbDisconnectListenerAttached = false;
59
- const identityProbeHandles = new WeakSet();
60
- const openingHandles = new WeakSet();
61
59
  function registerActiveWebUsbTransport(instance, usb) {
62
60
  activeWebUsbTransport = instance;
63
61
  if (usbDisconnectListenerAttached)
@@ -74,20 +72,17 @@ function registerActiveWebUsbTransport(instance, usb) {
74
72
  });
75
73
  }
76
74
  class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
77
- constructor(identityProbe = false) {
75
+ constructor() {
78
76
  super({
79
77
  router: transport.PROTOCOL_V2_CHANNEL_USB,
80
78
  maxFrameBytes: transport.PROTOCOL_V2_FRAME_MAX_BYTES,
81
79
  logPrefix: 'ProtocolV2 WebUSB',
82
80
  });
83
- this.identityProbe = identityProbe;
84
81
  this.deviceProtocol = new Map();
85
82
  this.confirmedDeviceProtocols = new Map();
86
83
  this.deviceProtocolHints = new Map();
87
84
  this.staleProtocolPaths = new Set();
88
85
  this.acquiredPaths = new Set();
89
- this.identityProbeDevices = new Map();
90
- this.identityProbeCleanupPaths = new Set();
91
86
  this.probedDeviceObjects = new Map();
92
87
  this.deviceEndpoints = new Map();
93
88
  this.name = 'WebUsbTransport';
@@ -106,8 +101,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
106
101
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'WebUSB is not supported by current browsers');
107
102
  }
108
103
  this.usb = usb;
109
- if (!this.identityProbe)
110
- registerActiveWebUsbTransport(this, usb);
104
+ registerActiveWebUsbTransport(this, usb);
111
105
  }
112
106
  emitDeviceDisconnect(path, device) {
113
107
  var _a, _b;
@@ -156,13 +150,6 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
156
150
  }
157
151
  enumerate() {
158
152
  return __awaiter(this, void 0, void 0, function* () {
159
- for (const path of this.identityProbeCleanupPaths) {
160
- try {
161
- yield this.release(path);
162
- }
163
- catch (_a) {
164
- }
165
- }
166
153
  yield this.getConnectedDevices();
167
154
  return this.deviceList;
168
155
  });
@@ -200,10 +187,6 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
200
187
  return __awaiter(this, void 0, void 0, function* () {
201
188
  if (!input.path)
202
189
  return;
203
- if (this.identityProbe) {
204
- yield this.getConnectedDevices();
205
- this.claimIdentityProbeHandle(input.path, yield this.findDevice(input.path));
206
- }
207
190
  try {
208
191
  yield this.rotateProtocolV2UsbGeneration(input.path, 'WebUSB transport acquired');
209
192
  yield this.closeOpenDevice(input.path);
@@ -265,12 +248,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
265
248
  catch (e) {
266
249
  this.Log.debug('acquire error: ', e instanceof Error ? `${e.name}: ${e.message}` : String(e));
267
250
  this.acquiredPaths.delete(input.path);
268
- try {
269
- yield this.closeOpenDevice(input.path);
270
- }
271
- finally {
272
- this.releaseIdentityProbeHandle(input.path);
273
- }
251
+ yield this.closeOpenDevice(input.path);
274
252
  throw e;
275
253
  }
276
254
  });
@@ -397,22 +375,12 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
397
375
  var _a;
398
376
  return __awaiter(this, void 0, void 0, function* () {
399
377
  let device = yield this.findDevice(path);
400
- if (this.identityProbe && this.identityProbeDevices.get(path) !== device) {
401
- yield this.closeOpenDevice(path);
402
- this.releaseIdentityProbeHandle(path);
403
- this.claimIdentityProbeHandle(path, device);
404
- }
405
- this.assertHandleAvailable(device);
406
378
  if (!device.opened) {
407
- openingHandles.add(device);
408
379
  try {
409
380
  yield device.open();
410
381
  }
411
382
  catch (error) {
412
- return yield this.throwWebUsbIoError(path, 'open', error);
413
- }
414
- finally {
415
- openingHandles.delete(device);
383
+ return this.throwWebUsbIoError(path, 'open', error);
416
384
  }
417
385
  }
418
386
  if (first || this.deviceProtocol.get(path) !== 'V1') {
@@ -425,22 +393,12 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
425
393
  }
426
394
  yield this.getConnectedDevices();
427
395
  device = yield this.findDevice(path);
428
- if (this.identityProbe && this.identityProbeDevices.get(path) !== device) {
429
- yield this.closeOpenDevice(path);
430
- this.releaseIdentityProbeHandle(path);
431
- this.claimIdentityProbeHandle(path, device);
432
- }
433
- this.assertHandleAvailable(device);
434
396
  if (!device.opened) {
435
- openingHandles.add(device);
436
397
  try {
437
398
  yield device.open();
438
399
  }
439
400
  catch (error) {
440
- return yield this.throwWebUsbIoError(path, 'open', error);
441
- }
442
- finally {
443
- openingHandles.delete(device);
401
+ return this.throwWebUsbIoError(path, 'open', error);
444
402
  }
445
403
  }
446
404
  if (first ||
@@ -460,39 +418,12 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
460
418
  yield this.clearEndpointHalt(device, 'out', endpoints.endpointOut);
461
419
  });
462
420
  }
463
- assertHandleAvailable(device) {
464
- if (identityProbeHandles.has(device) &&
465
- ![...this.identityProbeDevices.values()].includes(device)) {
466
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'USB device is already in use');
467
- }
468
- }
469
- claimIdentityProbeHandle(path, device) {
470
- if (device.opened || openingHandles.has(device) || identityProbeHandles.has(device)) {
471
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'USB device is already in use');
472
- }
473
- identityProbeHandles.add(device);
474
- this.identityProbeDevices.set(path, device);
475
- }
476
- releaseIdentityProbeHandle(path) {
477
- const device = this.identityProbeDevices.get(path);
478
- if (device === null || device === void 0 ? void 0 : device.opened) {
479
- this.identityProbeCleanupPaths.add(path);
480
- return;
481
- }
482
- if (device)
483
- identityProbeHandles.delete(device);
484
- this.identityProbeDevices.delete(path);
485
- this.identityProbeCleanupPaths.delete(path);
486
- }
487
421
  closeOpenDevice(path) {
488
422
  var _a, _b, _c, _d;
489
423
  return __awaiter(this, void 0, void 0, function* () {
490
- const current = this.identityProbe
491
- ? this.identityProbeDevices.get(path)
492
- : (_a = this.deviceList.find(device => device.path === path)) === null || _a === void 0 ? void 0 : _a.device;
424
+ const current = (_a = this.deviceList.find(device => device.path === path)) === null || _a === void 0 ? void 0 : _a.device;
493
425
  if (!(current === null || current === void 0 ? void 0 : current.opened))
494
426
  return;
495
- this.assertHandleAvailable(current);
496
427
  const endpoints = this.deviceEndpoints.get(path);
497
428
  const ifaceNum = (_b = endpoints === null || endpoints === void 0 ? void 0 : endpoints.interfaceNumber) !== null && _b !== void 0 ? _b : this.interfaceId;
498
429
  try {
@@ -506,8 +437,6 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
506
437
  }
507
438
  catch (error) {
508
439
  (_d = this.Log) === null || _d === void 0 ? void 0 : _d.debug('[WebUsbTransport] close before reconnect failed:', error);
509
- if (this.identityProbe)
510
- throw error;
511
440
  }
512
441
  });
513
442
  }
@@ -820,10 +749,10 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
820
749
  return false;
821
750
  }
822
751
  try {
823
- const response = yield this.callProtocolV1(path, this.identityProbe ? 'GetFeatures' : 'Initialize', {}, {
752
+ yield this.callProtocolV1(path, 'Initialize', {}, {
824
753
  timeoutMs: PROTOCOL_V1_PROBE_TIMEOUT,
825
754
  });
826
- return !this.identityProbe || response.type === 'Features';
755
+ return true;
827
756
  }
828
757
  catch (error) {
829
758
  if (this.isWebUsbIoHardwareError(error))
@@ -940,13 +869,8 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
940
869
  release(path) {
941
870
  return __awaiter(this, void 0, void 0, function* () {
942
871
  this.acquiredPaths.delete(path);
943
- try {
944
- yield this.invalidateProtocolV2UsbLink(path, 'WebUSB transport released');
945
- yield this.closeOpenDevice(path);
946
- }
947
- finally {
948
- this.releaseIdentityProbeHandle(path);
949
- }
872
+ yield this.invalidateProtocolV2UsbLink(path, 'WebUSB transport released');
873
+ yield this.closeOpenDevice(path);
950
874
  this.deviceEndpoints.delete(path);
951
875
  });
952
876
  }
package/dist/webusb.d.ts CHANGED
@@ -9,7 +9,6 @@ export interface DeviceInfo extends OneKeyDeviceInfoBase {
9
9
  protocolType?: ProtocolType;
10
10
  }
11
11
  export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string> {
12
- private readonly identityProbe;
13
12
  messages: ReturnType<typeof transport.parseConfigure> | undefined;
14
13
  messagesV2: ReturnType<typeof transport.parseConfigure> | undefined;
15
14
  private protocolV2SchemaSource;
@@ -18,8 +17,6 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
18
17
  private deviceProtocolHints;
19
18
  private staleProtocolPaths;
20
19
  private acquiredPaths;
21
- private identityProbeDevices;
22
- private identityProbeCleanupPaths;
23
20
  private probedDeviceObjects;
24
21
  private deviceEndpoints;
25
22
  name: string;
@@ -32,7 +29,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
32
29
  configurationId: number;
33
30
  endpointId: number;
34
31
  interfaceId: number;
35
- constructor(identityProbe?: boolean);
32
+ constructor();
36
33
  init(logger: any, emitter?: EventEmitter): void;
37
34
  emitDeviceDisconnect(path: string, device?: USBDevice): void;
38
35
  markProtocolStale(path: string): void;
@@ -50,9 +47,6 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
50
47
  connect(path: string, first: boolean): Promise<undefined>;
51
48
  private discoverEndpoints;
52
49
  connectToDevice(path: string, first: boolean): Promise<undefined>;
53
- private assertHandleAvailable;
54
- private claimIdentityProbeHandle;
55
- private releaseIdentityProbeHandle;
56
50
  private closeOpenDevice;
57
51
  private clearEndpointHalt;
58
52
  private assertAcquired;
@@ -1 +1 @@
1
- {"version":3,"file":"webusb.d.ts","sourceRoot":"","sources":["../src/webusb.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webusb.d.ts","sourceRoot":"","sources":["../src/webusb.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-transport-web-device",
3
- "version": "1.2.8-alpha.51",
3
+ "version": "1.2.8-alpha.52",
4
4
  "author": "OneKey",
5
5
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
6
6
  "license": "MIT",
@@ -21,13 +21,13 @@
21
21
  "lint:fix": "eslint . --fix"
22
22
  },
23
23
  "dependencies": {
24
- "@onekeyfe/hd-shared": "1.2.8-alpha.51",
25
- "@onekeyfe/hd-transport": "1.2.8-alpha.51"
24
+ "@onekeyfe/hd-shared": "1.2.8-alpha.52",
25
+ "@onekeyfe/hd-transport": "1.2.8-alpha.52"
26
26
  },
27
27
  "devDependencies": {
28
- "@onekeyfe/hd-transport-electron": "1.2.8-alpha.51",
28
+ "@onekeyfe/hd-transport-electron": "1.2.8-alpha.52",
29
29
  "@types/w3c-web-usb": "^1.0.6",
30
30
  "@types/web-bluetooth": "^0.0.17"
31
31
  },
32
- "gitHead": "0ccbc08199c62e96f6084e864e558055100b66ed"
32
+ "gitHead": "389c588beb19de26451c729bb09bc8e7ce6b0717"
33
33
  }
package/src/webusb.ts CHANGED
@@ -82,10 +82,6 @@ type WebUsbOperation = 'open' | 'claimInterface' | 'transferIn' | 'transferOut';
82
82
  */
83
83
  let activeWebUsbTransport: WebUsbTransport | undefined;
84
84
  let usbDisconnectListenerAttached = false;
85
- // Only isolated discovery owns these handles. Normal calls must never close or
86
- // open them, including while native open() is still pending.
87
- const identityProbeHandles = new WeakSet<USBDevice>();
88
- const openingHandles = new WeakSet<USBDevice>();
89
85
 
90
86
  function registerActiveWebUsbTransport(instance: WebUsbTransport, usb: USB) {
91
87
  activeWebUsbTransport = instance;
@@ -128,10 +124,6 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
128
124
  /** Paths currently acquired (between a successful acquire() and its release()). */
129
125
  private acquiredPaths: Set<string> = new Set();
130
126
 
131
- private identityProbeDevices = new Map<string, USBDevice>();
132
-
133
- private identityProbeCleanupPaths = new Set<string>();
134
-
135
127
  /**
136
128
  * The exact USBDevice object each cached protocol was probed against. The
137
129
  * browser returns the same object identity for a device as long as it stays
@@ -168,7 +160,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
168
160
 
169
161
  interfaceId = INTERFACE_ID;
170
162
 
171
- constructor(private readonly identityProbe = false) {
163
+ constructor() {
172
164
  super({
173
165
  router: PROTOCOL_V2_CHANNEL_USB,
174
166
  maxFrameBytes: PROTOCOL_V2_FRAME_MAX_BYTES,
@@ -191,7 +183,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
191
183
  );
192
184
  }
193
185
  this.usb = usb;
194
- if (!this.identityProbe) registerActiveWebUsbTransport(this, usb);
186
+ registerActiveWebUsbTransport(this, usb);
195
187
  }
196
188
 
197
189
  /**
@@ -275,14 +267,6 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
275
267
  * It does NOT prompt the user to select a device
276
268
  */
277
269
  async enumerate() {
278
- // Retry only our failed cleanup before Core skips already-open USB handles.
279
- for (const path of this.identityProbeCleanupPaths) {
280
- try {
281
- await this.release(path);
282
- } catch {
283
- // Keep ownership while native close still fails; retry on the next probe.
284
- }
285
- }
286
270
  await this.getConnectedDevices();
287
271
  return this.deviceList;
288
272
  }
@@ -327,10 +311,6 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
327
311
  */
328
312
  async acquire(input: AcquireInput) {
329
313
  if (!input.path) return;
330
- if (this.identityProbe) {
331
- await this.getConnectedDevices();
332
- this.claimIdentityProbeHandle(input.path, await this.findDevice(input.path));
333
- }
334
314
  try {
335
315
  await this.rotateProtocolV2UsbGeneration(input.path, 'WebUSB transport acquired');
336
316
  await this.closeOpenDevice(input.path);
@@ -414,11 +394,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
414
394
  } catch (e) {
415
395
  this.Log.debug('acquire error: ', e instanceof Error ? `${e.name}: ${e.message}` : String(e));
416
396
  this.acquiredPaths.delete(input.path);
417
- try {
418
- await this.closeOpenDevice(input.path);
419
- } finally {
420
- this.releaseIdentityProbeHandle(input.path);
421
- }
397
+ await this.closeOpenDevice(input.path);
422
398
  throw e;
423
399
  }
424
400
  }
@@ -593,20 +569,11 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
593
569
  */
594
570
  async connectToDevice(path: string, first: boolean) {
595
571
  let device: USBDevice = await this.findDevice(path);
596
- if (this.identityProbe && this.identityProbeDevices.get(path) !== device) {
597
- await this.closeOpenDevice(path);
598
- this.releaseIdentityProbeHandle(path);
599
- this.claimIdentityProbeHandle(path, device);
600
- }
601
- this.assertHandleAvailable(device);
602
572
  if (!device.opened) {
603
- openingHandles.add(device);
604
573
  try {
605
574
  await device.open();
606
575
  } catch (error) {
607
- return await this.throwWebUsbIoError(path, 'open', error);
608
- } finally {
609
- openingHandles.delete(device);
576
+ return this.throwWebUsbIoError(path, 'open', error);
610
577
  }
611
578
  }
612
579
  // A V1 packet retry continues an in-flight exchange. Preserve its endpoint
@@ -620,20 +587,11 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
620
587
  }
621
588
  await this.getConnectedDevices();
622
589
  device = await this.findDevice(path);
623
- if (this.identityProbe && this.identityProbeDevices.get(path) !== device) {
624
- await this.closeOpenDevice(path);
625
- this.releaseIdentityProbeHandle(path);
626
- this.claimIdentityProbeHandle(path, device);
627
- }
628
- this.assertHandleAvailable(device);
629
590
  if (!device.opened) {
630
- openingHandles.add(device);
631
591
  try {
632
592
  await device.open();
633
593
  } catch (error) {
634
- return await this.throwWebUsbIoError(path, 'open', error);
635
- } finally {
636
- openingHandles.delete(device);
594
+ return this.throwWebUsbIoError(path, 'open', error);
637
595
  }
638
596
  }
639
597
 
@@ -657,41 +615,9 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
657
615
  await this.clearEndpointHalt(device, 'out', endpoints.endpointOut);
658
616
  }
659
617
 
660
- private assertHandleAvailable(device: USBDevice) {
661
- if (
662
- identityProbeHandles.has(device) &&
663
- ![...this.identityProbeDevices.values()].includes(device)
664
- ) {
665
- throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'USB device is already in use');
666
- }
667
- }
668
-
669
- private claimIdentityProbeHandle(path: string, device: USBDevice) {
670
- if (device.opened || openingHandles.has(device) || identityProbeHandles.has(device)) {
671
- throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'USB device is already in use');
672
- }
673
- identityProbeHandles.add(device);
674
- this.identityProbeDevices.set(path, device);
675
- }
676
-
677
- private releaseIdentityProbeHandle(path: string) {
678
- const device = this.identityProbeDevices.get(path);
679
- // A failed native close must not make an open probe handle available to other callers.
680
- if (device?.opened) {
681
- this.identityProbeCleanupPaths.add(path);
682
- return;
683
- }
684
- if (device) identityProbeHandles.delete(device);
685
- this.identityProbeDevices.delete(path);
686
- this.identityProbeCleanupPaths.delete(path);
687
- }
688
-
689
618
  private async closeOpenDevice(path: string) {
690
- const current = this.identityProbe
691
- ? this.identityProbeDevices.get(path)
692
- : this.deviceList.find(device => device.path === path)?.device;
619
+ const current = this.deviceList.find(device => device.path === path)?.device;
693
620
  if (!current?.opened) return;
694
- this.assertHandleAvailable(current);
695
621
 
696
622
  const endpoints = this.deviceEndpoints.get(path);
697
623
  const ifaceNum = endpoints?.interfaceNumber ?? this.interfaceId;
@@ -704,7 +630,6 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
704
630
  await current.close();
705
631
  } catch (error) {
706
632
  this.Log?.debug('[WebUsbTransport] close before reconnect failed:', error);
707
- if (this.identityProbe) throw error;
708
633
  }
709
634
  }
710
635
 
@@ -1059,15 +984,15 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
1059
984
  }
1060
985
 
1061
986
  try {
1062
- const response = await this.callProtocolV1(
987
+ await this.callProtocolV1(
1063
988
  path,
1064
- this.identityProbe ? 'GetFeatures' : 'Initialize',
989
+ 'Initialize',
1065
990
  {},
1066
991
  {
1067
992
  timeoutMs: PROTOCOL_V1_PROBE_TIMEOUT,
1068
993
  }
1069
994
  );
1070
- return !this.identityProbe || response.type === 'Features';
995
+ return true;
1071
996
  } catch (error) {
1072
997
  if (this.isWebUsbIoHardwareError(error)) throw error;
1073
998
  return false;
@@ -1224,12 +1149,8 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
1224
1149
  */
1225
1150
  async release(path: string) {
1226
1151
  this.acquiredPaths.delete(path);
1227
- try {
1228
- await this.invalidateProtocolV2UsbLink(path, 'WebUSB transport released');
1229
- await this.closeOpenDevice(path);
1230
- } finally {
1231
- this.releaseIdentityProbeHandle(path);
1232
- }
1152
+ await this.invalidateProtocolV2UsbLink(path, 'WebUSB transport released');
1153
+ await this.closeOpenDevice(path);
1233
1154
  // Keep deviceProtocol/deviceProtocolHints across release: the probe result is a
1234
1155
  // physical-device property, so the next acquire can skip the wire-level probe.
1235
1156
  // V2 entries are still dropped by onProtocolV2UsbLinkInvalidated via the link
@@ -1,268 +0,0 @@
1
- import WebUsbTransport from '../src/webusb';
2
- import { probeUsbDeviceIdentities } from '@onekeyfe/hd-common-connect-sdk/src';
3
-
4
- import type { MessageFromOneKey, TransportCallOptions } from '@onekeyfe/hd-transport';
5
-
6
- jest.mock('@onekeyfe/hd-core', () => jest.requireActual('../../core/src'));
7
- jest.mock('../../core/src/data/config', () => ({
8
- getSDKVersion: () => '1.0.0-test',
9
- DEFAULT_DOMAIN: 'https://jssdk.onekey.so/1.0.0-test/',
10
- }));
11
- jest.mock('@onekeyfe/hd-transport-web-device', () => ({
12
- WebUsbTransport: jest.requireActual('../src/webusb').default,
13
- }));
14
- jest.mock('@onekeyfe/hd-transport-http', () => ({ __esModule: true, default: jest.fn() }));
15
- jest.mock('@onekeyfe/hd-transport-lowlevel', () => ({}));
16
- jest.mock('@onekeyfe/hd-transport-emulator', () => ({}));
17
-
18
- describe('WebUSB identity probe ownership', () => {
19
- let originalNavigator: PropertyDescriptor | undefined;
20
- const device = {
21
- vendorId: 0x1209,
22
- productId: 0x53c1,
23
- serialNumber: 'USB_PATH',
24
- opened: false,
25
- close: jest.fn(),
26
- };
27
- let disconnectListener: (event: { device: typeof device }) => void;
28
- const usb = {
29
- getDevices: jest.fn(),
30
- addEventListener: jest.fn((_type, callback) => {
31
- disconnectListener = callback;
32
- }),
33
- };
34
- beforeEach(() => {
35
- originalNavigator = Object.getOwnPropertyDescriptor(globalThis, 'navigator');
36
- device.opened = false;
37
- device.close.mockReset().mockImplementation(() => {
38
- device.opened = false;
39
- return Promise.resolve();
40
- });
41
- usb.getDevices.mockResolvedValue([device]);
42
- usb.addEventListener.mockClear();
43
- Object.defineProperty(globalThis, 'navigator', { configurable: true, value: { usb } });
44
- });
45
- afterEach(() => {
46
- if (originalNavigator) Object.defineProperty(globalThis, 'navigator', originalNavigator);
47
- else delete (globalThis as { navigator?: Navigator }).navigator;
48
- });
49
-
50
- test('does not close a handle already opened by another operation', async () => {
51
- const probe = new WebUsbTransport(true);
52
- probe.init({ debug: jest.fn() });
53
- device.opened = true;
54
- await expect(probe.acquire({ path: 'USB_PATH' })).rejects.toThrow(
55
- 'USB device is already in use'
56
- );
57
- expect(device.close).not.toHaveBeenCalled();
58
- expect(usb.addEventListener).not.toHaveBeenCalled();
59
- });
60
-
61
- test('does not borrow a handle while a normal native open is pending', async () => {
62
- const active = new WebUsbTransport();
63
- const probe = new WebUsbTransport(true);
64
- active.init({ debug: jest.fn() });
65
- probe.init({ debug: jest.fn() });
66
- let finishOpen!: () => void;
67
- let started!: () => void;
68
- const opening = new Promise<void>(resolve => {
69
- finishOpen = resolve;
70
- });
71
- const entered = new Promise<void>(resolve => {
72
- started = resolve;
73
- });
74
- const native = Object.assign(device, {
75
- open: jest.fn(async () => {
76
- started();
77
- await opening;
78
- device.opened = true;
79
- }),
80
- reset: jest.fn(),
81
- configurations: [],
82
- configuration: { configurationValue: 1 },
83
- selectConfiguration: jest.fn(),
84
- claimInterface: jest.fn(),
85
- clearHalt: jest.fn(),
86
- });
87
- jest.spyOn(active, 'findDevice').mockResolvedValue(native as unknown as USBDevice);
88
- const connecting = active.connectToDevice('USB_PATH', true);
89
- await entered;
90
- await expect(probe.acquire({ path: 'USB_PATH' })).rejects.toThrow(
91
- 'USB device is already in use'
92
- );
93
- expect(device.close).not.toHaveBeenCalled();
94
- finishOpen();
95
- await connecting;
96
- });
97
-
98
- test('a normal connection cannot close an isolated probe handle and release closes the captured handle after re-enumeration', async () => {
99
- const probe = new WebUsbTransport(true);
100
- probe.init({ debug: jest.fn() });
101
- const internals = probe as unknown as {
102
- rotateProtocolV2UsbGeneration: () => Promise<void>;
103
- detectProtocol: () => Promise<'V1'>;
104
- };
105
- jest.spyOn(internals, 'rotateProtocolV2UsbGeneration').mockResolvedValue(undefined);
106
- jest.spyOn(internals, 'detectProtocol').mockResolvedValue('V1');
107
- jest.spyOn(probe, 'connect').mockImplementation(() => {
108
- device.opened = true;
109
- return Promise.resolve();
110
- });
111
- await probe.acquire({ path: 'USB_PATH' });
112
- const active = new WebUsbTransport();
113
- active.init({ debug: jest.fn() });
114
- await expect(active.connectToDevice('USB_PATH', true)).rejects.toThrow(
115
- 'USB device is already in use'
116
- );
117
- expect(device.close).not.toHaveBeenCalled();
118
- const replacement = { ...device, close: jest.fn() };
119
- usb.getDevices.mockResolvedValue([replacement]);
120
- await probe.getConnectedDevices();
121
- device.close.mockRejectedValueOnce(new Error('native close failed'));
122
- await expect(probe.release('USB_PATH')).rejects.toThrow('native close failed');
123
- await probe.enumerate();
124
- expect(device.close).toHaveBeenCalledTimes(2);
125
- expect(replacement.close).not.toHaveBeenCalled();
126
- });
127
-
128
- test('does not replace the active SDK disconnect observer', () => {
129
- const active = new WebUsbTransport();
130
- active.init({ debug: jest.fn() });
131
- const probe = new WebUsbTransport(true);
132
- probe.init({ debug: jest.fn() });
133
- const activeDisconnect = jest.spyOn(active, 'markProtocolStale');
134
- const probeDisconnect = jest.spyOn(probe, 'markProtocolStale');
135
- disconnectListener({ device });
136
- expect(activeDisconnect).toHaveBeenCalledWith('USB_PATH');
137
- expect(probeDisconnect).not.toHaveBeenCalled();
138
- });
139
-
140
- test.each(['release', 'acquire failure'])(
141
- 'keeps a probe handle protected after close fails during %s and recovers after cleanup',
142
- async phase => {
143
- Object.assign(device, {
144
- open: jest.fn(() => {
145
- device.opened = true;
146
- return Promise.resolve();
147
- }),
148
- releaseInterface: jest.fn().mockResolvedValue(undefined),
149
- reset: jest.fn(),
150
- configurations: [],
151
- configuration: { configurationValue: 1 },
152
- selectConfiguration: jest.fn(),
153
- claimInterface: jest.fn(),
154
- clearHalt: jest.fn(),
155
- });
156
- const probe = new WebUsbTransport(true);
157
- probe.init({ debug: jest.fn() });
158
- const internals = probe as unknown as {
159
- rotateProtocolV2UsbGeneration: () => Promise<void>;
160
- detectProtocol: () => Promise<'V1'>;
161
- };
162
- jest.spyOn(internals, 'rotateProtocolV2UsbGeneration').mockResolvedValue(undefined);
163
- jest.spyOn(internals, 'detectProtocol').mockResolvedValue('V1');
164
- jest.spyOn(probe, 'connect').mockImplementation(() => {
165
- device.opened = true;
166
- if (phase === 'acquire failure') return Promise.reject(new Error('probe failed'));
167
- return Promise.resolve();
168
- });
169
- const closeFailure = new Error('native close failed');
170
- device.close.mockRejectedValueOnce(closeFailure);
171
- if (phase === 'release') {
172
- await probe.acquire({ path: 'USB_PATH' });
173
- await expect(probe.release('USB_PATH')).rejects.toBe(closeFailure);
174
- } else {
175
- await expect(probe.acquire({ path: 'USB_PATH' })).rejects.toBe(closeFailure);
176
- }
177
- expect(device.opened).toBe(true);
178
- const active = new WebUsbTransport();
179
- active.init({ debug: jest.fn() });
180
- await expect(active.connectToDevice('USB_PATH', true)).rejects.toThrow(
181
- 'USB device is already in use'
182
- );
183
- expect(device.close).toHaveBeenCalledTimes(1);
184
-
185
- await probe.release('USB_PATH');
186
- expect(device.opened).toBe(false);
187
- await expect(active.connectToDevice('USB_PATH', true)).resolves.toBeUndefined();
188
- expect(device.opened).toBe(true);
189
- await active.release('USB_PATH');
190
- }
191
- );
192
-
193
- test.each(['release', 'acquire failure'])(
194
- 'the public probe retries failed %s cleanup on its next call',
195
- async phase => {
196
- const internals = WebUsbTransport.prototype as unknown as {
197
- rotateProtocolV2UsbGeneration: () => Promise<void>;
198
- detectProtocol: () => Promise<'V1'>;
199
- };
200
- jest.spyOn(internals, 'rotateProtocolV2UsbGeneration').mockResolvedValue(undefined);
201
- jest.spyOn(internals, 'detectProtocol').mockResolvedValue('V1');
202
- jest.spyOn(WebUsbTransport.prototype, 'getProtocolType').mockReturnValue('V1');
203
- jest.spyOn(WebUsbTransport.prototype, 'configure').mockImplementation(() => undefined);
204
- jest
205
- .spyOn(WebUsbTransport.prototype, 'configureProtocolV2')
206
- .mockImplementation(() => undefined);
207
- const connect = jest.spyOn(WebUsbTransport.prototype, 'connect').mockImplementation(() => {
208
- device.opened = true;
209
- return Promise.resolve();
210
- });
211
- if (phase === 'acquire failure') {
212
- connect.mockImplementationOnce(() => {
213
- device.opened = true;
214
- return Promise.reject(new Error('probe failed'));
215
- });
216
- }
217
- jest.spyOn(WebUsbTransport.prototype, 'call').mockResolvedValue({
218
- type: 'Features',
219
- message: { onekey_serial_no: 'PHYSICAL_SERIAL', onekey_device_type: 'CLASSIC1S' },
220
- });
221
- device.close.mockRejectedValueOnce(new Error('native close failed'));
222
- try {
223
- await expect(probeUsbDeviceIdentities({ commType: 'webusb' })).resolves.toEqual([]);
224
- expect(device.opened).toBe(true);
225
- const active = new WebUsbTransport();
226
- active.init({ debug: jest.fn() });
227
- await expect(active.connectToDevice('USB_PATH', true)).rejects.toThrow(
228
- 'USB device is already in use'
229
- );
230
- device.close.mockRejectedValueOnce(new Error('native close still failing'));
231
- await expect(probeUsbDeviceIdentities({ commType: 'webusb' })).resolves.toEqual([]);
232
- expect(device.opened).toBe(true);
233
- expect(connect).toHaveBeenCalledTimes(1);
234
- expect(device.close).toHaveBeenCalledTimes(2);
235
- await expect(probeUsbDeviceIdentities({ commType: 'webusb' })).resolves.toMatchObject([
236
- { path: 'USB_PATH', serialNo: 'PHYSICAL_SERIAL' },
237
- ]);
238
- expect(connect).toHaveBeenCalledTimes(2);
239
- expect(device.opened).toBe(false);
240
- } finally {
241
- jest.restoreAllMocks();
242
- }
243
- }
244
- );
245
-
246
- test.each([false, true])(
247
- 'uses a read-only V1 probe only for isolated discovery (%s)',
248
- async identityProbe => {
249
- const probe = new WebUsbTransport(identityProbe);
250
- const internals = probe as unknown as {
251
- messages: object;
252
- callProtocolV1: (
253
- path: string,
254
- name: string,
255
- data: object,
256
- options: TransportCallOptions
257
- ) => Promise<MessageFromOneKey>;
258
- probeProtocolV1: (path: string) => Promise<boolean>;
259
- };
260
- internals.messages = {};
261
- const call = jest
262
- .spyOn(internals, 'callProtocolV1')
263
- .mockResolvedValue({ type: 'Features', message: {} });
264
- await expect(internals.probeProtocolV1('USB_PATH')).resolves.toBe(true);
265
- expect(call.mock.calls[0][1]).toBe(identityProbe ? 'GetFeatures' : 'Initialize');
266
- }
267
- );
268
- });