diff options
-rw-r--r-- | android/app/src/com/android/bluetooth/btservice/AdapterService.java | 15 | ||||
-rw-r--r-- | android/app/src/com/android/bluetooth/gatt/GattService.java | 19 | ||||
-rw-r--r-- | flags/connectivity.aconfig | 24 | ||||
-rw-r--r-- | flags/gap.aconfig | 20 | ||||
-rw-r--r-- | framework/tests/bumble/src/android/bluetooth/pairing/PairingTest.java | 101 | ||||
-rw-r--r-- | system/gd/hci/acl_manager/le_impl.h | 15 | ||||
-rw-r--r-- | system/gd/hci/acl_manager/le_impl_test.cc | 303 | ||||
-rw-r--r-- | system/stack/eatt/eatt_impl.h | 6 | ||||
-rw-r--r-- | system/stack/gatt/gatt_main.cc | 2 | ||||
-rw-r--r-- | system/stack/test/eatt/eatt_test.cc | 1 |
10 files changed, 248 insertions, 258 deletions
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java index e9202c4f6c..182e75cceb 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java @@ -3106,16 +3106,13 @@ public class AdapterService extends Service { public int getConnectionState(BluetoothDevice device) { final String address = device.getAddress(); - if (Flags.apiGetConnectionStateUsingIdentityAddress()) { - int connectionState = mNativeInterface.getConnectionState(getBytesFromAddress(address)); - final String identityAddress = getIdentityAddress(address); - if (identityAddress != null) { - connectionState |= - mNativeInterface.getConnectionState(getBytesFromAddress(identityAddress)); - } - return connectionState; + int connectionState = mNativeInterface.getConnectionState(getBytesFromAddress(address)); + final String identityAddress = getIdentityAddress(address); + if (identityAddress != null) { + connectionState |= + mNativeInterface.getConnectionState(getBytesFromAddress(identityAddress)); } - return mNativeInterface.getConnectionState(getBytesFromAddress(address)); + return connectionState; } int getConnectionHandle(BluetoothDevice device, int transport) { diff --git a/android/app/src/com/android/bluetooth/gatt/GattService.java b/android/app/src/com/android/bluetooth/gatt/GattService.java index bc5aeb3367..10190b09ef 100644 --- a/android/app/src/com/android/bluetooth/gatt/GattService.java +++ b/android/app/src/com/android/bluetooth/gatt/GattService.java @@ -2319,21 +2319,14 @@ public class GattService extends ProfileService { int handle = 0; Integer connId = 0; - if (!Flags.gattServerRequestsFix()) { - HandleMap.Entry entry = mHandleMap.getByRequestId(requestId); - if (entry != null) { - handle = entry.mHandle; - } - connId = mServerMap.connIdByAddress(serverIf, address); + HandleMap.RequestData requestData = mHandleMap.getRequestDataByRequestId(requestId); + if (requestData != null) { + handle = requestData.handle(); + connId = requestData.connId(); } else { - HandleMap.RequestData requestData = mHandleMap.getRequestDataByRequestId(requestId); - if (requestData != null) { - handle = requestData.handle(); - connId = requestData.connId(); - } else { - connId = mServerMap.connIdByAddress(serverIf, address); - } + connId = mServerMap.connIdByAddress(serverIf, address); } + mNativeInterface.gattServerSendResponse( serverIf, connId != null ? connId : 0, diff --git a/flags/connectivity.aconfig b/flags/connectivity.aconfig index 482c7e68e8..738c294078 100644 --- a/flags/connectivity.aconfig +++ b/flags/connectivity.aconfig @@ -2,30 +2,6 @@ package: "com.android.bluetooth.flags" container: "com.android.bt" flag { - name: "api_get_connection_state_using_identity_address" - namespace: "bluetooth" - description: "Use identity address to check current connection state" - bug: "319471537" -} - -flag { - name: "use_le_shim_connection_map_guard" - namespace: "bluetooth" - description: "Guard the le shim connection map with a mutex" - bug: "302054609" -} - -flag { - name: "improve_create_connection_for_already_connecting_device" - namespace: "bluetooth" - description: "Make sure to not stop controller with create connection cancel when not needed" - bug: "356593752" - metadata { - purpose: PURPOSE_BUGFIX - } -} - -flag { name: "allow_gatt_connect_from_the_apps_without_making_leaudio_device_active" namespace: "bluetooth" description: "Allows for GATT connection without making LeAudio device active after connection" diff --git a/flags/gap.aconfig b/flags/gap.aconfig index 419e846836..856f4f7bb4 100644 --- a/flags/gap.aconfig +++ b/flags/gap.aconfig @@ -70,26 +70,6 @@ flag { } flag { - name: "gatt_disconnect_fix" - namespace: "bluetooth" - description: "Fix GATT disconnect handling" - bug: "361538527" - metadata { - purpose: PURPOSE_BUGFIX - } -} - -flag { - name: "gatt_server_requests_fix" - namespace: "bluetooth" - description: "Fix GATT server handling" - bug: "361331170" - metadata { - purpose: PURPOSE_BUGFIX - } -} - -flag { name: "le_scan_msft_support" namespace: "bluetooth" description: "Support MSFT HCI extension for LE Scanning. go/bt-msft-aosp-dd" diff --git a/framework/tests/bumble/src/android/bluetooth/pairing/PairingTest.java b/framework/tests/bumble/src/android/bluetooth/pairing/PairingTest.java index 37dc344cb5..ecb400deb3 100644 --- a/framework/tests/bumble/src/android/bluetooth/pairing/PairingTest.java +++ b/framework/tests/bumble/src/android/bluetooth/pairing/PairingTest.java @@ -32,6 +32,7 @@ import android.bluetooth.BluetoothHidHost; import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothStatusCodes; +import android.bluetooth.BluetoothSocket; import android.bluetooth.PandoraDevice; import android.bluetooth.StreamObserverSpliterator; import android.bluetooth.Utils; @@ -41,6 +42,7 @@ import android.bluetooth.test_utils.BlockingBluetoothAdapter; import android.bluetooth.test_utils.EnableBluetoothRule; import android.content.Context; import android.os.ParcelUuid; +import android.util.Log; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; @@ -80,6 +82,9 @@ import java.time.Duration; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.io.IOException; @RunWith(TestParameterInjector.class) public class PairingTest { @@ -87,6 +92,7 @@ public class PairingTest { private static final Duration BOND_INTENT_TIMEOUT = Duration.ofSeconds(10); private static final int TEST_DELAY_MS = 1000; + private static final int TEST_PSM = 5; private static final ParcelUuid BATTERY_UUID = ParcelUuid.fromString("0000180F-0000-1000-8000-00805F9B34FB"); @@ -836,6 +842,101 @@ public class PairingTest { intentReceiver.close(); } + /** + * Test pending LE L2CAP socket connection and LE pairing + * + * <p>Prerequisites: + * + * <ol> + * <li>Bumble and Android are not bonded + * </ol> + * + * <p>Steps: + * + * <ol> + * <li>Make Remote device non-connectable over LE + * <li>Initiate LE socket connection from DUT to Remote device + * <li>Initiate LE pairing from DUT to Remote device + * <li>Start LE Advertisement from Remote device after few seconds + * </ol> + * + * <p>Expectation: LE connection should be created and LE Pairing should succeed. + */ + @Test + public void testCreateLeSocket_BondLe() throws Exception { + IntentReceiver intentReceiver = new IntentReceiver.Builder(sTargetContext, + BluetoothDevice.ACTION_ACL_CONNECTED, + BluetoothDevice.ACTION_PAIRING_REQUEST, + BluetoothDevice.ACTION_BOND_STATE_CHANGED) + .build(); + + StreamObserver<PairingEventAnswer> pairingEventAnswerObserver = + mBumble.security() + .withDeadlineAfter(BOND_INTENT_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS) + .onPairing(mPairingEventStreamObserver); + + BluetoothSocket bluetoothSocket = mBumbleDevice.createL2capChannel(TEST_PSM); + + ExecutorService executor = Executors.newSingleThreadExecutor(); + executor.submit(() -> { + try { + bluetoothSocket.connect(); + } catch (IOException e) { + Log.e(TAG, "Exception during socket connection: " + e); + } + }); + executor.shutdown(); + + // Wait for LE L2CAP socket connection above to be called and reach BT stack + Thread.sleep(2000); + + mBumbleDevice.createBond(BluetoothDevice.TRANSPORT_LE); + + /* Make LE L2CAP socket connection and LE Bond calls to wait for few seconds + and start LE advertisement from remote device. */ + Thread.sleep(3000); + + // Start LE advertisement from Bumble + AdvertiseRequest.Builder advRequestBuilder = + AdvertiseRequest.newBuilder().setLegacy(true) + .setConnectable(true) + .setOwnAddressType(OwnAddressType.PUBLIC); + + StreamObserverSpliterator<AdvertiseResponse> responseObserver = + new StreamObserverSpliterator<>(); + mBumble.host().advertise(advRequestBuilder.build(), responseObserver); + + intentReceiver.verifyReceivedOrdered( + hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), + hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDING)); + + intentReceiver.verifyReceivedOrdered( + hasAction(BluetoothDevice.ACTION_ACL_CONNECTED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), + hasExtra(BluetoothDevice.EXTRA_TRANSPORT, BluetoothDevice.TRANSPORT_LE)); + + intentReceiver.verifyReceivedOrdered( + hasAction(BluetoothDevice.ACTION_PAIRING_REQUEST), + hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), + hasExtra( + BluetoothDevice.EXTRA_PAIRING_VARIANT, + BluetoothDevice.PAIRING_VARIANT_CONSENT)); + mBumbleDevice.setPairingConfirmation(true); + + PairingEvent pairingEvent = mPairingEventStreamObserver.iterator().next(); + assertThat(pairingEvent.hasJustWorks()).isTrue(); + pairingEventAnswerObserver.onNext( + PairingEventAnswer.newBuilder().setEvent(pairingEvent).setConfirm(true).build()); + + intentReceiver.verifyReceivedOrdered( + hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), + hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDED)); + + intentReceiver.close(); + } + /** Helper/testStep functions goes here */ /** diff --git a/system/gd/hci/acl_manager/le_impl.h b/system/gd/hci/acl_manager/le_impl.h index ef5bfb0d7d..122f76525e 100644 --- a/system/gd/hci/acl_manager/le_impl.h +++ b/system/gd/hci/acl_manager/le_impl.h @@ -1063,15 +1063,12 @@ public: add_device_to_accept_list(address_with_type); } - if (com::android::bluetooth::flags:: - improve_create_connection_for_already_connecting_device()) { - bool in_accept_list_due_to_direct_connect = - direct_connections_.find(address_with_type) != direct_connections_.end(); - - if (already_in_accept_list && (in_accept_list_due_to_direct_connect || !is_direct)) { - log::info("Device {} already in accept list. Stop here.", address_with_type); - return; - } + bool in_accept_list_due_to_direct_connect = + direct_connections_.find(address_with_type) != direct_connections_.end(); + + if (already_in_accept_list && (in_accept_list_due_to_direct_connect || !is_direct)) { + log::info("Device {} already in accept list. Stop here.", address_with_type); + return; } if (is_direct) { diff --git a/system/gd/hci/acl_manager/le_impl_test.cc b/system/gd/hci/acl_manager/le_impl_test.cc index 274b6827c9..f54d316d30 100644 --- a/system/gd/hci/acl_manager/le_impl_test.cc +++ b/system/gd/hci/acl_manager/le_impl_test.cc @@ -284,164 +284,6 @@ protected: hci_layer_->IncomingEvent(LeSetRandomAddressCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); } - void test_direct_connection_after_background_connection() { - set_random_device_address_policy(); - - hci::AddressWithType address({0x21, 0x22, 0x23, 0x24, 0x25, 0x26}, - AddressType::PUBLIC_DEVICE_ADDRESS); - - // arrange: Create background connection. Remember that acl_manager adds device background list - le_impl_->add_device_to_background_connection_list(address); - le_impl_->create_le_connection(address, true, /* is_direct */ false); - hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); - hci_layer_->IncomingEvent( - LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); - auto raw_bg_create_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION); - hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); - sync_handler(); - - // act: Create direct connection - le_impl_->create_le_connection(address, true, /* is_direct */ true); - auto cancel_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION_CANCEL); - if (cancel_connection.IsValid()) { - hci_layer_->IncomingEvent( - LeCreateConnectionCancelCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); - hci_layer_->IncomingLeMetaEvent(LeConnectionCompleteBuilder::Create( - ErrorCode::UNKNOWN_CONNECTION, kHciHandle, Role::CENTRAL, - AddressType::PUBLIC_DEVICE_ADDRESS, Address::kEmpty, 0x0000, 0x0000, 0x0000, - ClockAccuracy::PPM_30)); - } - auto raw_direct_create_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION); - - // assert - auto bg_create_connection = - LeCreateConnectionView::Create(LeConnectionManagementCommandView::Create( - AclCommandView::Create(raw_bg_create_connection))); - EXPECT_TRUE(bg_create_connection.IsValid()); - auto direct_create_connection = - LeCreateConnectionView::Create(LeConnectionManagementCommandView::Create( - AclCommandView::Create(raw_direct_create_connection))); - EXPECT_TRUE(direct_create_connection.IsValid()); - log::info("Scan Interval {}", direct_create_connection.GetLeScanInterval()); - ASSERT_NE(direct_create_connection.GetLeScanInterval(), - bg_create_connection.GetLeScanInterval()); - - hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); - sync_handler(); - - // Check state is ARMED - ASSERT_EQ(ConnectabilityState::ARMED, le_impl_->connectability_state_); - - // Simulate timeout on direct connect. Verify background connect is still in place - EXPECT_CALL(mock_le_connection_callbacks_, - OnLeConnectFail(_, ErrorCode::CONNECTION_ACCEPT_TIMEOUT)) - .Times(1); - le_impl_->on_create_connection_timeout(address); - sync_handler(); - cancel_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION_CANCEL); - hci_layer_->IncomingEvent( - LeCreateConnectionCancelCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); - hci_layer_->IncomingLeMetaEvent(LeConnectionCompleteBuilder::Create( - ErrorCode::UNKNOWN_CONNECTION, kHciHandle, Role::CENTRAL, - AddressType::PUBLIC_DEVICE_ADDRESS, Address::kEmpty, 0x0000, 0x0000, 0x0000, - ClockAccuracy::PPM_30)); - EXPECT_TRUE(cancel_connection.IsValid()); - raw_bg_create_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION); - bg_create_connection = LeCreateConnectionView::Create(LeConnectionManagementCommandView::Create( - AclCommandView::Create(raw_bg_create_connection))); - EXPECT_TRUE(bg_create_connection.IsValid()); - sync_handler(); - ASSERT_TRUE(le_impl_->create_connection_timeout_alarms_.empty()); - - hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); - sync_handler(); - - // Check state is ARMED - ASSERT_EQ(ConnectabilityState::ARMED, le_impl_->connectability_state_); - } - - void test_direct_connect_after_direct_connect() { - set_random_device_address_policy(); - - hci::AddressWithType address({0x21, 0x22, 0x23, 0x24, 0x25, 0x26}, - AddressType::PUBLIC_DEVICE_ADDRESS); - - // Create first direct connection - le_impl_->create_le_connection(address, true, /* is_direct */ true); - hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); - hci_layer_->IncomingEvent( - LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); - auto raw_direct_1_create_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION); - hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); - sync_handler(); - - // Check state is ARMED - ASSERT_EQ(ConnectabilityState::ARMED, le_impl_->connectability_state_); - - // assert - auto direct_1_create_connection = - LeCreateConnectionView::Create(LeConnectionManagementCommandView::Create( - AclCommandView::Create(raw_direct_1_create_connection))); - EXPECT_TRUE(direct_1_create_connection.IsValid()); - - log::info("Second direct connect to the same device"); - - // Create second direct connection - le_impl_->create_le_connection(address, true, /* is_direct */ true); - sync_handler(); - - CommandView cancel_connection = CommandView::Create( - PacketView<packet::kLittleEndian>(std::make_shared<std::vector<uint8_t>>())); - - if (!com::android::bluetooth::flags:: - improve_create_connection_for_already_connecting_device()) { - cancel_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION_CANCEL); - if (cancel_connection.IsValid()) { - hci_layer_->IncomingEvent( - LeCreateConnectionCancelCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); - hci_layer_->IncomingLeMetaEvent(LeConnectionCompleteBuilder::Create( - ErrorCode::UNKNOWN_CONNECTION, kHciHandle, Role::CENTRAL, - AddressType::PUBLIC_DEVICE_ADDRESS, Address::kEmpty, 0x0000, 0x0000, 0x0000, - ClockAccuracy::PPM_30)); - } - - auto raw_direct_2_create_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION); - - auto direct_2_create_connection = - LeCreateConnectionView::Create(LeConnectionManagementCommandView::Create( - AclCommandView::Create(raw_direct_2_create_connection))); - EXPECT_TRUE(direct_2_create_connection.IsValid()); - hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); - sync_handler(); - } else { - hci_layer_->AssertNoQueuedCommand(); - } - - log::info("Simulate timeout"); - - EXPECT_CALL(mock_le_connection_callbacks_, - OnLeConnectFail(_, ErrorCode::CONNECTION_ACCEPT_TIMEOUT)) - .Times(1); - le_impl_->on_create_connection_timeout(address); - sync_handler(); - cancel_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION_CANCEL); - EXPECT_TRUE(cancel_connection.IsValid()); - hci_layer_->IncomingEvent( - LeCreateConnectionCancelCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); - hci_layer_->IncomingLeMetaEvent(LeConnectionCompleteBuilder::Create( - ErrorCode::UNKNOWN_CONNECTION, kHciHandle, Role::CENTRAL, - AddressType::PUBLIC_DEVICE_ADDRESS, Address::kEmpty, 0x0000, 0x0000, 0x0000, - ClockAccuracy::PPM_30)); - sync_handler(); - ASSERT_TRUE(le_impl_->create_connection_timeout_alarms_.empty()); - - hci_layer_->GetCommand(OpCode::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST); - hci_layer_->IncomingEvent( - LeRemoveDeviceFromFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); - hci_layer_->AssertNoQueuedCommand(); - ASSERT_EQ(ConnectabilityState::DISARMED, le_impl_->connectability_state_); - } - // Need to store the LeAclConnection so it is not immediately dropped => disconnected std::unique_ptr<LeAclConnection> create_enhanced_connection(std::string remote_address_string, int handle) { @@ -1693,29 +1535,138 @@ TEST_F(LeImplTest, DisconnectionAcceptlistCallback) { } TEST_F(LeImplTest, direct_connection_after_background_connection) { - // TODO b/356593752 - remove when test removing flag - com::android::bluetooth::flags::provider_ - ->improve_create_connection_for_already_connecting_device(false); - test_direct_connection_after_background_connection(); -} + set_random_device_address_policy(); + + hci::AddressWithType address({0x21, 0x22, 0x23, 0x24, 0x25, 0x26}, + AddressType::PUBLIC_DEVICE_ADDRESS); + + // arrange: Create background connection. Remember that acl_manager adds device background list + le_impl_->add_device_to_background_connection_list(address); + le_impl_->create_le_connection(address, true, /* is_direct */ false); + hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); + hci_layer_->IncomingEvent( + LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + auto raw_bg_create_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION); + hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); + sync_handler(); -TEST_F(LeImplTest, direct_connection_after_background_connection_with_improvement) { - com::android::bluetooth::flags::provider_ - ->improve_create_connection_for_already_connecting_device(true); - test_direct_connection_after_background_connection(); + // act: Create direct connection + le_impl_->create_le_connection(address, true, /* is_direct */ true); + auto cancel_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION_CANCEL); + if (cancel_connection.IsValid()) { + hci_layer_->IncomingEvent( + LeCreateConnectionCancelCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingLeMetaEvent(LeConnectionCompleteBuilder::Create( + ErrorCode::UNKNOWN_CONNECTION, kHciHandle, Role::CENTRAL, + AddressType::PUBLIC_DEVICE_ADDRESS, Address::kEmpty, 0x0000, 0x0000, 0x0000, + ClockAccuracy::PPM_30)); + } + auto raw_direct_create_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION); + + // assert + auto bg_create_connection = + LeCreateConnectionView::Create(LeConnectionManagementCommandView::Create( + AclCommandView::Create(raw_bg_create_connection))); + EXPECT_TRUE(bg_create_connection.IsValid()); + auto direct_create_connection = + LeCreateConnectionView::Create(LeConnectionManagementCommandView::Create( + AclCommandView::Create(raw_direct_create_connection))); + EXPECT_TRUE(direct_create_connection.IsValid()); + log::info("Scan Interval {}", direct_create_connection.GetLeScanInterval()); + ASSERT_NE(direct_create_connection.GetLeScanInterval(), bg_create_connection.GetLeScanInterval()); + + hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); + sync_handler(); + + // Check state is ARMED + ASSERT_EQ(ConnectabilityState::ARMED, le_impl_->connectability_state_); + + // Simulate timeout on direct connect. Verify background connect is still in place + EXPECT_CALL(mock_le_connection_callbacks_, + OnLeConnectFail(_, ErrorCode::CONNECTION_ACCEPT_TIMEOUT)) + .Times(1); + le_impl_->on_create_connection_timeout(address); + sync_handler(); + cancel_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION_CANCEL); + hci_layer_->IncomingEvent( + LeCreateConnectionCancelCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingLeMetaEvent(LeConnectionCompleteBuilder::Create( + ErrorCode::UNKNOWN_CONNECTION, kHciHandle, Role::CENTRAL, + AddressType::PUBLIC_DEVICE_ADDRESS, Address::kEmpty, 0x0000, 0x0000, 0x0000, + ClockAccuracy::PPM_30)); + EXPECT_TRUE(cancel_connection.IsValid()); + raw_bg_create_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION); + bg_create_connection = LeCreateConnectionView::Create(LeConnectionManagementCommandView::Create( + AclCommandView::Create(raw_bg_create_connection))); + EXPECT_TRUE(bg_create_connection.IsValid()); + sync_handler(); + ASSERT_TRUE(le_impl_->create_connection_timeout_alarms_.empty()); + + hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); + sync_handler(); + + // Check state is ARMED + ASSERT_EQ(ConnectabilityState::ARMED, le_impl_->connectability_state_); } TEST_F(LeImplTest, direct_connection_after_direct_connection) { - // TODO b/356593752 - remove when test removing flag - com::android::bluetooth::flags::provider_ - ->improve_create_connection_for_already_connecting_device(false); - test_direct_connect_after_direct_connect(); -} + set_random_device_address_policy(); -TEST_F(LeImplTest, direct_connection_after_direct_connection_with_improvement) { - com::android::bluetooth::flags::provider_ - ->improve_create_connection_for_already_connecting_device(true); - test_direct_connect_after_direct_connect(); + hci::AddressWithType address({0x21, 0x22, 0x23, 0x24, 0x25, 0x26}, + AddressType::PUBLIC_DEVICE_ADDRESS); + + // Create first direct connection + le_impl_->create_le_connection(address, true, /* is_direct */ true); + hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); + hci_layer_->IncomingEvent( + LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + auto raw_direct_1_create_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION); + hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); + sync_handler(); + + // Check state is ARMED + ASSERT_EQ(ConnectabilityState::ARMED, le_impl_->connectability_state_); + + // assert + auto direct_1_create_connection = + LeCreateConnectionView::Create(LeConnectionManagementCommandView::Create( + AclCommandView::Create(raw_direct_1_create_connection))); + EXPECT_TRUE(direct_1_create_connection.IsValid()); + + log::info("Second direct connect to the same device"); + + // Create second direct connection + le_impl_->create_le_connection(address, true, /* is_direct */ true); + sync_handler(); + + CommandView cancel_connection = CommandView::Create( + PacketView<packet::kLittleEndian>(std::make_shared<std::vector<uint8_t>>())); + + hci_layer_->AssertNoQueuedCommand(); + + log::info("Simulate timeout"); + + EXPECT_CALL(mock_le_connection_callbacks_, + OnLeConnectFail(_, ErrorCode::CONNECTION_ACCEPT_TIMEOUT)) + .Times(1); + le_impl_->on_create_connection_timeout(address); + sync_handler(); + cancel_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION_CANCEL); + EXPECT_TRUE(cancel_connection.IsValid()); + hci_layer_->IncomingEvent( + LeCreateConnectionCancelCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingLeMetaEvent(LeConnectionCompleteBuilder::Create( + ErrorCode::UNKNOWN_CONNECTION, kHciHandle, Role::CENTRAL, + AddressType::PUBLIC_DEVICE_ADDRESS, Address::kEmpty, 0x0000, 0x0000, 0x0000, + ClockAccuracy::PPM_30)); + sync_handler(); + ASSERT_TRUE(le_impl_->create_connection_timeout_alarms_.empty()); + + hci_layer_->GetCommand(OpCode::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST); + hci_layer_->IncomingEvent( + LeRemoveDeviceFromFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->AssertNoQueuedCommand(); + ASSERT_EQ(ConnectabilityState::DISARMED, le_impl_->connectability_state_); } TEST_F(LeImplTest, direct_connection_cancel_but_connected) { diff --git a/system/stack/eatt/eatt_impl.h b/system/stack/eatt/eatt_impl.h index 0d27726af4..b602636f0d 100644 --- a/system/stack/eatt/eatt_impl.h +++ b/system/stack/eatt/eatt_impl.h @@ -723,11 +723,7 @@ struct eatt_impl { tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(channel->bda_, BT_TRANSPORT_LE); log::warn("disconnecting channel {:#x} for {}", channel->cid_, channel->bda_); - if (com::android::bluetooth::flags::gatt_disconnect_fix()) { - EattExtension::GetInstance()->Disconnect(channel->bda_, channel->cid_); - } else { - gatt_disconnect(p_tcb); - } + EattExtension::GetInstance()->Disconnect(channel->bda_, channel->cid_); } void start_indication_confirm_timer(const RawAddress& bd_addr, uint16_t cid) { diff --git a/system/stack/gatt/gatt_main.cc b/system/stack/gatt/gatt_main.cc index 19fd83990a..5228369a26 100644 --- a/system/stack/gatt/gatt_main.cc +++ b/system/stack/gatt/gatt_main.cc @@ -282,7 +282,7 @@ bool gatt_disconnect(tGATT_TCB* p_tcb) { return true; } - if (com::android::bluetooth::flags::gatt_disconnect_fix() && p_tcb->eatt) { + if (p_tcb->eatt) { /* ATT is fixed channel and it is expected to drop ACL. * Make sure all EATT channels are disconnected before doing that. */ diff --git a/system/stack/test/eatt/eatt_test.cc b/system/stack/test/eatt/eatt_test.cc index 5d7a2eeea8..17f4908b3e 100644 --- a/system/stack/test/eatt/eatt_test.cc +++ b/system/stack/test/eatt/eatt_test.cc @@ -660,7 +660,6 @@ TEST_F(EattTest, ChannelUnavailableWhileReconfiguring) { } TEST_F(EattTest, DisconnectChannelOnIndicationConfirmationTimeout) { - com::android::bluetooth::flags::provider_->gatt_disconnect_fix(true); ConnectDeviceEattSupported(1); eatt_instance_->StartIndicationConfirmationTimer(test_address, test_local_cids[0]); |