@onekeyfe/react-native-ble-utils 0.1.8 → 0.1.9

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.
@@ -29,9 +29,12 @@ class BleUtilsModule(private val reactContext: ReactApplicationContext) :
29
29
 
30
30
  override fun getName() = NAME
31
31
 
32
- // Lets JS skip waiting for an event this OS version never broadcasts.
32
+ // Lets JS skip waiting for events this OS version never broadcasts.
33
33
  override fun getConstants(): MutableMap<String, Any> =
34
- hashMapOf("supportsKeyMissingEvent" to supportsKeyMissingEvent())
34
+ hashMapOf(
35
+ "supportsKeyMissingEvent" to supportsKeyMissingEvent(),
36
+ "supportsEncryptionChangeEvent" to supportsEncryptionChangeEvent()
37
+ )
35
38
 
36
39
  private fun getBluetoothManager(): BluetoothManager? {
37
40
  if (bluetoothManager == null) {
@@ -60,6 +63,11 @@ class BleUtilsModule(private val reactContext: ReactApplicationContext) :
60
63
  if (supportsKeyMissingEvent()) {
61
64
  filter.addAction(ACTION_KEY_MISSING)
62
65
  }
66
+ if (supportsEncryptionChangeEvent()) {
67
+ filter.addAction(ACTION_ENCRYPTION_CHANGE)
68
+ // Tells JS when an earlier encryption result stops describing the current link.
69
+ filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED)
70
+ }
63
71
  val intentFilter = IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST)
64
72
  intentFilter.priority = IntentFilter.SYSTEM_HIGH_PRIORITY
65
73
  if (Build.VERSION.SDK_INT >= 34) {
@@ -91,6 +99,18 @@ class BleUtilsModule(private val reactContext: ReactApplicationContext) :
91
99
  .emit("onDeviceKeyMissing", params)
92
100
  }
93
101
 
102
+ fun emitOnDeviceEncryptionChange(params: WritableMap) {
103
+ reactContext
104
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
105
+ .emit("onDeviceEncryptionChange", params)
106
+ }
107
+
108
+ fun emitOnDeviceAclDisconnected(params: WritableMap) {
109
+ reactContext
110
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
111
+ .emit("onDeviceAclDisconnected", params)
112
+ }
113
+
94
114
  // 事件监听管理
95
115
  @ReactMethod
96
116
  fun addListener(eventName: String) {
@@ -292,20 +312,45 @@ class BleUtilsModule(private val reactContext: ReactApplicationContext) :
292
312
  Log.d(LOG_TAG, "onReceive BluetoothDevice BondState Change ${map}")
293
313
  module.emitOnDeviceBondState(map)
294
314
  } else if (action == ACTION_KEY_MISSING) {
295
- val device: BluetoothDevice? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
296
- intent.getParcelableExtra(
297
- BluetoothDevice.EXTRA_DEVICE, BluetoothDevice::class.java
298
- )
299
- } else {
300
- intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
301
- }
302
- if (device == null) return
315
+ val device = deviceExtra(intent) ?: return
303
316
 
304
317
  val map = Arguments.createMap()
305
318
  map.putString("id", device.address)
306
319
  Log.d(LOG_TAG, "onReceive BluetoothDevice KeyMissing")
307
320
  module.emitOnDeviceKeyMissing(map)
321
+ } else if (action == ACTION_ENCRYPTION_CHANGE) {
322
+ val device = deviceExtra(intent) ?: return
323
+ if (!isLeTransport(intent)) return
324
+
325
+ val map = Arguments.createMap()
326
+ map.putString("id", device.address)
327
+ // HCI status: 0 on success, 6 (PIN or key missing) when the peer lost the bond.
328
+ map.putInt("status", intent.getIntExtra(EXTRA_ENCRYPTION_STATUS, BluetoothDevice.ERROR))
329
+ map.putBoolean("enabled", intent.getBooleanExtra(EXTRA_ENCRYPTION_ENABLED, false))
330
+ Log.d(LOG_TAG, "onReceive BluetoothDevice EncryptionChange ${map}")
331
+ module.emitOnDeviceEncryptionChange(map)
332
+ } else if (action == BluetoothDevice.ACTION_ACL_DISCONNECTED) {
333
+ val device = deviceExtra(intent) ?: return
334
+ if (!isLeTransport(intent)) return
335
+
336
+ val map = Arguments.createMap()
337
+ map.putString("id", device.address)
338
+ Log.d(LOG_TAG, "onReceive BluetoothDevice AclDisconnected")
339
+ module.emitOnDeviceAclDisconnected(map)
340
+ }
341
+ }
342
+
343
+ private fun deviceExtra(intent: Intent): BluetoothDevice? =
344
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
345
+ intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, BluetoothDevice::class.java)
346
+ } else {
347
+ intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
308
348
  }
