diff --git a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
index c67ea1b5dd043cfd18cdc026ce2f1c6fa9ab2c68..c1ac9a572720643e8ab17e00089dd88ac96179ac 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 ec9c9c8f91e0263795c0bbbadbe0a709baa5f8bb..03604a957f3b17603d5e3be4706180fe22d11665 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 a5c986942aa89a1fbb42b51b6dbb286a233dccf1..f7108f494b29612eb32efb9cb3390c034aeada49 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 7176fed0449e59944f1b922121a459183e257f5f..4dd5c6e7828ee4c6e1c2d5c9c8750c1a8a810f0c 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 b7ba057d2487c137010e519b0a45c20b8c65fbd8..54a2930f947ed45f982735f36b60ea4e1af8b724 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 67db13f4d0666fdd88348918d0e29080d244d845..82c9095fe2c6f661cc0fb5aac67d1c2ee6a4acb8 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 8d88f26c52f7b7e775c6b681ac00d5184043e2b3..913d310246554c4cc743d0dd97b748466a2f9551 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 5a7de732235a727abf1d51ba1bb52d40a9d1a390..d14b7053f0e8eead8ffb17f473ba2dee1d9aff73 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 1352336adcc26f5c06849be4bc46ed32fa5961a9..302935377c9a357c6abfe6b591e56256d50c4f57 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 1109a50cc41d341c1f5add1fa396e2e307991c31..8bd58c3697193fd1dcc01a547247a64984f06b0d 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 ff85ece8a9efb7b88a5c8ae6414548e3d7fda5bc..4331919f9e32ea9257e8b9d1e8e4dd026380ee16 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 a49d8ee8261758a9029debea4aa410df8acb243a..ec724851452bc85f537a57d1053ad688db15b86a 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 4d69014a9faa94617d5b785e3629f6dd3c6f9f91..72d2117a6f900fed914139c5c86df561b419d101 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 12a1ac6271496f7d90f0bae0300d800b5514fef0..16e5856bf408aafe7690c6e1c5cde775fb3cbd22 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 b303c3d095c5370ea0cf097c18a9c016902f576d..96b823302919c235bcebdb92649d7fd2f9efb920 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 84fdd66fafa69b45170f73a98fa3c25d3fd3dd39..e8186ba3a73b5813b6dde91a7c29a8d734b753b3 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 9a7e6840b063959bb16992ae77dd30527e2c2730..fae3b8ab954a119e281f2f5a2b0896ed5d170346 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 54346a974a07a043f350f33234fc83669ed95fc3..d0eb60b11546d71bb0de03e326ddb761dfeddc76 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 b5f9eab13a56370e5ecd2f50b4d374802622bb06..cd2d0f5aeb6a59bc1528910ae2cbd4688c6ad830 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 a5e1193f67432a2b3f618a2e9a8084caf29e030e..beae42218c642b83c498e56a3c28a9a9e21bbcc7 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 df67c648c93d69179a1914812f121d284cb8d6b1..9783f555a171f6c9ede8ce460c950855b638356f 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 a89477240ec43e830eee82c5974e26173fbdba29..73cf8360258d52c21cb3feec8129b977c8cf434f 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 01f2ff5714553311f8e397bf25a6e3e2944c613a..40cc2842b095a4e023c7e0ee7ddf6a3ee7ebfa25 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 82f9f9c07a8c8297e9f914ebf533b7f9feec51c2..03b9f20e10327024dfaa74b1e295bbf7eae5e11f 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 c0884f24be4dac1149c34436647409c4c4a94b1f..fa81ad20268e510eab97424e45f29ee0ace2f97d 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 9beabe26ce728ac456a8fe75cb5656304a43bea6..28ed335686e6ecb0ce9d4199ff81f4ebd5356a29 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 c88dc2d6e7cca13968c34c894ab13605e40f6b5b..fb6a9a22633f62cd247e20a4db34568bba0cc5cf 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 add7c4a4fd7f0f0e348f5dafddd980e9f27c96ee..5a2c47859ed03b0428f57c4bfd6d4b51f7440d5d 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 74a89e57999c4945832e54944c38bb0a944e8064..9006afd139e17f754aa2bd61cc126845a3763299 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)(&params);
     }
   }
diff --git a/system/test/headless/interface.h b/system/test/headless/interface.h
index 248285b72ade184a6a297b81fc730e817c4fd55a..370d86138ec85771c14fb63ff8dd44337e24b593 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 17be0f6e4c978b18da7b80c12a640217d3f2d6b6..728547f6666f32d5bd8c99457fabc8939b82eb80 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 b64f5f62fc6de231792522db51f777554c52edfe..5f6e2d7d750b835b312e8c0759f73b68c0ada0c1 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 755e04d1815ad60ad342b1785901d37f44f73f34..3f2867a08c9d62faa1f0fea8dfbb722c290bc132 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;