Skip to content

Commit 3d8ed63

Browse files
authored
Merge pull request #365 from NordicSemiconductor/bugfix/race-condition-on-remove-bond
Making sure then() callback is called for RemoveBond request
2 parents 8f51a99 + ef22b9e commit 3d8ed63

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

ble/src/main/java/no/nordicsemi/android/ble/BleManagerHandler.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,9 @@ public void onReceive(final Context context, final Intent intent) {
335335
return;
336336
}
337337
} else if (previousBondState == BluetoothDevice.BOND_BONDED) {
338+
// Removing the bond will cause disconnection.
339+
userDisconnected = true;
340+
338341
if (request != null && request.type == Request.Type.REMOVE_BOND) {
339342
// The device has already disconnected by now.
340343
log(Log.INFO, () -> "Bond information removed");
@@ -345,7 +348,15 @@ public void onReceive(final Context context, final Intent intent) {
345348
// or in Android Settings), the BluetoothGatt object should be closed, so
346349
// the library won't reconnect to the device automatically.
347350
// See: https://github.com/NordicSemiconductor/Android-BLE-Library/issues/157
348-
close();
351+
if (!isConnected())
352+
close();
353+
354+
// Due to https://github.com/NordicSemiconductor/Android-BLE-Library/issues/363,
355+
// the call to close() here has been placed behind an if statement.
356+
// Instead, the 'userDisconnected' flag is set to true (here and in
357+
// 'internalRemoveBond()'.
358+
// When the device gets disconnected, close() method will be called from
359+
// 'notifyDeviceDisconnected(...)'.
349360
}
350361
break;
351362
case BluetoothDevice.BOND_BONDING:
@@ -764,6 +775,8 @@ private boolean internalRemoveBond() {
764775
//noinspection JavaReflectionMemberAccess
765776
final Method removeBond = device.getClass().getMethod("removeBond");
766777
log(Log.DEBUG, () -> "device.removeBond() (hidden)");
778+
// Removing a call will initiate disconnection.
779+
userDisconnected = true;
767780
return removeBond.invoke(device) == Boolean.TRUE;
768781
} catch (final Exception e) {
769782
Log.w(TAG, "An exception occurred while removing bond", e);
@@ -1577,12 +1590,17 @@ private void notifyDeviceDisconnected(@NonNull final BluetoothDevice device, fin
15771590
// ConnectRequest was already notified
15781591
} else if (userDisconnected) {
15791592
log(Log.INFO, () -> "Disconnected");
1580-
close();
1593+
// If Remove Bond was called, the broadcast may be called AFTER the device has disconnected.
1594+
// In that case, we can't call close() here, as that would unregister the broadcast
1595+
// receiver. Instead, close() will be called from the receiver.
1596+
if (request == null || request.type != Request.Type.REMOVE_BOND)
1597+
close();
15811598
postCallback(c -> c.onDeviceDisconnected(device));
15821599
postConnectionStateChange(o -> o.onDeviceDisconnected(device, status));
15831600
final Request request = this.request;
15841601
if (request != null && request.type == Request.Type.DISCONNECT) {
15851602
request.notifySuccess(device);
1603+
this.request = null;
15861604
}
15871605
} else {
15881606
log(Log.WARN, () -> "Connection lost");

0 commit comments

Comments
 (0)