Loading framework/tests/bumble/src/android/bluetooth/pairing/PairingTest.java +269 −150 Original line number Diff line number Diff line Loading @@ -31,8 +31,10 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.PandoraDevice; import android.bluetooth.StreamObserverSpliterator; import android.bluetooth.test_utils.BlockingBluetoothAdapter; import android.bluetooth.test_utils.EnableBluetoothRule; import android.content.BroadcastReceiver; import android.content.Context; Loading Loading @@ -105,14 +107,13 @@ public class PairingTest { @Rule(order = 3) public final EnableBluetoothRule mEnableBluetoothRule = new EnableBluetoothRule(false /* enableTestMode */, true /* toggleBluetooth */); @Mock private BroadcastReceiver mReceiver; private final Map<String, Integer> mActionRegistrationCounts = new HashMap<>(); private InOrder mInOrder = null; private BluetoothDevice mBumbleDevice; private final StreamObserverSpliterator<PairingEvent> mPairingEventStreamObserver = new StreamObserverSpliterator<>(); @Mock private BroadcastReceiver mReceiver; private InOrder mInOrder = null; private BluetoothDevice mBumbleDevice; @Before public void setUp() throws Exception { Loading Loading @@ -299,7 +300,7 @@ public class PairingTest { * <li>Service discovery completes * <li>Android cancels the pairing * </ol> * * <p> * Expectation: Pairing gets cancelled instead of getting timed out */ @Test Loading Loading @@ -349,7 +350,7 @@ public class PairingTest { * <li>Android does confirms the pairing * <li>Pairing is successful * </ol> * * <p> * Expectation: Pairing succeeds */ @Test Loading Loading @@ -377,6 +378,124 @@ public class PairingTest { unregisterIntentActions(BluetoothDevice.ACTION_BOND_STATE_CHANGED); } /** * Test if bonded LE device can reconnect after BT restart * * <p>Prerequisites: * * <ol> * <li>Bumble and Android are not bonded * </ol> * * <p>Steps: * * <ol> * <li>Bumble is discoverable and connectable over LE * <li>Android pairs with Bumble over LE * <li>Android restarts * <li>Bumble is connectable over LE * <li>Android reconnects to Bumble successfully and re-encrypts the link * </ol> * <p> * Expectation: Pairing succeeds */ @Test public void testBondLe_Reconnect() { registerIntentActions(BluetoothDevice.ACTION_ACL_CONNECTED); testStep_BondLe(); assertThat(sAdapter.getBondedDevices()).contains(mBumbleDevice); testStep_restartBt(); assertThat(sAdapter.getBondedDevices()).contains(mBumbleDevice); mBumble.hostBlocking() .advertise( AdvertiseRequest.newBuilder() .setLegacy(true) .setConnectable(true) .setOwnAddressType(OwnAddressType.PUBLIC) .build()); assertThat(mBumbleDevice.connect()).isEqualTo(BluetoothStatusCodes.SUCCESS); verifyIntentReceived( hasAction(BluetoothDevice.ACTION_ACL_CONNECTED), hasExtra(BluetoothDevice.EXTRA_TRANSPORT, BluetoothDevice.TRANSPORT_LE), hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice)); verifyNoMoreInteractions(mReceiver); unregisterIntentActions(BluetoothDevice.ACTION_ACL_CONNECTED); } private void testStep_BondLe() { registerIntentActions( BluetoothDevice.ACTION_BOND_STATE_CHANGED, BluetoothDevice.ACTION_ACL_CONNECTED, BluetoothDevice.ACTION_PAIRING_REQUEST); mBumble.gattBlocking() .registerService( GattProto.RegisterServiceRequest.newBuilder() .setService( GattProto.GattServiceParams.newBuilder() .setUuid(BATTERY_UUID.toString()) .build()) .build()); mBumble.hostBlocking() .advertise( AdvertiseRequest.newBuilder() .setLegacy(true) .setConnectable(true) .setOwnAddressType(OwnAddressType.PUBLIC) .build()); StreamObserver<PairingEventAnswer> pairingEventAnswerObserver = mBumble.security() .withDeadlineAfter(BOND_INTENT_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS) .onPairing(mPairingEventStreamObserver); assertThat(mBumbleDevice.createBond(BluetoothDevice.TRANSPORT_LE)).isTrue(); verifyIntentReceivedUnordered( hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED), hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDING)); verifyIntentReceived(hasAction(BluetoothDevice.ACTION_ACL_CONNECTED), hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), hasExtra(BluetoothDevice.EXTRA_TRANSPORT, BluetoothDevice.TRANSPORT_LE)); verifyIntentReceivedUnordered( hasAction(BluetoothDevice.ACTION_PAIRING_REQUEST), hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), hasExtra( BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_CONSENT)); // Approve pairing from Android assertThat(mBumbleDevice.setPairingConfirmation(true)).isTrue(); PairingEvent pairingEvent = mPairingEventStreamObserver.iterator().next(); assertThat(pairingEvent.hasJustWorks()).isTrue(); pairingEventAnswerObserver.onNext( PairingEventAnswer.newBuilder().setEvent(pairingEvent).setConfirm(true).build()); // Ensure that pairing succeeds verifyIntentReceived( hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED), hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDED)); verifyNoMoreInteractions(mReceiver); unregisterIntentActions( BluetoothDevice.ACTION_BOND_STATE_CHANGED, BluetoothDevice.ACTION_ACL_CONNECTED, BluetoothDevice.ACTION_PAIRING_REQUEST); } private void testStep_restartBt() { assertThat(BlockingBluetoothAdapter.disable(true)).isTrue(); assertThat(BlockingBluetoothAdapter.enable()).isTrue(); } /* Starts outgoing GATT service discovery and incoming LE pairing in parallel */ private StreamObserverSpliterator<SecureResponse> helper_OutgoingGattServiceDiscoveryWithIncomingLePairing() { Loading Loading
framework/tests/bumble/src/android/bluetooth/pairing/PairingTest.java +269 −150 Original line number Diff line number Diff line Loading @@ -31,8 +31,10 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.PandoraDevice; import android.bluetooth.StreamObserverSpliterator; import android.bluetooth.test_utils.BlockingBluetoothAdapter; import android.bluetooth.test_utils.EnableBluetoothRule; import android.content.BroadcastReceiver; import android.content.Context; Loading Loading @@ -105,14 +107,13 @@ public class PairingTest { @Rule(order = 3) public final EnableBluetoothRule mEnableBluetoothRule = new EnableBluetoothRule(false /* enableTestMode */, true /* toggleBluetooth */); @Mock private BroadcastReceiver mReceiver; private final Map<String, Integer> mActionRegistrationCounts = new HashMap<>(); private InOrder mInOrder = null; private BluetoothDevice mBumbleDevice; private final StreamObserverSpliterator<PairingEvent> mPairingEventStreamObserver = new StreamObserverSpliterator<>(); @Mock private BroadcastReceiver mReceiver; private InOrder mInOrder = null; private BluetoothDevice mBumbleDevice; @Before public void setUp() throws Exception { Loading Loading @@ -299,7 +300,7 @@ public class PairingTest { * <li>Service discovery completes * <li>Android cancels the pairing * </ol> * * <p> * Expectation: Pairing gets cancelled instead of getting timed out */ @Test Loading Loading @@ -349,7 +350,7 @@ public class PairingTest { * <li>Android does confirms the pairing * <li>Pairing is successful * </ol> * * <p> * Expectation: Pairing succeeds */ @Test Loading Loading @@ -377,6 +378,124 @@ public class PairingTest { unregisterIntentActions(BluetoothDevice.ACTION_BOND_STATE_CHANGED); } /** * Test if bonded LE device can reconnect after BT restart * * <p>Prerequisites: * * <ol> * <li>Bumble and Android are not bonded * </ol> * * <p>Steps: * * <ol> * <li>Bumble is discoverable and connectable over LE * <li>Android pairs with Bumble over LE * <li>Android restarts * <li>Bumble is connectable over LE * <li>Android reconnects to Bumble successfully and re-encrypts the link * </ol> * <p> * Expectation: Pairing succeeds */ @Test public void testBondLe_Reconnect() { registerIntentActions(BluetoothDevice.ACTION_ACL_CONNECTED); testStep_BondLe(); assertThat(sAdapter.getBondedDevices()).contains(mBumbleDevice); testStep_restartBt(); assertThat(sAdapter.getBondedDevices()).contains(mBumbleDevice); mBumble.hostBlocking() .advertise( AdvertiseRequest.newBuilder() .setLegacy(true) .setConnectable(true) .setOwnAddressType(OwnAddressType.PUBLIC) .build()); assertThat(mBumbleDevice.connect()).isEqualTo(BluetoothStatusCodes.SUCCESS); verifyIntentReceived( hasAction(BluetoothDevice.ACTION_ACL_CONNECTED), hasExtra(BluetoothDevice.EXTRA_TRANSPORT, BluetoothDevice.TRANSPORT_LE), hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice)); verifyNoMoreInteractions(mReceiver); unregisterIntentActions(BluetoothDevice.ACTION_ACL_CONNECTED); } private void testStep_BondLe() { registerIntentActions( BluetoothDevice.ACTION_BOND_STATE_CHANGED, BluetoothDevice.ACTION_ACL_CONNECTED, BluetoothDevice.ACTION_PAIRING_REQUEST); mBumble.gattBlocking() .registerService( GattProto.RegisterServiceRequest.newBuilder() .setService( GattProto.GattServiceParams.newBuilder() .setUuid(BATTERY_UUID.toString()) .build()) .build()); mBumble.hostBlocking() .advertise( AdvertiseRequest.newBuilder() .setLegacy(true) .setConnectable(true) .setOwnAddressType(OwnAddressType.PUBLIC) .build()); StreamObserver<PairingEventAnswer> pairingEventAnswerObserver = mBumble.security() .withDeadlineAfter(BOND_INTENT_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS) .onPairing(mPairingEventStreamObserver); assertThat(mBumbleDevice.createBond(BluetoothDevice.TRANSPORT_LE)).isTrue(); verifyIntentReceivedUnordered( hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED), hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDING)); verifyIntentReceived(hasAction(BluetoothDevice.ACTION_ACL_CONNECTED), hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), hasExtra(BluetoothDevice.EXTRA_TRANSPORT, BluetoothDevice.TRANSPORT_LE)); verifyIntentReceivedUnordered( hasAction(BluetoothDevice.ACTION_PAIRING_REQUEST), hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), hasExtra( BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_CONSENT)); // Approve pairing from Android assertThat(mBumbleDevice.setPairingConfirmation(true)).isTrue(); PairingEvent pairingEvent = mPairingEventStreamObserver.iterator().next(); assertThat(pairingEvent.hasJustWorks()).isTrue(); pairingEventAnswerObserver.onNext( PairingEventAnswer.newBuilder().setEvent(pairingEvent).setConfirm(true).build()); // Ensure that pairing succeeds verifyIntentReceived( hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED), hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDED)); verifyNoMoreInteractions(mReceiver); unregisterIntentActions( BluetoothDevice.ACTION_BOND_STATE_CHANGED, BluetoothDevice.ACTION_ACL_CONNECTED, BluetoothDevice.ACTION_PAIRING_REQUEST); } private void testStep_restartBt() { assertThat(BlockingBluetoothAdapter.disable(true)).isTrue(); assertThat(BlockingBluetoothAdapter.enable()).isTrue(); } /* Starts outgoing GATT service discovery and incoming LE pairing in parallel */ private StreamObserverSpliterator<SecureResponse> helper_OutgoingGattServiceDiscoveryWithIncomingLePairing() { Loading