From 2a6137f7374d47b3a9307516af2c0107f5dca887 Mon Sep 17 00:00:00 2001 From: Rahul Arya <aryarahul@google.com> Date: Wed, 18 Jan 2023 02:35:27 +0000 Subject: [PATCH] [Offload] Alternative API for getAclHandle() This is a synchronous API on BluetoothDevice rather than a callback-based one on BluetoothGatt. Test: compiles Bug: 261093955 Change-Id: I3e008e84e1b2e19158984ecee963b9a63e74b8b1 --- ...oid_bluetooth_btservice_AdapterService.cpp | 10 +++-- .../bluetooth/btservice/AdapterService.java | 36 ++++++++++++++++ .../bluetooth/btservice/JniCallbacks.java | 4 +- .../bluetooth/btservice/RemoteDevices.java | 41 ++++++++++++++++++- .../btservice/RemoteDevicesTest.java | 3 +- framework/api/system-current.txt | 1 + .../android/bluetooth/BluetoothDevice.java | 36 ++++++++++++++++ .../binder/android/bluetooth/IBluetooth.aidl | 2 + system/bta/dm/bta_dm_act.cc | 10 +++-- system/bta/dm/bta_dm_int.h | 3 +- system/bta/include/bta_api.h | 1 + system/bta/include/bta_dm_acl.h | 3 +- system/btif/include/btif_common.h | 3 +- system/btif/include/core_callbacks.h | 3 +- system/btif/src/bluetooth.cc | 11 +++-- system/btif/src/btif_dm.cc | 8 ++-- system/btif/test/btif_core_test.cc | 3 +- system/gd/rust/linux/stack/src/bluetooth.rs | 2 + system/gd/rust/topshim/src/btif.rs | 12 +++++- system/include/hardware/bluetooth.h | 12 +++--- system/main/shim/l2c_api.cc | 2 +- system/service/adapter.cc | 3 +- system/service/hal/bluetooth_interface.cc | 12 +++--- system/service/hal/bluetooth_interface.h | 3 +- .../service/hal/fake_bluetooth_interface.cc | 6 +-- system/service/hal/fake_bluetooth_interface.h | 10 ++--- system/service/test/adapter_unittest.cc | 6 +-- system/stack/acl/btm_acl.cc | 2 +- system/test/headless/headless.cc | 4 +- system/test/headless/interface.h | 10 +++-- system/test/mock/mock_bluetooth_interface.cc | 3 +- system/test/mock/mock_bta_dm_act.cc | 10 +++-- system/test/mock/mock_bta_dm_act.h | 22 ++++++---- 33 files changed, 226 insertions(+), 71 deletions(-) diff --git a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp index c67ea1b5dd0..c1ac9a57272 100644 --- a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp +++ b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp @@ -367,7 +367,8 @@ static void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr, bt_acl_state_t state, int transport_link_type, bt_hci_error_code_t hci_reason, - bt_conn_direction_t direction) { + bt_conn_direction_t direction, + uint16_t acl_handle) { if (!bd_addr) { ALOGE("Address is null in %s", __func__); return; @@ -387,7 +388,8 @@ static void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr, sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback, (jint)status, addr.get(), (jint)state, - (jint)transport_link_type, (jint)hci_reason); + (jint)transport_link_type, (jint)hci_reason, + (jint)acl_handle); } static void discovery_state_changed_callback(bt_discovery_state_t state) { @@ -959,8 +961,8 @@ static void classInitNative(JNIEnv* env, jclass clazz) { method_leAddressAssociateCallback = env->GetMethodID( jniCallbackClass, "leAddressAssociateCallback", "([B[B)V"); - method_aclStateChangeCallback = - env->GetMethodID(jniCallbackClass, "aclStateChangeCallback", "(I[BIII)V"); + method_aclStateChangeCallback = env->GetMethodID( + jniCallbackClass, "aclStateChangeCallback", "(I[BIIII)V"); method_linkQualityReportCallback = env->GetMethodID( jniCallbackClass, "linkQualityReportCallback", "(JIIIIII)V"); diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java index ec9c9c8f91e..03604a957f3 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java @@ -2466,6 +2466,34 @@ public class AdapterService extends Service { return service.getConnectionState(device); } + @Override + public void getConnectionHandle(BluetoothDevice device, int transport, + AttributionSource source, SynchronousResultReceiver receiver) { + try { + receiver.send(getConnectionHandle(device, transport, source)); + } catch (RuntimeException e) { + receiver.propagateException(e); + } + } + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + private int getConnectionHandle( + BluetoothDevice device, int transport, AttributionSource attributionSource) { + AdapterService service = getService(); + if (service == null + || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setActiveDevice") + || !Utils.checkConnectPermissionForDataDelivery( + service, attributionSource, TAG)) { + return BluetoothDevice.ERROR; + } + + enforceBluetoothPrivilegedPermission(service); + + return service.getConnectionHandle(device, transport); + } + @Override public void canBondWithoutDialog(BluetoothDevice device, AttributionSource source, SynchronousResultReceiver receiver) { @@ -4453,6 +4481,14 @@ public class AdapterService extends Service { return getConnectionStateNative(getBytesFromAddress(device.getAddress())); } + int getConnectionHandle(BluetoothDevice device, int transport) { + DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); + if (deviceProp == null) { + return BluetoothDevice.ERROR; + } + return deviceProp.getConnectionHandle(transport); + } + /** * Checks whether the device was recently associated with the comapnion app that called * {@link BluetoothDevice#createBond}. This allows these devices to skip the pairing dialog if diff --git a/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java b/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java index a5c986942aa..f7108f494b2 100644 --- a/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java +++ b/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java @@ -76,9 +76,9 @@ final class JniCallbacks { } void aclStateChangeCallback(int status, byte[] address, int newState, - int transportLinkType, int hciReason) { + int transportLinkType, int hciReason, int handle) { mRemoteDevices.aclStateChangeCallback(status, address, newState, - transportLinkType, hciReason); + transportLinkType, hciReason, handle); } void stateChangeCallback(int status) { diff --git a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java index 7176fed0449..4dd5c6e7828 100644 --- a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java +++ b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java @@ -307,6 +307,8 @@ final class RemoteDevices { private String mIdentityAddress; private boolean mIsConsolidated = false; private int mBluetoothClass = BluetoothClass.Device.Major.UNCATEGORIZED; + private int mBredrConnectionHandle = BluetoothDevice.ERROR; + private int mLeConnectionHandle = BluetoothDevice.ERROR; private short mRssi; private String mAlias; private BluetoothDevice mDevice; @@ -394,6 +396,38 @@ final class RemoteDevices { } } + /** + * @param transport the transport on which the connection exists + * @return the mConnectionHandle + */ + int getConnectionHandle(int transport) { + synchronized (mObject) { + if (transport == BluetoothDevice.TRANSPORT_BREDR) { + return mBredrConnectionHandle; + } else if (transport == BluetoothDevice.TRANSPORT_LE) { + return mLeConnectionHandle; + } else { + return BluetoothDevice.ERROR; + } + } + } + + /** + * @param connectionHandle the connectionHandle to set + * @param transport the transport on which to set the handle + */ + void setConnectionHandle(int connectionHandle, int transport) { + synchronized (mObject) { + if (transport == BluetoothDevice.TRANSPORT_BREDR) { + mBredrConnectionHandle = connectionHandle; + } else if (transport == BluetoothDevice.TRANSPORT_LE) { + mLeConnectionHandle = connectionHandle; + } else { + errorLog("setConnectionHandle() unexpected transport value " + transport); + } + } + } + /** * @return the mUuids */ @@ -945,7 +979,7 @@ final class RemoteDevices { android.Manifest.permission.BLUETOOTH_PRIVILEGED, }) void aclStateChangeCallback(int status, byte[] address, int newState, - int transportLinkType, int hciReason) { + int transportLinkType, int hciReason, int handle) { if (status != AbstractionLayer.BT_STATUS_SUCCESS) { debugLog("aclStateChangeCallback status is " + status + ", skipping"); return; @@ -958,10 +992,14 @@ final class RemoteDevices { + Utils.getAddressStringFromByte(address) + ", newState=" + newState); return; } + + DeviceProperties deviceProperties = getDeviceProperties(device); + int state = mAdapterService.getState(); Intent intent = null; if (newState == AbstractionLayer.BT_ACL_STATE_CONNECTED) { + deviceProperties.setConnectionHandle(handle, transportLinkType); if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_TURNING_ON) { intent = new Intent(BluetoothDevice.ACTION_ACL_CONNECTED); intent.putExtra(BluetoothDevice.EXTRA_TRANSPORT, transportLinkType); @@ -979,6 +1017,7 @@ final class RemoteDevices { "aclStateChangeCallback: Adapter State: " + BluetoothAdapter.nameForState(state) + " Connected: " + device); } else { + deviceProperties.setConnectionHandle(BluetoothDevice.ERROR, transportLinkType); if (device.getBondState() == BluetoothDevice.BOND_BONDING) { // Send PAIRING_CANCEL intent to dismiss any dialog requesting bonding. intent = new Intent(BluetoothDevice.ACTION_PAIRING_CANCEL); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java index b7ba057d248..54a2930f947 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java @@ -296,7 +296,8 @@ public class RemoteDevicesTest { // BluetoothDevice.BATTERY_LEVEL_UNKNOWN when(mAdapterService.getState()).thenReturn(BluetoothAdapter.STATE_ON); mRemoteDevices.aclStateChangeCallback(0, Utils.getByteAddress(mDevice1), - AbstractionLayer.BT_ACL_STATE_DISCONNECTED, 2, 19); // HCI code 19 remote terminated + AbstractionLayer.BT_ACL_STATE_DISCONNECTED, 2, 19, + BluetoothDevice.ERROR); // HCI code 19 remote terminated // Verify ACTION_ACL_DISCONNECTED and BATTERY_LEVEL_CHANGED intent are sent verify(mAdapterService, times(3)).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt index 67db13f4d06..82c9095fe2c 100644 --- a/framework/api/system-current.txt +++ b/framework/api/system-current.txt @@ -172,6 +172,7 @@ package android.bluetooth { method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.bluetooth.BluetoothAudioPolicy getAudioPolicy(); method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getAudioPolicyRemoteSupported(); method @IntRange(from=0xffffff9c, to=100) @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getBatteryLevel(); + method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionHandle(int); method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public String getIdentityAddress(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getMessageAccessPermission(); method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public byte[] getMetadata(int); diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java index 8d88f26c52f..913d3102465 100644 --- a/framework/java/android/bluetooth/BluetoothDevice.java +++ b/framework/java/android/bluetooth/BluetoothDevice.java @@ -2206,6 +2206,42 @@ public final class BluetoothDevice implements Parcelable, Attributable { return false; } + /** + * Returns the ACL connection handle associated with an open connection to + * this device on the given transport. + * + * @return the ACL handle, or {@link BluetoothDevice#ERROR} if no connection currently exists on + * the given transport. + * @hide + */ + @SystemApi + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + public int getConnectionHandle(@Transport int transport) { + if (DBG) { + log("getConnectionHandle()"); + } + final IBluetooth service = getService(); + if (service == null || !isBluetoothEnabled()) { + Log.w(TAG, "Proxy not attached to service"); + if (DBG) { + log(Log.getStackTraceString(new Throwable())); + } + } else { + try { + final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get(); + service.getConnectionHandle(this, transport, mAttributionSource, recv); + return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(-1); + } catch (RemoteException | TimeoutException e) { + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + } + } + // BT is not enabled, we cannot be connected. + return BluetoothDevice.ERROR; + } + /** * Returns whether there is an open connection to this device * that has been encrypted. diff --git a/system/binder/android/bluetooth/IBluetooth.aidl b/system/binder/android/bluetooth/IBluetooth.aidl index 5a7de732235..d14b7053f0e 100644 --- a/system/binder/android/bluetooth/IBluetooth.aidl +++ b/system/binder/android/bluetooth/IBluetooth.aidl @@ -120,6 +120,8 @@ interface IBluetooth oneway void getSupportedProfiles(in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") oneway void getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") + oneway void getConnectionHandle(in BluetoothDevice device, int transport, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") oneway void getRemoteName(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc index 1352336adcc..302935377c9 100644 --- a/system/bta/dm/bta_dm_act.cc +++ b/system/bta/dm/bta_dm_act.cc @@ -2525,7 +2525,8 @@ static tBTA_DM_PEER_DEVICE* allocate_device_for(const RawAddress& bd_addr, return nullptr; } -void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport) { +void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport, + uint16_t acl_handle) { auto device = allocate_device_for(bd_addr, transport); if (device == nullptr) { LOG_WARN("Unable to allocate device resources for new connection"); @@ -2552,6 +2553,7 @@ void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport) { memset(&conn, 0, sizeof(tBTA_DM_SEC)); conn.link_up.bd_addr = bd_addr; conn.link_up.transport_link_type = transport; + conn.link_up.acl_handle = acl_handle; bta_dm_cb.p_sec_cback(BTA_DM_LINK_UP_EVT, &conn); LOG_DEBUG("Executed security callback for new connection available"); @@ -2559,8 +2561,10 @@ void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport) { bta_dm_adjust_roles(true); } -void BTA_dm_acl_up(const RawAddress bd_addr, tBT_TRANSPORT transport) { - do_in_main_thread(FROM_HERE, base::Bind(bta_dm_acl_up, bd_addr, transport)); +void BTA_dm_acl_up(const RawAddress bd_addr, tBT_TRANSPORT transport, + uint16_t acl_handle) { + do_in_main_thread(FROM_HERE, + base::Bind(bta_dm_acl_up, bd_addr, transport, acl_handle)); } static void bta_dm_acl_up_failed(const RawAddress bd_addr, diff --git a/system/bta/dm/bta_dm_int.h b/system/bta/dm/bta_dm_int.h index 1109a50cc41..8bd58c36971 100644 --- a/system/bta/dm/bta_dm_int.h +++ b/system/bta/dm/bta_dm_int.h @@ -242,7 +242,8 @@ struct tBTA_DM_PEER_DEVICE { bool in_use; private: - friend void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport); + friend void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport, + uint16_t acl_handle); friend void bta_dm_pm_btm_status(const RawAddress& bd_addr, tBTM_PM_STATUS status, uint16_t value, tHCI_STATUS hci_status); diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h index ff85ece8a9e..4331919f9e3 100644 --- a/system/bta/include/bta_api.h +++ b/system/bta/include/bta_api.h @@ -336,6 +336,7 @@ typedef struct { typedef struct { RawAddress bd_addr; /* BD address peer device. */ tBT_TRANSPORT transport_link_type; + uint16_t acl_handle; } tBTA_DM_LINK_UP; /* Structure associated with BTA_DM_LINK_UP_FAILED_EVT */ diff --git a/system/bta/include/bta_dm_acl.h b/system/bta/include/bta_dm_acl.h index a49d8ee8261..ec724851452 100644 --- a/system/bta/include/bta_dm_acl.h +++ b/system/bta/include/bta_dm_acl.h @@ -24,7 +24,8 @@ #include "types/hci_role.h" #include "types/raw_address.h" -void BTA_dm_acl_up(const RawAddress bd_addr, tBT_TRANSPORT transport); +void BTA_dm_acl_up(const RawAddress bd_addr, tBT_TRANSPORT transport, + uint16_t acl_handle); void BTA_dm_acl_up_failed(const RawAddress bd_addr, tBT_TRANSPORT transport, tHCI_STATUS hci_status); void BTA_dm_acl_down(const RawAddress bd_addr, tBT_TRANSPORT transport); diff --git a/system/btif/include/btif_common.h b/system/btif/include/btif_common.h index 4d69014a9fa..72d2117a6f9 100644 --- a/system/btif/include/btif_common.h +++ b/system/btif/include/btif_common.h @@ -225,7 +225,8 @@ void invoke_le_address_associate_cb(RawAddress main_bd_addr, void invoke_acl_state_changed_cb(bt_status_t status, RawAddress bd_addr, bt_acl_state_t state, int transport_link_type, bt_hci_error_code_t hci_reason, - bt_conn_direction_t direction); + bt_conn_direction_t direction, + uint16_t acl_handle); void invoke_thread_evt_cb(bt_cb_thread_evt event); void invoke_le_test_mode_cb(bt_status_t status, uint16_t count); void invoke_energy_info_cb(bt_activity_energy_info energy_info, diff --git a/system/btif/include/core_callbacks.h b/system/btif/include/core_callbacks.h index 12a1ac62714..16e5856bf40 100644 --- a/system/btif/include/core_callbacks.h +++ b/system/btif/include/core_callbacks.h @@ -55,7 +55,8 @@ struct EventCallbacks { bt_acl_state_t state, int transport_link_type, bt_hci_error_code_t hci_reason, - bt_conn_direction_t direction); + bt_conn_direction_t direction, + uint16_t acl_handle); void (*invoke_thread_evt_cb)(bt_cb_thread_evt event); void (*invoke_le_test_mode_cb)(bt_status_t status, uint16_t count); void (*invoke_energy_info_cb)(bt_activity_energy_info energy_info, diff --git a/system/btif/src/bluetooth.cc b/system/btif/src/bluetooth.cc index b303c3d095c..96b82330291 100644 --- a/system/btif/src/bluetooth.cc +++ b/system/btif/src/bluetooth.cc @@ -1239,17 +1239,20 @@ void invoke_le_address_associate_cb(RawAddress main_bd_addr, void invoke_acl_state_changed_cb(bt_status_t status, RawAddress bd_addr, bt_acl_state_t state, int transport_link_type, bt_hci_error_code_t hci_reason, - bt_conn_direction_t direction) { + bt_conn_direction_t direction, + uint16_t acl_handle) { do_in_jni_thread( FROM_HERE, base::BindOnce( [](bt_status_t status, RawAddress bd_addr, bt_acl_state_t state, int transport_link_type, bt_hci_error_code_t hci_reason, - bt_conn_direction_t direction) { + bt_conn_direction_t direction, uint16_t acl_handle) { HAL_CBACK(bt_hal_cbacks, acl_state_changed_cb, status, &bd_addr, - state, transport_link_type, hci_reason, direction); + state, transport_link_type, hci_reason, direction, + acl_handle); }, - status, bd_addr, state, transport_link_type, hci_reason, direction)); + status, bd_addr, state, transport_link_type, hci_reason, direction, + acl_handle)); } void invoke_thread_evt_cb(bt_cb_thread_evt event) { diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc index 84fdd66fafa..e8186ba3a73 100644 --- a/system/btif/src/btif_dm.cc +++ b/system/btif/src/btif_dm.cc @@ -1923,7 +1923,8 @@ static void btif_dm_upstreams_evt(uint16_t event, char* p_param) { (int)p_data->link_up.transport_link_type, HCI_SUCCESS, btm_is_acl_locally_initiated() ? bt_conn_direction_t::BT_CONN_DIRECTION_OUTGOING - : bt_conn_direction_t::BT_CONN_DIRECTION_INCOMING); + : bt_conn_direction_t::BT_CONN_DIRECTION_INCOMING, + p_data->link_up.acl_handle); break; case BTA_DM_LINK_UP_FAILED_EVT: @@ -1933,7 +1934,8 @@ static void btif_dm_upstreams_evt(uint16_t event, char* p_param) { p_data->link_up_failed.status, btm_is_acl_locally_initiated() ? bt_conn_direction_t::BT_CONN_DIRECTION_OUTGOING - : bt_conn_direction_t::BT_CONN_DIRECTION_INCOMING); + : bt_conn_direction_t::BT_CONN_DIRECTION_INCOMING, + INVALID_ACL_HANDLE); break; case BTA_DM_LINK_DOWN_EVT: { @@ -1961,7 +1963,7 @@ static void btif_dm_upstreams_evt(uint16_t event, char* p_param) { BT_STATUS_SUCCESS, bd_addr, BT_ACL_STATE_DISCONNECTED, (int)p_data->link_down.transport_link_type, static_cast<bt_hci_error_code_t>(btm_get_acl_disc_reason_code()), - direction); + direction, INVALID_ACL_HANDLE); LOG_DEBUG( "Sent BT_ACL_STATE_DISCONNECTED upward as ACL link down event " "device:%s reason:%s", diff --git a/system/btif/test/btif_core_test.cc b/system/btif/test/btif_core_test.cc index 9a7e6840b06..fae3b8ab954 100644 --- a/system/btif/test/btif_core_test.cc +++ b/system/btif/test/btif_core_test.cc @@ -78,7 +78,8 @@ void le_address_associate_callback(RawAddress* main_bd_addr, void acl_state_changed_callback(bt_status_t status, RawAddress* remote_bd_addr, bt_acl_state_t state, int transport_link_type, bt_hci_error_code_t hci_reason, - bt_conn_direction_t direction) {} + bt_conn_direction_t direction, + uint16_t acl_handle) {} void link_quality_report_callback(uint64_t timestamp, int report_id, int rssi, int snr, int retransmission_count, int packets_not_receive_count, diff --git a/system/gd/rust/linux/stack/src/bluetooth.rs b/system/gd/rust/linux/stack/src/bluetooth.rs index 54346a974a0..d0eb60b1154 100644 --- a/system/gd/rust/linux/stack/src/bluetooth.rs +++ b/system/gd/rust/linux/stack/src/bluetooth.rs @@ -782,6 +782,7 @@ pub(crate) trait BtifBluetoothCallbacks { link_type: BtTransport, hci_reason: BtHciErrorCode, conn_direction: BtConnectionDirection, + acl_handle: u16, ) { } @@ -1143,6 +1144,7 @@ impl BtifBluetoothCallbacks for Bluetooth { link_type: BtTransport, hci_reason: BtHciErrorCode, conn_direction: BtConnectionDirection, + acl_handle: u16, ) { if status != BtStatus::Success { warn!( diff --git a/system/gd/rust/topshim/src/btif.rs b/system/gd/rust/topshim/src/btif.rs index b5f9eab13a5..cd2d0f5aeb6 100644 --- a/system/gd/rust/topshim/src/btif.rs +++ b/system/gd/rust/topshim/src/btif.rs @@ -839,7 +839,15 @@ pub enum BaseCallbacks { BondState(BtStatus, RawAddress, BtBondState, i32), AddressConsolidate(RawAddress, RawAddress), LeAddressAssociate(RawAddress, RawAddress), - AclState(BtStatus, RawAddress, BtAclState, BtTransport, BtHciErrorCode, BtConnectionDirection), + AclState( + BtStatus, + RawAddress, + BtAclState, + BtTransport, + BtHciErrorCode, + BtConnectionDirection, + u16, + ), // Unimplemented so far: // thread_evt_cb // dut_mode_recv_cb @@ -902,7 +910,7 @@ cb_variant!(BaseCb, le_address_associate_cb -> BaseCallbacks::LeAddressAssociate }); cb_variant!(BaseCb, acl_state_cb -> BaseCallbacks::AclState, -u32 -> BtStatus, *mut RawAddress, bindings::bt_acl_state_t -> BtAclState, i32 -> BtTransport, bindings::bt_hci_error_code_t -> BtHciErrorCode, bindings::bt_conn_direction_t -> BtConnectionDirection, { +u32 -> BtStatus, *mut RawAddress, bindings::bt_acl_state_t -> BtAclState, i32 -> BtTransport, bindings::bt_hci_error_code_t -> BtHciErrorCode, bindings::bt_conn_direction_t -> BtConnectionDirection, u16 -> u16, { let _1 = unsafe { *(_1 as *const RawAddress) }; }); diff --git a/system/include/hardware/bluetooth.h b/system/include/hardware/bluetooth.h index a5e1193f674..beae42218c6 100644 --- a/system/include/hardware/bluetooth.h +++ b/system/include/hardware/bluetooth.h @@ -183,6 +183,8 @@ typedef enum { BT_CONN_DIRECTION_INCOMING } bt_conn_direction_t; +constexpr uint16_t INVALID_ACL_HANDLE = 0xFFFF; + /** Bluetooth SDP service record */ typedef struct { bluetooth::Uuid uuid; @@ -495,12 +497,10 @@ typedef void (*le_address_associate_callback)(RawAddress* main_bd_addr, RawAddress* secondary_bd_addr); /** Bluetooth ACL connection state changed callback */ -typedef void (*acl_state_changed_callback)(bt_status_t status, - RawAddress* remote_bd_addr, - bt_acl_state_t state, - int transport_link_type, - bt_hci_error_code_t hci_reason, - bt_conn_direction_t direction); +typedef void (*acl_state_changed_callback)( + bt_status_t status, RawAddress* remote_bd_addr, bt_acl_state_t state, + int transport_link_type, bt_hci_error_code_t hci_reason, + bt_conn_direction_t direction, uint16_t acl_handle); /** Bluetooth link quality report callback */ typedef void (*link_quality_report_callback)( diff --git a/system/main/shim/l2c_api.cc b/system/main/shim/l2c_api.cc index df67c648c93..9783f555a17 100644 --- a/system/main/shim/l2c_api.cc +++ b/system/main/shim/l2c_api.cc @@ -482,7 +482,7 @@ class SecurityListenerShim address_to_handle_[bda] = handle; btm_sec_connected(bda, handle, HCI_SUCCESS, 0); BTM_PM_OnConnected(handle, bda); - BTA_dm_acl_up(bda, BT_TRANSPORT_BR_EDR); + BTA_dm_acl_up(bda, BT_TRANSPORT_BR_EDR, handle); address_to_interface_[bda] = std::move(interface); } diff --git a/system/service/adapter.cc b/system/service/adapter.cc index a89477240ec..73cf8360258 100644 --- a/system/service/adapter.cc +++ b/system/service/adapter.cc @@ -693,7 +693,8 @@ class AdapterImpl : public Adapter, public hal::BluetoothInterface::Observer { const RawAddress& remote_bdaddr, bt_acl_state_t state, int transport_link_type, bt_hci_error_code_t hci_reason, - bt_conn_direction_t direction) override { + bt_conn_direction_t direction, + uint16_t acl_handle) override { std::string device_address = BtAddrString(&remote_bdaddr); bool connected = (state == BT_ACL_STATE_CONNECTED); LOG(INFO) << "ACL state changed: " << device_address diff --git a/system/service/hal/bluetooth_interface.cc b/system/service/hal/bluetooth_interface.cc index 01f2ff57145..40cc2842b09 100644 --- a/system/service/hal/bluetooth_interface.cc +++ b/system/service/hal/bluetooth_interface.cc @@ -164,7 +164,8 @@ void LeAddressAssociateCallback(RawAddress* main_bd_addr, void AclStateChangedCallback(bt_status_t status, RawAddress* remote_bd_addr, bt_acl_state_t state, int transport_link_type, bt_hci_error_code_t hci_reason, - bt_conn_direction_t direction) { + bt_conn_direction_t direction, + uint16_t acl_handle) { shared_lock<shared_mutex_impl> lock(g_instance_lock); VERIFY_INTERFACE_OR_RETURN(); CHECK(remote_bd_addr); @@ -173,9 +174,9 @@ void AclStateChangedCallback(bt_status_t status, RawAddress* remote_bd_addr, << " - BD_ADDR: " << BtAddrString(remote_bd_addr) << " - state: " << ((state == BT_ACL_STATE_CONNECTED) ? "CONNECTED" : "DISCONNECTED") << " - HCI_REASON: " << std::to_string(hci_reason); - FOR_EACH_BLUETOOTH_OBSERVER( - AclStateChangedCallback(status, *remote_bd_addr, state, - transport_link_type, hci_reason, direction)); + FOR_EACH_BLUETOOTH_OBSERVER(AclStateChangedCallback( + status, *remote_bd_addr, state, transport_link_type, hci_reason, + direction, acl_handle)); } void ThreadEventCallback(bt_cb_thread_evt evt) { @@ -454,7 +455,8 @@ void BluetoothInterface::Observer::BondStateChangedCallback( void BluetoothInterface::Observer::AclStateChangedCallback( bt_status_t /* status */, const RawAddress& /* remote_bdaddr */, bt_acl_state_t /* state */, int /* transport_link_type */, - bt_hci_error_code_t /* hci_reason */, bt_conn_direction_t /* direction */) { + bt_hci_error_code_t /* hci_reason */, bt_conn_direction_t /* direction */, + uint16_t /* acl_handle*/) { // Do nothing. } diff --git a/system/service/hal/bluetooth_interface.h b/system/service/hal/bluetooth_interface.h index 82f9f9c07a8..03b9f20e103 100644 --- a/system/service/hal/bluetooth_interface.h +++ b/system/service/hal/bluetooth_interface.h @@ -77,7 +77,8 @@ class BluetoothInterface { bt_acl_state_t state, int transport_link_type, bt_hci_error_code_t hci_reason, - bt_conn_direction_t direction); + bt_conn_direction_t direction, + uint16_t acl_handle); virtual void LinkQualityReportCallback( uint64_t timestamp, int report_id, int rssi, int snr, int retransmission_count, int packets_not_receive_count, diff --git a/system/service/hal/fake_bluetooth_interface.cc b/system/service/hal/fake_bluetooth_interface.cc index c0884f24be4..fa81ad20268 100644 --- a/system/service/hal/fake_bluetooth_interface.cc +++ b/system/service/hal/fake_bluetooth_interface.cc @@ -159,11 +159,11 @@ void FakeBluetoothInterface::NotifyAdapterLocalLeFeaturesPropertyChanged( void FakeBluetoothInterface::NotifyAclStateChangedCallback( bt_status_t status, const RawAddress& remote_bdaddr, bt_acl_state_t state, int transport_link_type, bt_hci_error_code_t hci_reason, - bt_conn_direction_t direction) { + bt_conn_direction_t direction, uint16_t acl_handle) { for (auto& observer : observers_) { observer.AclStateChangedCallback(status, remote_bdaddr, state, - transport_link_type, hci_reason, - direction); + transport_link_type, hci_reason, direction, + acl_handle); } } diff --git a/system/service/hal/fake_bluetooth_interface.h b/system/service/hal/fake_bluetooth_interface.h index 9beabe26ce7..28ed335686e 100644 --- a/system/service/hal/fake_bluetooth_interface.h +++ b/system/service/hal/fake_bluetooth_interface.h @@ -58,12 +58,10 @@ class FakeBluetoothInterface : public BluetoothInterface { void NotifyAdapterAddressPropertyChanged(const RawAddress* address); void NotifyAdapterLocalLeFeaturesPropertyChanged( const bt_local_le_features_t* features); - void NotifyAclStateChangedCallback(bt_status_t status, - const RawAddress& remote_bdaddr, - bt_acl_state_t state, - int transport_link_type, - bt_hci_error_code_t hci_reason, - bt_conn_direction_t direction); + void NotifyAclStateChangedCallback( + bt_status_t status, const RawAddress& remote_bdaddr, bt_acl_state_t state, + int transport_link_type, bt_hci_error_code_t hci_reason, + bt_conn_direction_t direction, uint16_t acl_handle); // hal::BluetoothInterface overrides: void AddObserver(Observer* observer) override; diff --git a/system/service/test/adapter_unittest.cc b/system/service/test/adapter_unittest.cc index c88dc2d6e7c..fb6a9a22633 100644 --- a/system/service/test/adapter_unittest.cc +++ b/system/service/test/adapter_unittest.cc @@ -263,7 +263,7 @@ TEST_F(AdapterTest, IsDeviceConnected) { // status != BT_STATUS_SUCCESS should be ignored fake_hal_iface_->NotifyAclStateChangedCallback( BT_STATUS_FAIL, hal_addr, BT_ACL_STATE_CONNECTED, BT_TRANSPORT_LE, 0xff, - BT_CONN_DIRECTION_OUTGOING); // HCI_ERR_UNDEFINED + BT_CONN_DIRECTION_OUTGOING, 1); // HCI_ERR_UNDEFINED EXPECT_FALSE(adapter_->IsDeviceConnected(kDeviceAddr)); EXPECT_TRUE(observer.last_connection_state_address().empty()); EXPECT_FALSE(observer.last_device_connected_state()); @@ -271,7 +271,7 @@ TEST_F(AdapterTest, IsDeviceConnected) { // Connected fake_hal_iface_->NotifyAclStateChangedCallback( BT_STATUS_SUCCESS, hal_addr, BT_ACL_STATE_CONNECTED, BT_TRANSPORT_LE, - 0x00, BT_CONN_DIRECTION_OUTGOING); // HCI_SUCCESS + 0x00, BT_CONN_DIRECTION_OUTGOING, 1); // HCI_SUCCESS EXPECT_TRUE(adapter_->IsDeviceConnected(kDeviceAddr)); EXPECT_EQ(kDeviceAddr, observer.last_connection_state_address()); EXPECT_TRUE(observer.last_device_connected_state()); @@ -279,7 +279,7 @@ TEST_F(AdapterTest, IsDeviceConnected) { // Disconnected fake_hal_iface_->NotifyAclStateChangedCallback( BT_STATUS_SUCCESS, hal_addr, BT_ACL_STATE_DISCONNECTED, BT_TRANSPORT_LE, - 0x16, BT_CONN_DIRECTION_OUTGOING); // HCI_ERR_CONN_CAUSE_LOCAL_HOST + 0x16, BT_CONN_DIRECTION_OUTGOING, 1); // HCI_ERR_CONN_CAUSE_LOCAL_HOST EXPECT_FALSE(adapter_->IsDeviceConnected(kDeviceAddr)); EXPECT_EQ(kDeviceAddr, observer.last_connection_state_address()); EXPECT_FALSE(observer.last_device_connected_state()); diff --git a/system/stack/acl/btm_acl.cc b/system/stack/acl/btm_acl.cc index add7c4a4fd7..5a2c47859ed 100644 --- a/system/stack/acl/btm_acl.cc +++ b/system/stack/acl/btm_acl.cc @@ -162,7 +162,7 @@ void NotifyAclLinkUp(tACL_CONN& p_acl) { return; } p_acl.link_up_issued = true; - BTA_dm_acl_up(p_acl.remote_addr, p_acl.transport); + BTA_dm_acl_up(p_acl.remote_addr, p_acl.transport, p_acl.hci_handle); } void NotifyAclLinkDown(tACL_CONN& p_acl) { diff --git a/system/test/headless/headless.cc b/system/test/headless/headless.cc index 74a89e57999..9006afd139e 100644 --- a/system/test/headless/headless.cc +++ b/system/test/headless/headless.cc @@ -156,7 +156,7 @@ void le_address_associate([[maybe_unused]] RawAddress* main_bd_addr, void acl_state_changed(bt_status_t status, RawAddress* remote_bd_addr, bt_acl_state_t state, int transport_link_type, bt_hci_error_code_t hci_reason, - bt_conn_direction_t direction) { + bt_conn_direction_t direction, uint16_t acl_handle) { CHECK(remote_bd_addr != nullptr); const size_t num_callbacks = interface_api_callback_map_.size(); auto callback_list = interface_api_callback_map_.find(__func__); @@ -165,7 +165,7 @@ void acl_state_changed(bt_status_t status, RawAddress* remote_bd_addr, for (auto callback : callback_list->second) { acl_state_changed_params_t params(status, raw_address, state, transport_link_type, hci_reason, - direction); + direction, acl_handle); (callback)(¶ms); } } diff --git a/system/test/headless/interface.h b/system/test/headless/interface.h index 248285b72ad..370d86138ec 100644 --- a/system/test/headless/interface.h +++ b/system/test/headless/interface.h @@ -39,14 +39,15 @@ struct acl_state_changed_params_t : public callback_params_t { acl_state_changed_params_t(bt_status_t status, RawAddress remote_bd_addr, bt_acl_state_t state, int transport_link_type, bt_hci_error_code_t hci_reason, - bt_conn_direction_t direction) + bt_conn_direction_t direction, uint16_t acl_handle) : callback_params_t("acl_state_changed"), status(status), remote_bd_addr(remote_bd_addr), state(state), transport_link_type(transport_link_type), hci_reason(hci_reason), - direction(direction) {} + direction(direction), + acl_handle(acl_handle) {} acl_state_changed_params_t(const acl_state_changed_params_t& params) = default; virtual ~acl_state_changed_params_t() {} @@ -57,17 +58,18 @@ struct acl_state_changed_params_t : public callback_params_t { int transport_link_type; bt_hci_error_code_t hci_reason; bt_conn_direction_t direction; + uint16_t acl_handle; std::string ToString() const override { return base::StringPrintf( "status:%s remote_bd_addr:%s state:%s transport:%s reason:%s " - "direction:%d", + "direction:%d handle:%d", bt_status_text(status).c_str(), remote_bd_addr.ToString().c_str(), (state == BT_ACL_STATE_CONNECTED) ? "CONNECTED" : "DISCONNECTED", bt_transport_text(static_cast<const tBT_TRANSPORT>(transport_link_type)) .c_str(), bt_status_text(static_cast<const bt_status_t>(hci_reason)).c_str(), - direction); + direction, acl_handle); } }; diff --git a/system/test/mock/mock_bluetooth_interface.cc b/system/test/mock/mock_bluetooth_interface.cc index 17be0f6e4c9..728547f6666 100644 --- a/system/test/mock/mock_bluetooth_interface.cc +++ b/system/test/mock/mock_bluetooth_interface.cc @@ -269,7 +269,8 @@ void invoke_le_address_associate_cb(RawAddress main_bd_addr, void invoke_acl_state_changed_cb(bt_status_t status, RawAddress bd_addr, bt_acl_state_t state, int transport_link_type, bt_hci_error_code_t hci_reason, - bt_conn_direction_t direction) {} + bt_conn_direction_t direction, + uint16_t acl_handle) {} void invoke_thread_evt_cb(bt_cb_thread_evt event) {} diff --git a/system/test/mock/mock_bta_dm_act.cc b/system/test/mock/mock_bta_dm_act.cc index b64f5f62fc6..5f6e2d7d750 100644 --- a/system/test/mock/mock_bta_dm_act.cc +++ b/system/test/mock/mock_bta_dm_act.cc @@ -116,9 +116,10 @@ void BTA_dm_acl_down(const RawAddress bd_addr, tBT_TRANSPORT transport) { mock_function_count_map[__func__]++; test::mock::bta_dm_act::BTA_dm_acl_down(bd_addr, transport); } -void BTA_dm_acl_up(const RawAddress bd_addr, tBT_TRANSPORT transport) { +void BTA_dm_acl_up(const RawAddress bd_addr, tBT_TRANSPORT transport, + uint16_t acl_handle) { mock_function_count_map[__func__]++; - test::mock::bta_dm_act::BTA_dm_acl_up(bd_addr, transport); + test::mock::bta_dm_act::BTA_dm_acl_up(bd_addr, transport, acl_handle); } void BTA_dm_acl_up_failed(const RawAddress bd_addr, tBT_TRANSPORT transport, tHCI_STATUS hci_status) { @@ -143,9 +144,10 @@ void BTA_dm_report_role_change(const RawAddress bd_addr, tHCI_ROLE new_role, test::mock::bta_dm_act::BTA_dm_report_role_change(bd_addr, new_role, hci_status); } -void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport) { +void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport, + uint16_t acl_handle) { mock_function_count_map[__func__]++; - test::mock::bta_dm_act::bta_dm_acl_up(bd_addr, transport); + test::mock::bta_dm_act::bta_dm_acl_up(bd_addr, transport, acl_handle); } void bta_dm_add_ble_device(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type, tBT_DEVICE_TYPE dev_type) { diff --git a/system/test/mock/mock_bta_dm_act.h b/system/test/mock/mock_bta_dm_act.h index 755e04d1815..3f2867a08c9 100644 --- a/system/test/mock/mock_bta_dm_act.h +++ b/system/test/mock/mock_bta_dm_act.h @@ -91,10 +91,13 @@ extern struct BTA_dm_acl_down BTA_dm_acl_down; // Params: const RawAddress bd_addr, tBT_TRANSPORT transport // Return: void struct BTA_dm_acl_up { - std::function<void(const RawAddress bd_addr, tBT_TRANSPORT transport)> body{ - [](const RawAddress bd_addr, tBT_TRANSPORT transport) {}}; - void operator()(const RawAddress bd_addr, tBT_TRANSPORT transport) { - body(bd_addr, transport); + std::function<void(const RawAddress bd_addr, tBT_TRANSPORT transport, + uint16_t acl_handle)> + body{[](const RawAddress bd_addr, tBT_TRANSPORT transport, + uint16_t acl_handle) {}}; + void operator()(const RawAddress bd_addr, tBT_TRANSPORT transport, + uint16_t acl_handle) { + body(bd_addr, transport, acl_handle); }; }; extern struct BTA_dm_acl_up BTA_dm_acl_up; @@ -162,10 +165,13 @@ extern struct BTA_dm_report_role_change BTA_dm_report_role_change; // Params: const RawAddress& bd_addr, tBT_TRANSPORT transport // Return: void struct bta_dm_acl_up { - std::function<void(const RawAddress& bd_addr, tBT_TRANSPORT transport)> body{ - [](const RawAddress& bd_addr, tBT_TRANSPORT transport) {}}; - void operator()(const RawAddress& bd_addr, tBT_TRANSPORT transport) { - body(bd_addr, transport); + std::function<void(const RawAddress& bd_addr, tBT_TRANSPORT transport, + uint16_t acl_handle)> + body{[](const RawAddress& bd_addr, tBT_TRANSPORT transport, + uint16_t acl_handle) {}}; + void operator()(const RawAddress& bd_addr, tBT_TRANSPORT transport, + uint16_t acl_handle) { + body(bd_addr, transport, acl_handle); }; }; extern struct bta_dm_acl_up bta_dm_acl_up; -- GitLab