349
+
350
+ // A dual-mode peer reports BR/EDR events too; only the LE link carries GATT.
351
+ private fun isLeTransport(intent: Intent): Boolean {
352
+ if (!intent.hasExtra(EXTRA_TRANSPORT)) return true
353
+ return intent.getIntExtra(EXTRA_TRANSPORT, TRANSPORT_LE) == TRANSPORT_LE
309
354
  }
310
355
  }
311
356
 
@@ -313,11 +358,20 @@ class BleUtilsModule(private val reactContext: ReactApplicationContext) :
313
358
  const val NAME = "BleUtilsModule"
314
359
  const val LOG_TAG: String = "RNBleUtils"
315
360
 
316
- // BluetoothDevice.ACTION_KEY_MISSING is public from API 36. The literal keeps this
361
+ // These BluetoothDevice constants are public from API 36. The literals keep this
317
362
  // module building against older compileSdk versions.
318
363
  const val ACTION_KEY_MISSING = "android.bluetooth.device.action.KEY_MISSING"
319
- private const val KEY_MISSING_MIN_SDK = 36
320
-
321
- fun supportsKeyMissingEvent(): Boolean = Build.VERSION.SDK_INT >= KEY_MISSING_MIN_SDK
364
+ const val ACTION_ENCRYPTION_CHANGE = "android.bluetooth.device.action.ENCRYPTION_CHANGE"
365
+ private const val EXTRA_ENCRYPTION_STATUS = "android.bluetooth.device.extra.ENCRYPTION_STATUS"
366
+ private const val EXTRA_ENCRYPTION_ENABLED = "android.bluetooth.device.extra.ENCRYPTION_ENABLED"
367
+ // BluetoothDevice.EXTRA_TRANSPORT and TRANSPORT_LE, public from API 33 and 23.
368
+ private const val EXTRA_TRANSPORT = "android.bluetooth.device.extra.TRANSPORT"
369
+ private const val TRANSPORT_LE = 2
370
+ private const val LINK_SECURITY_EVENTS_MIN_SDK = 36
371
+
372
+ fun supportsKeyMissingEvent(): Boolean = Build.VERSION.SDK_INT >= LINK_SECURITY_EVENTS_MIN_SDK
373
+
374
+ fun supportsEncryptionChangeEvent(): Boolean =
375
+ Build.VERSION.SDK_INT >= LINK_SECURITY_EVENTS_MIN_SDK
322
376
  }
323
377
  }
@@ -8,12 +8,12 @@ var _reactNative = require("react-native");
8
8
  const {
9
9
  BleUtilsModule
10
10
  } = _reactNative.NativeModules;
