@ledgerhq/device-transport-kit-react-native-hid 0.0.0-rn-ble-perf-20251009143619 → 0.0.0-rn-hid-issues-20251022142715
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.
|
@@ -22,6 +22,7 @@ import com.ledger.devicesdk.shared.internal.connection.InternalConnectedDevice
|
|
|
22
22
|
import com.ledger.devicesdk.shared.internal.connection.InternalConnectionResult
|
|
23
23
|
import com.ledger.devicesdk.shared.internal.event.SdkEventDispatcher
|
|
24
24
|
import com.ledger.devicesdk.shared.internal.service.logger.LoggerService
|
|
25
|
+
import com.ledger.devicesdk.shared.internal.service.logger.buildSimpleDebugLogInfo
|
|
25
26
|
import com.ledger.devicesdk.shared.internal.transport.TransportEvent
|
|
26
27
|
import kotlinx.coroutines.CoroutineScope
|
|
27
28
|
import kotlinx.coroutines.Dispatchers
|
|
@@ -34,6 +35,8 @@ import kotlin.random.Random
|
|
|
34
35
|
import kotlin.time.Duration
|
|
35
36
|
import kotlin.time.Duration.Companion.milliseconds
|
|
36
37
|
|
|
38
|
+
private val TAG = "TransportHidModule"
|
|
39
|
+
|
|
37
40
|
class TransportHidModule(
|
|
38
41
|
private val reactContext: ReactApplicationContext,
|
|
39
42
|
private val coroutineScope: CoroutineScope
|
|
@@ -133,12 +136,18 @@ class TransportHidModule(
|
|
|
133
136
|
transport?.stopScan()
|
|
134
137
|
}
|
|
135
138
|
|
|
136
|
-
private var
|
|
139
|
+
private var activeScanCount = 0
|
|
137
140
|
|
|
138
141
|
@ReactMethod
|
|
139
142
|
fun startScan(promise: Promise) {
|
|
140
|
-
|
|
141
|
-
|
|
143
|
+
loggerService.log(
|
|
144
|
+
buildSimpleDebugLogInfo(TAG, "[startScan] called")
|
|
145
|
+
)
|
|
146
|
+
activeScanCount += 1
|
|
147
|
+
if (activeScanCount > 1) {
|
|
148
|
+
loggerService.log(
|
|
149
|
+
buildSimpleDebugLogInfo(TAG, "[startScan] already scanning")
|
|
150
|
+
)
|
|
142
151
|
promise.resolve(null)
|
|
143
152
|
return
|
|
144
153
|
}
|
|
@@ -156,16 +165,34 @@ class TransportHidModule(
|
|
|
156
165
|
|
|
157
166
|
@ReactMethod
|
|
158
167
|
fun stopScan(promise: Promise) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
168
|
+
loggerService.log(
|
|
169
|
+
buildSimpleDebugLogInfo(TAG, "[stopScan] called, activeScanCount=$activeScanCount")
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
when(activeScanCount) {
|
|
173
|
+
0 -> {
|
|
174
|
+
loggerService.log(buildSimpleDebugLogInfo(TAG, "[stopScan] no active scan"))
|
|
175
|
+
promise.resolve(null)
|
|
176
|
+
}
|
|
177
|
+
1 -> {
|
|
178
|
+
try {
|
|
179
|
+
transport!!.stopScan()
|
|
180
|
+
promise.resolve(null)
|
|
181
|
+
} catch (e: Exception) {
|
|
182
|
+
promise.reject(e);
|
|
183
|
+
}
|
|
184
|
+
activeScanCount = 0
|
|
185
|
+
}
|
|
186
|
+
else -> {
|
|
187
|
+
loggerService.log(
|
|
188
|
+
buildSimpleDebugLogInfo(
|
|
189
|
+
TAG,
|
|
190
|
+
"[stopScan] still scanning because there are active listeners"
|
|
191
|
+
)
|
|
192
|
+
)
|
|
193
|
+
activeScanCount -= 1
|
|
194
|
+
promise.resolve(null)
|
|
195
|
+
}
|
|
169
196
|
}
|
|
170
197
|
}
|
|
171
198
|
|
|
@@ -45,6 +45,8 @@ import kotlinx.coroutines.launch
|
|
|
45
45
|
import kotlin.time.Duration
|
|
46
46
|
import kotlin.time.Duration.Companion.seconds
|
|
47
47
|
|
|
48
|
+
private val TAG = "DefaultAndroidUsbTransport"
|
|
49
|
+
|
|
48
50
|
internal class DefaultAndroidUsbTransport(
|
|
49
51
|
private val application: Application,
|
|
50
52
|
private val usbManager: UsbManager,
|
|
@@ -67,22 +69,16 @@ internal class DefaultAndroidUsbTransport(
|
|
|
67
69
|
private var discoveryJob: Job? = null
|
|
68
70
|
|
|
69
71
|
override fun startScan(): Flow<List<DiscoveryDevice>> {
|
|
72
|
+
loggerService.log(buildSimpleDebugLogInfo(TAG, "[startScan] called"))
|
|
70
73
|
val scanStateFlow = MutableStateFlow<List<DiscoveryDevice>>(emptyList())
|
|
71
74
|
discoveryJob?.cancel()
|
|
72
75
|
discoveryJob =
|
|
73
76
|
scope.launch {
|
|
74
77
|
while (isActive) {
|
|
75
|
-
|
|
76
|
-
val
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
usbConnections.filter {
|
|
80
|
-
device == it.value.getApduSender().dependencies.usbDevice
|
|
81
|
-
}.isEmpty()
|
|
82
|
-
}.toUsbDevices()
|
|
83
|
-
|
|
84
|
-
scanStateFlow.value = devices.toScannedDevices()
|
|
85
|
-
|
|
78
|
+
loggerService.log(buildSimpleDebugLogInfo(TAG, "[startScan] isActive loop"))
|
|
79
|
+
val usbDevices = usbManager.deviceList.values.toList().toUsbDevices()
|
|
80
|
+
scanStateFlow.value = usbDevices.toScannedDevices()
|
|
81
|
+
loggerService.log(buildSimpleDebugLogInfo(TAG, "[startScan] scannedDevices=${scanStateFlow.value}"))
|
|
86
82
|
delay(scanDelay)
|
|
87
83
|
}
|
|
88
84
|
}
|
|
@@ -90,6 +86,7 @@ internal class DefaultAndroidUsbTransport(
|
|
|
90
86
|
}
|
|
91
87
|
|
|
92
88
|
override fun stopScan() {
|
|
89
|
+
loggerService.log(buildSimpleDebugLogInfo(TAG, "[stopScan] called"))
|
|
93
90
|
discoveryJob?.cancel()
|
|
94
91
|
discoveryJob = null
|
|
95
92
|
}
|
|
@@ -294,6 +291,27 @@ internal class DefaultAndroidUsbTransport(
|
|
|
294
291
|
return if (usbDevice == null || ledgerUsbDevice == null) {
|
|
295
292
|
InternalConnectionResult.ConnectionError(error = InternalConnectionResult.Failure.DeviceNotFound)
|
|
296
293
|
} else {
|
|
294
|
+
|
|
295
|
+
val existingConnection = usbConnections.firstNotNullOfOrNull {
|
|
296
|
+
if (it.value.getApduSender().dependencies.usbDevice == usbDevice) it.value
|
|
297
|
+
else if (it.key == generateSessionId(usbDevice)) it.value
|
|
298
|
+
else null
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (existingConnection != null) {
|
|
302
|
+
val connectedDevice =
|
|
303
|
+
InternalConnectedDevice(
|
|
304
|
+
existingConnection.sessionId,
|
|
305
|
+
discoveryDevice.name,
|
|
306
|
+
discoveryDevice.ledgerDevice,
|
|
307
|
+
discoveryDevice.connectivityType,
|
|
308
|
+
sendApduFn = { apdu: ByteArray, triggersDisconnection: Boolean, abortTimeoutDuration: Duration ->
|
|
309
|
+
existingConnection.requestSendApdu(apdu, triggersDisconnection, abortTimeoutDuration)
|
|
310
|
+
}
|
|
311
|
+
)
|
|
312
|
+
return InternalConnectionResult.Connected(device = connectedDevice, sessionId = existingConnection.sessionId)
|
|
313
|
+
}
|
|
314
|
+
|
|
297
315
|
val permissionResult = checkOrRequestPermission(usbDevice)
|
|
298
316
|
if (permissionResult is PermissionResult.Denied) {
|
|
299
317
|
return permissionResult.connectionError
|