11
- const readSupportsKeyMissingEvent = () => {
11
+ const readNativeFlag = name => {
12
12
  if (_reactNative.Platform.OS !== 'android' || !BleUtilsModule) return false;
13
13
  // Interop exposes legacy constants through getConstants(); the bridge exposes them
14
14
  // as plain properties.
15
15
  const constants = typeof BleUtilsModule.getConstants === 'function' ? BleUtilsModule.getConstants() : BleUtilsModule;
16
- return constants?.supportsKeyMissingEvent === true;
16
+ return constants?.[name] === true;
17
17
  };
18
18
  class BleUtils {
19
19
  UiEventEmitter = null;
@@ -119,7 +119,7 @@ class BleUtils {
119
119
  * the event never fires, so callers should not wait for it.
120
120
  */
121
121
  supportsDeviceKeyMissing() {
122
- return readSupportsKeyMissingEvent();
122
+ return readNativeFlag('supportsKeyMissingEvent');
123
123
  }
124
124
 
125
125
  /**
@@ -136,6 +136,44 @@ class BleUtils {
136
136
  subscription?.remove();
137
137
  };
138
138
  }
139
+
140
+ /**
141
+ * [Android only]
142
+ * Whether this OS version and native build report `onDeviceEncryptionChange` and
143
+ * `onDeviceAclDisconnected`. When false those events never fire.
144
+ */
145
+ supportsDeviceEncryptionChange() {
146
+ return readNativeFlag('supportsEncryptionChangeEvent');
147
+ }
148
+
149
+ /**
150
+ * [Android 16+ only]
151
+ * The LE link to a device finished an encryption attempt. Android starts it on its own
152
+ * right after connecting to a bonded device, so this reports whether the stored bond
153
+ * still works before any request that needs encryption is sent.
154
+ * Each subscription is removed on its own, so several callers can listen at once.
155
+ * @param callback
156
+ */
157
+ onDeviceEncryptionChange(callback) {
158
+ const subscription = this.UiEventEmitter?.addListener('onDeviceEncryptionChange', callback);
159
+ return () => {
160
+ subscription?.remove();
161
+ };
162
+ }
163
+
164
+ /**
165
+ * [Android 16+ only]
166
+ * The LE link to a device is gone, so earlier encryption results no longer apply.
167
+ * Unlike a GATT disconnect, this does not fire while the system keeps the link alive
168
+ * for another client.
169
+ * @param callback
170
+ */
171
+ onDeviceAclDisconnected(callback) {
172
+ const subscription = this.UiEventEmitter?.addListener('onDeviceAclDisconnected', callback);
173
+ return () => {
174
+ subscription?.remove();
175
+ };
176
+ }
139
177
  }
140
178
  var _default = exports.default = new BleUtils();
141
179
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","BleUtilsModule","NativeModules","readSupportsKeyMissingEvent","Platform","OS","constants","getConstants","supportsKeyMissingEvent","BleUtils","UiEventEmitter","constructor","NativeEventEmitter","checkState","Promise","fulfill","_","state","pairDevice","macAddress","resolve","bonded","bonding","reject","error","result","getConnectedPeripherals","serviceUUIDs","getBondedPeripherals","onDeviceBondState","callback","addListener","removeAllListeners","supportsDeviceKeyMissing","onDeviceKeyMissing","subscription","remove","_default","exports","default"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","BleUtilsModule","NativeModules","readNativeFlag","name","Platform","OS","constants","getConstants","BleUtils","UiEventEmitter","constructor","NativeEventEmitter","checkState","Promise","fulfill","_","state","pairDevice","macAddress","resolve","bonded","bonding","reject","error","result","getConnectedPeripherals","serviceUUIDs","getBondedPeripherals","onDeviceBondState","callback","addListener","removeAllListeners","supportsDeviceKeyMissing","onDeviceKeyMissing","subscription","remove","supportsDeviceEncryptionChange","onDeviceEncryptionChange","onDeviceAclDisconnected","_default","exports","default"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}
@@ -4,12 +4,12 @@ import { NativeEventEmitter, NativeModules, Platform } from 'react-native';
4
4
  const {
5
5
  BleUtilsModule
6
6
  } = NativeModules;
7
- const readSupportsKeyMissingEvent = () => {
7
+ const readNativeFlag = name => {
8
8
  if (Platform.OS !== 'android' || !BleUtilsModule) return false;
9
9
  // Interop exposes legacy constants through getConstants(); the bridge exposes them
10
10
  // as plain properties.
11
11
  const constants = typeof BleUtilsModule.getConstants === 'function' ? BleUtilsModule.getConstants() : BleUtilsModule;
12
- return constants?.supportsKeyMissingEvent === true;
12
+ return constants?.[name] === true;
13
13
  };
14
14
  class BleUtils {
15
15
  UiEventEmitter = null;
@@ -115,7 +115,7 @@ class BleUtils {
115
115
  * the event never fires, so callers should not wait for it.
116
116
  */
117
117
  supportsDeviceKeyMissing() {
118
- return readSupportsKeyMissingEvent();
118
+ return readNativeFlag('supportsKeyMissingEvent');
119
119
  }
120
120
 
121
121
  /**
@@ -132,6 +132,44 @@ class BleUtils {
132
132
  subscription?.remove();
133
133
  };
134
134
  }
135
+
136
+ /**
137
+ * [Android only]
138
+ * Whether this OS version and native build report `onDeviceEncryptionChange` and
139
+ * `onDeviceAclDisconnected`. When false those events never fire.
140
+ */
141
+ supportsDeviceEncryptionChange() {
142
+ return readNativeFlag('supportsEncryptionChangeEvent');
143
+ }
144
+
145
+ /**
146
+ * [Android 16+ only]
147
+ * The LE link to a device finished an encryption attempt. Android starts it on its own
148
+ * right after connecting to a bonded device, so this reports whether the stored bond
149
+ * still works before any request that needs encryption is sent.
150
+ * Each subscription is removed on its own, so several callers can listen at once.
151
+ * @param callback
152
+ */
153
+ onDeviceEncryptionChange(callback) {
154
+ const subscription = this.UiEventEmitter?.addListener('onDeviceEncryptionChange', callback);
155
+ return () => {
156
+ subscription?.remove();
157
+ };
158
+ }
159
+
160
+ /**
161
+ * [Android 16+ only]
162
+ * The LE link to a device is gone, so earlier encryption results no longer apply.
163
+ * Unlike a GATT disconnect, this does not fire while the system keeps the link alive
164
+ * for another client.
165
+ * @param callback
166
+ */
167
+ onDeviceAclDisconnected(callback) {
168
+ const subscription = this.UiEventEmitter?.addListener('onDeviceAclDisconnected', callback);
169
+ return () => {
170
+ subscription?.remove();
171
+ };
172
+ }
135
173
  }
136
174
  export default new BleUtils();
137
175
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["NativeEventEmitter","NativeModules","Platform","BleUtilsModule","readSupportsKeyMissingEvent","OS","constants","getConstants","supportsKeyMissingEvent","BleUtils","UiEventEmitter","constructor","checkState","Promise","fulfill","_","state","pairDevice","macAddress","resolve","bonded","bonding","reject","error","result","getConnectedPeripherals","serviceUUIDs","getBondedPeripherals","onDeviceBondState","callback","addListener","removeAllListeners","supportsDeviceKeyMissing","onDeviceKeyMissing","subscription","remove"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["NativeEventEmitter","NativeModules","Platform","BleUtilsModule","readNativeFlag","name","OS","constants","getConstants","BleUtils","UiEventEmitter","constructor","checkState","Promise","fulfill","_","state","pairDevice","macAddress","resolve","bonded","bonding","reject","error","result","getConnectedPeripherals","serviceUUIDs","getBondedPeripherals","onDeviceBondState","callback","addListener","removeAllListeners","supportsDeviceKeyMissing","onDeviceKeyMissing","subscription","remove","supportsDeviceEncryptionChange","onDeviceEncryptionChange","onDeviceAclDisconnected"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}
@@ -1,5 +1,5 @@
1
1
  import { NativeEventEmitter } from 'react-native';
2
- import type { BleState, Peripheral, BondState, AdvertisingData, KeyMissingPeripheral } from './type';
2
+ import type { BleState, Peripheral, BondState, AdvertisingData, KeyMissingPeripheral, EncryptionChangePeripheral, AclDisconnectedPeripheral } from './type';
3
3
  type PairDeviceResult = {
4
4
  bonded: boolean;
5
5
  bonding: boolean;
@@ -54,8 +54,31 @@ declare class BleUtils {
54
54
  * @param callback
55
55
  */
56
56
  onDeviceKeyMissing(callback: (peripheral: KeyMissingPeripheral) => void): () => void;
57
+ /**
58
+ * [Android only]
59
+ * Whether this OS version and native build report `onDeviceEncryptionChange` and
60
+ * `onDeviceAclDisconnected`. When false those events never fire.
61
+ */
62
+ supportsDeviceEncryptionChange(): boolean;
63
+ /**
64
+ * [Android 16+ only]
65
+ * The LE link to a device finished an encryption attempt. Android starts it on its own
66
+ * right after connecting to a bonded device, so this reports whether the stored bond
67
+ * still works before any request that needs encryption is sent.
68
+ * Each subscription is removed on its own, so several callers can listen at once.
69
+ * @param callback
70
+ */
71
+ onDeviceEncryptionChange(callback: (peripheral: EncryptionChangePeripheral) => void): () => void;
72
+ /**
73
+ * [Android 16+ only]
74
+ * The LE link to a device is gone, so earlier encryption results no longer apply.
75
+ * Unlike a GATT disconnect, this does not fire while the system keeps the link alive
76
+ * for another client.
77
+ * @param callback
78
+ */
79
+ onDeviceAclDisconnected(callback: (peripheral: AclDisconnectedPeripheral) => void): () => void;
57
80
  }
58
81
  declare const _default: BleUtils;
59
82
  export default _default;
60
- export type { BleState, Peripheral, BondState, AdvertisingData, KeyMissingPeripheral, PairDeviceResult, };
83
+ export type { BleState, Peripheral, BondState, AdvertisingData, KeyMissingPeripheral, EncryptionChangePeripheral, AclDisconnectedPeripheral, PairDeviceResult, };
61
84
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA2B,MAAM,cAAc,CAAC;AAC3E,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,oBAAoB,EACrB,MAAM,QAAQ,CAAC;AAGhB,KAAK,gBAAgB,GAAG;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAaF,cAAM,QAAQ;IACZ,cAAc,EAAE,kBAAkB,GAAG,IAAI,CAAQ;;IAOjD,UAAU;IAQV;;;;OAIG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA2BzD;;;;OAIG;IACH,uBAAuB,CAAC,YAAY,GAAE,MAAM,EAAO;IAmBnD;;;OAGG;IACH,oBAAoB;IAkBpB;;;;;;OAMG;IACH,iBAAiB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI;IAQ5D;;;;OAIG;IACH,wBAAwB;IAIxB;;;;;;;OAOG;IACH,kBAAkB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,oBAAoB,KAAK,IAAI;CASxE;;AAED,wBAA8B;AAC9B,YAAY,EACV,QAAQ,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,gBAAgB,GACjB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA2B,MAAM,cAAc,CAAC;AAC3E,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,QAAQ,CAAC;AAGhB,KAAK,gBAAgB,GAAG;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAiBF,cAAM,QAAQ;IACZ,cAAc,EAAE,kBAAkB,GAAG,IAAI,CAAQ;;IAOjD,UAAU;IAQV;;;;OAIG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA2BzD;;;;OAIG;IACH,uBAAuB,CAAC,YAAY,GAAE,MAAM,EAAO;IAmBnD;;;OAGG;IACH,oBAAoB;IAkBpB;;;;;;OAMG;IACH,iBAAiB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI;IAQ5D;;;;OAIG;IACH,wBAAwB;IAIxB;;;;;;;OAOG;IACH,kBAAkB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,oBAAoB,KAAK,IAAI;IAUvE;;;;OAIG;IACH,8BAA8B;IAI9B;;;;;;;OAOG;IACH,wBAAwB,CACtB,QAAQ,EAAE,CAAC,UAAU,EAAE,0BAA0B,KAAK,IAAI;IAW5D;;;;;;OAMG;IACH,uBAAuB,CACrB,QAAQ,EAAE,CAAC,UAAU,EAAE,yBAAyB,KAAK,IAAI;CAU5D;;AAED,wBAA8B;AAC9B,YAAY,EACV,QAAQ,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,gBAAgB,GACjB,CAAC"}
@@ -44,6 +44,18 @@ export interface KeyMissingPeripheral {
44
44
  /** Device MAC address. */
45
45
  id: string;
46
46
  }
47
+ export interface EncryptionChangePeripheral {
48
+ /** Device MAC address. */
49
+ id: string;
50
+ /** HCI status of the encryption procedure: 0 on success, 6 when the peer lost the bond. */
51
+ status: number;
52
+ /** Whether the LE link is encrypted after the change. */
53
+ enabled: boolean;
54
+ }
55
+ export interface AclDisconnectedPeripheral {
56
+ /** Device MAC address. */
57
+ id: string;
58
+ }
47
59
  export interface AdvertisingData {
48
60
  isConnectable?: boolean;
49
61
  localName?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../../src/type.ts"],"names":[],"mappings":"AAAA;;;KAGK;AACL,oBAAY,QAAQ;IAClB;;OAEG;IACH,OAAO,YAAY;IACnB;;OAEG;IACH,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B;;OAEG;IACH,YAAY,iBAAiB;IAC7B,EAAE,OAAO;IACT,GAAG,QAAQ;IACX;;OAEG;IACH,SAAS,eAAe;IACxB;;OAEG;IACH,UAAU,gBAAgB;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
1
+ {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../../src/type.ts"],"names":[],"mappings":"AAAA;;;KAGK;AACL,oBAAY,QAAQ;IAClB;;OAEG;IACH,OAAO,YAAY;IACnB;;OAEG;IACH,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B;;OAEG;IACH,YAAY,iBAAiB;IAC7B,EAAE,OAAO;IACT,GAAG,QAAQ;IACX;;OAEG;IACH,SAAS,eAAe;IACxB;;OAEG;IACH,UAAU,gBAAgB;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,0BAA0B;IACzC,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,2FAA2F;IAC3F,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB;IACxC,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
@@ -1,5 +1,5 @@
1
1
  import { NativeEventEmitter } from 'react-native';
2
- import type { BleState, Peripheral, BondState, AdvertisingData, KeyMissingPeripheral } from './type';
2
+ import type { BleState, Peripheral, BondState, AdvertisingData, KeyMissingPeripheral, EncryptionChangePeripheral, AclDisconnectedPeripheral } from './type';
3
3
  type PairDeviceResult = {
4
4
  bonded: boolean;
5
5
  bonding: boolean;
@@ -54,8 +54,31 @@ declare class BleUtils {
54
54
  * @param callback
55
55
  */
56
56
  onDeviceKeyMissing(callback: (peripheral: KeyMissingPeripheral) => void): () => void;
57
+ /**
58
+ * [Android only]
59
+ * Whether this OS version and native build report `onDeviceEncryptionChange` and
60
+ * `onDeviceAclDisconnected`. When false those events never fire.
61
+ */
62
+ supportsDeviceEncryptionChange(): boolean;
63
+ /**
64
+ * [Android 16+ only]
65
+ * The LE link to a device finished an encryption attempt. Android starts it on its own
66
+ * right after connecting to a bonded device, so this reports whether the stored bond
67
+ * still works before any request that needs encryption is sent.
68
+ * Each subscription is removed on its own, so several callers can listen at once.
69
+ * @param callback
70
+ */
71
+ onDeviceEncryptionChange(callback: (peripheral: EncryptionChangePeripheral) => void): () => void;
72
+ /**
73
+ * [Android 16+ only]
74
+ * The LE link to a device is gone, so earlier encryption results no longer apply.
75
+ * Unlike a GATT disconnect, this does not fire while the system keeps the link alive
76
+ * for another client.
77
+ * @param callback
78
+ */
79
+ onDeviceAclDisconnected(callback: (peripheral: AclDisconnectedPeripheral) => void): () => void;
57
80
  }
58
81
  declare const _default: BleUtils;
59
82
  export default _default;
60
- export type { BleState, Peripheral, BondState, AdvertisingData, KeyMissingPeripheral, PairDeviceResult, };
83
+ export type { BleState, Peripheral, BondState, AdvertisingData, KeyMissingPeripheral, EncryptionChangePeripheral, AclDisconnectedPeripheral, PairDeviceResult, };
61
84
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA2B,MAAM,cAAc,CAAC;AAC3E,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,oBAAoB,EACrB,MAAM,QAAQ,CAAC;AAGhB,KAAK,gBAAgB,GAAG;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAaF,cAAM,QAAQ;IACZ,cAAc,EAAE,kBAAkB,GAAG,IAAI,CAAQ;;IAOjD,UAAU;IAQV;;;;OAIG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA2BzD;;;;OAIG;IACH,uBAAuB,CAAC,YAAY,GAAE,MAAM,EAAO;IAmBnD;;;OAGG;IACH,oBAAoB;IAkBpB;;;;;;OAMG;IACH,iBAAiB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI;IAQ5D;;;;OAIG;IACH,wBAAwB;IAIxB;;;;;;;OAOG;IACH,kBAAkB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,oBAAoB,KAAK,IAAI;CASxE;;AAED,wBAA8B;AAC9B,YAAY,EACV,QAAQ,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,gBAAgB,GACjB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA2B,MAAM,cAAc,CAAC;AAC3E,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,QAAQ,CAAC;AAGhB,KAAK,gBAAgB,GAAG;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAiBF,cAAM,QAAQ;IACZ,cAAc,EAAE,kBAAkB,GAAG,IAAI,CAAQ;;IAOjD,UAAU;IAQV;;;;OAIG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA2BzD;;;;OAIG;IACH,uBAAuB,CAAC,YAAY,GAAE,MAAM,EAAO;IAmBnD;;;OAGG;IACH,oBAAoB;IAkBpB;;;;;;OAMG;IACH,iBAAiB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI;IAQ5D;;;;OAIG;IACH,wBAAwB;IAIxB;;;;;;;OAOG;IACH,kBAAkB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,oBAAoB,KAAK,IAAI;IAUvE;;;;OAIG;IACH,8BAA8B;IAI9B;;;;;;;OAOG;IACH,wBAAwB,CACtB,QAAQ,EAAE,CAAC,UAAU,EAAE,0BAA0B,KAAK,IAAI;IAW5D;;;;;;OAMG;IACH,uBAAuB,CACrB,QAAQ,EAAE,CAAC,UAAU,EAAE,yBAAyB,KAAK,IAAI;CAU5D;;AAED,wBAA8B;AAC9B,YAAY,EACV,QAAQ,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,gBAAgB,GACjB,CAAC"}
@@ -44,6 +44,18 @@ export interface KeyMissingPeripheral {
44
44
  /** Device MAC address. */
45
45
  id: string;
46
46
  }
47
+ export interface EncryptionChangePeripheral {
48
+ /** Device MAC address. */
49
+ id: string;
50
+ /** HCI status of the encryption procedure: 0 on success, 6 when the peer lost the bond. */
51
+ status: number;
52
+ /** Whether the LE link is encrypted after the change. */
53
+ enabled: boolean;
54
+ }
55
+ export interface AclDisconnectedPeripheral {
56
+ /** Device MAC address. */
57
+ id: string;
58
+ }
47
59
  export interface AdvertisingData {
48
60
  isConnectable?: boolean;
49
61
  localName?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../../src/type.ts"],"names":[],"mappings":"AAAA;;;KAGK;AACL,oBAAY,QAAQ;IAClB;;OAEG;IACH,OAAO,YAAY;IACnB;;OAEG;IACH,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B;;OAEG;IACH,YAAY,iBAAiB;IAC7B,EAAE,OAAO;IACT,GAAG,QAAQ;IACX;;OAEG;IACH,SAAS,eAAe;IACxB;;OAEG;IACH,UAAU,gBAAgB;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
1
+ {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../../src/type.ts"],"names":[],"mappings":"AAAA;;;KAGK;AACL,oBAAY,QAAQ;IAClB;;OAEG;IACH,OAAO,YAAY;IACnB;;OAEG;IACH,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B;;OAEG;IACH,YAAY,iBAAiB;IAC7B,EAAE,OAAO;IACT,GAAG,QAAQ;IACX;;OAEG;IACH,SAAS,eAAe;IACxB;;OAEG;IACH,UAAU,gBAAgB;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,0BAA0B;IACzC,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,2FAA2F;IAC3F,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB;IACxC,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/react-native-ble-utils",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "ble uilts",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./dist/commonjs/index.js",
package/src/index.ts CHANGED
@@ -5,6 +5,8 @@ import type {
5
5
  BondState,
6
6
  AdvertisingData,
7
7
  KeyMissingPeripheral,
8
+ EncryptionChangePeripheral,
9
+ AclDisconnectedPeripheral,
8
10
  } from './type';
9
11
 
10
12
  const { BleUtilsModule } = NativeModules;
@@ -19,7 +21,11 @@ type PairDeviceResult = {
19
21
  initiated?: boolean;
20
22
  };
21
23
 
22
- const readSupportsKeyMissingEvent = (): boolean => {
24
+ type NativeConstantName =
25
+ | 'supportsKeyMissingEvent'
26
+ | 'supportsEncryptionChangeEvent';
27
+
28
+ const readNativeFlag = (name: NativeConstantName): boolean => {
23
29
  if (Platform.OS !== 'android' || !BleUtilsModule) return false;
24
30
  // Interop exposes legacy constants through getConstants(); the bridge exposes them
25
31
  // as plain properties.
@@ -27,7 +33,7 @@ const readSupportsKeyMissingEvent = (): boolean => {
27
33
  typeof BleUtilsModule.getConstants === 'function'
28
34
  ? BleUtilsModule.getConstants()
29
35
  : BleUtilsModule;
30
- return constants?.supportsKeyMissingEvent === true;
36
+ return constants?.[name] === true;
31
37
  };
32
38
 
33
39
  class BleUtils {
@@ -145,7 +151,7 @@ class BleUtils {
145
151
  * the event never fires, so callers should not wait for it.
146
152
  */
147
153
  supportsDeviceKeyMissing() {
148
- return readSupportsKeyMissingEvent();
154
+ return readNativeFlag('supportsKeyMissingEvent');
149
155
  }
150
156
 
151
157
  /**
@@ -165,6 +171,54 @@ class BleUtils {
165
171
  subscription?.remove();
166
172
  };
167
173
  }
174
+
175
+ /**
176
+ * [Android only]
177
+ * Whether this OS version and native build report `onDeviceEncryptionChange` and
178
+ * `onDeviceAclDisconnected`. When false those events never fire.
179
+ */
180
+ supportsDeviceEncryptionChange() {
181
+ return readNativeFlag('supportsEncryptionChangeEvent');
182
+ }
183
+
184
+ /**
185
+ * [Android 16+ only]
186
+ * The LE link to a device finished an encryption attempt. Android starts it on its own
187
+ * right after connecting to a bonded device, so this reports whether the stored bond
188
+ * still works before any request that needs encryption is sent.
189
+ * Each subscription is removed on its own, so several callers can listen at once.
190
+ * @param callback
191
+ */
192
+ onDeviceEncryptionChange(
193
+ callback: (peripheral: EncryptionChangePeripheral) => void
194
+ ) {
195
+ const subscription = this.UiEventEmitter?.addListener(
196
+ 'onDeviceEncryptionChange',
197
+ callback
198
+ );
199
+ return () => {
200
+ subscription?.remove();
201
+ };
202
+ }
203
+
204
+ /**
205
+ * [Android 16+ only]
206
+ * The LE link to a device is gone, so earlier encryption results no longer apply.
207
+ * Unlike a GATT disconnect, this does not fire while the system keeps the link alive
208
+ * for another client.
209
+ * @param callback
210
+ */
211
+ onDeviceAclDisconnected(
212
+ callback: (peripheral: AclDisconnectedPeripheral) => void
213
+ ) {
214
+ const subscription = this.UiEventEmitter?.addListener(
215
+ 'onDeviceAclDisconnected',
216
+ callback
217
+ );
218
+ return () => {
219
+ subscription?.remove();
220
+ };
221
+ }
168
222
  }
169
223
 
170
224
  export default new BleUtils();
@@ -174,5 +228,7 @@ export type {
174
228
  BondState,
175
229
  AdvertisingData,
176
230
  KeyMissingPeripheral,
231
+ EncryptionChangePeripheral,
232
+ AclDisconnectedPeripheral,
177
233
  PairDeviceResult,
178
234
  };
package/src/type.ts CHANGED
@@ -48,6 +48,20 @@ export interface KeyMissingPeripheral {
48
48
  id: string;
49
49
  }
50
50
 
51
+ export interface EncryptionChangePeripheral {
52
+ /** Device MAC address. */
53
+ id: string;
54
+ /** HCI status of the encryption procedure: 0 on success, 6 when the peer lost the bond. */
55
+ status: number;
56
+ /** Whether the LE link is encrypted after the change. */
57
+ enabled: boolean;
58
+ }
59
+
60
+ export interface AclDisconnectedPeripheral {
61
+ /** Device MAC address. */
62
+ id: string;
63
+ }
64
+
51
65
  export interface AdvertisingData {
52
66
  isConnectable?: boolean;
53
67
  localName?: string;