Merge "Implement basic metrics for GATT." into main
diff --git a/android/app/src/com/android/bluetooth/gatt/GattService.java b/android/app/src/com/android/bluetooth/gatt/GattService.java
index 2be39b6..f6e7ea0 100644
--- a/android/app/src/com/android/bluetooth/gatt/GattService.java
+++ b/android/app/src/com/android/bluetooth/gatt/GattService.java
@@ -1334,6 +1334,13 @@
         if (app != null) {
             app.callback.onClientConnectionState(
                     status, clientIf, (status == BluetoothGatt.GATT_SUCCESS), address);
+            MetricsLogger.getInstance()
+                    .logBluetoothEvent(
+                            getDevice(address),
+                            BluetoothStatsLog
+                                    .BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__GATT_CONNECT_JAVA,
+                            connectionStatusToState(status),
+                            app.appUid);
         }
         statsLogGattConnectionStateChange(
                 BluetoothProfile.GATT, address, clientIf, connectionState, status);
@@ -1379,6 +1386,13 @@
 
         if (app != null) {
             app.callback.onClientConnectionState(status, clientIf, false, address);
+            MetricsLogger.getInstance()
+                    .logBluetoothEvent(
+                            getDevice(address),
+                            BluetoothStatsLog
+                                    .BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__GATT_DISCONNECT_JAVA,
+                            BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__SUCCESS,
+                            app.appUid);
         }
         statsLogGattConnectionStateChange(
                 BluetoothProfile.GATT,
@@ -1930,7 +1944,6 @@
         for (Map.Entry<Integer, String> entry : connMap.entrySet()) {
             Log.d(TAG, "disconnecting addr:" + entry.getValue());
             clientDisconnect(entry.getKey(), entry.getValue(), attributionSource);
-            // clientDisconnect(int clientIf, String address)
         }
     }
 
@@ -2156,6 +2169,15 @@
         }
 
         Log.d(TAG, "unregisterClient() - clientIf=" + clientIf);
+        for (ContextMap.Connection conn : mClientMap.getConnectionByApp(clientIf)) {
+            MetricsLogger.getInstance()
+                    .logBluetoothEvent(
+                            getDevice(conn.address),
+                            BluetoothStatsLog
+                                    .BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__GATT_DISCONNECT_JAVA,
+                            BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__END,
+                            attributionSource.getUid());
+        }
         mClientMap.remove(clientIf);
         mNativeInterface.gattClientUnregisterApp(clientIf);
     }
@@ -2198,6 +2220,18 @@
                 BluetoothProtoEnums.CONNECTION_STATE_CONNECTING,
                 -1);
 
+        MetricsLogger.getInstance()
+                .logBluetoothEvent(
+                        getDevice(address),
+                        BluetoothStatsLog
+                                .BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__GATT_CONNECT_JAVA,
+                        isDirect
+                                ? BluetoothStatsLog
+                                        .BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__DIRECT_CONNECT
+                                : BluetoothStatsLog
+                                        .BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__INDIRECT_CONNECT,
+                        attributionSource.getUid());
+
         int preferredMtu = 0;
 
         // Some applications expect MTU to be exchanged immediately on connections
@@ -2248,6 +2282,13 @@
                 clientIf,
                 BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTING,
                 -1);
+        MetricsLogger.getInstance()
+                .logBluetoothEvent(
+                        getDevice(address),
+                        BluetoothStatsLog
+                                .BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__GATT_DISCONNECT_JAVA,
+                        BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__START,
+                        attributionSource.getUid());
         mNativeInterface.gattClientDisconnect(clientIf, address, connId != null ? connId : 0);
     }
 
@@ -3797,6 +3838,24 @@
         mTransitionalScanHelper.dumpProto(builder);
     }
 
+    private BluetoothDevice getDevice(String address) {
+        byte[] addressBytes = Utils.getBytesFromAddress(address);
+        return mAdapterService.getDeviceFromByte(addressBytes);
+    }
+
+    private static int connectionStatusToState(int status) {
+        return switch (status) {
+                // GATT_SUCCESS
+            case 0x00 -> BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__SUCCESS;
+                // GATT_CONNECTION_TIMEOUT
+            case 0x93 ->
+                    BluetoothStatsLog
+                            .BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__CONNECTION_TIMEOUT;
+                // For now all other errors are bucketed together.
+            default -> BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__FAIL;
+        };
+    }
+
     /**************************************************************************
      * GATT Test functions
      *************************************************************************/
diff --git a/system/bta/Android.bp b/system/bta/Android.bp
index 698752d..a529367 100644
--- a/system/bta/Android.bp
+++ b/system/bta/Android.bp
@@ -428,6 +428,7 @@
         "libbluetooth_core_rs_bridge",
         "libbluetooth_crypto_toolbox",
         "libbluetooth_gd",
+        "libbluetooth_hci_pdl",
         "libbluetooth_log",
         "libbt-audio-hal-interface",
         "libbt-bta",
diff --git a/system/btif/Android.bp b/system/btif/Android.bp
index c8de253..7549459 100644
--- a/system/btif/Android.bp
+++ b/system/btif/Android.bp
@@ -504,6 +504,7 @@
     static_libs: [
         "libbluetooth-types",
         "libbluetooth_core_rs_bridge",
+        "libbluetooth_hci_pdl",
         "libbluetooth_log",
         "libbt-platform-protos-lite",
         "libchrome",
@@ -591,6 +592,7 @@
         "libbluetooth_core_rs_bridge",
         "libbluetooth_crypto_toolbox",
         "libbluetooth_gd",
+        "libbluetooth_hci_pdl",
         "libbluetooth_log",
         "libbt-audio-hal-interface",
         "libbt-common",
diff --git a/system/gd/Android.bp b/system/gd/Android.bp
index e7b3db9..b928ee2 100644
--- a/system/gd/Android.bp
+++ b/system/gd/Android.bp
@@ -254,7 +254,9 @@
         ":BluetoothFacade_hci_hal",
         ":BluetoothFacade_hci_layer",
         ":BluetoothFacade_neighbor",
+        ":TestCommonMockFunctions",
         ":TestMockMainShimStack",
+        ":TestMockStackMetrics",
         "facade/facade_main.cc",
         "facade/grpc_root_server.cc",
         "facade/read_only_property_server.cc",
@@ -280,6 +282,7 @@
         "libbluetooth_ras_pdl",
         "libbluetooth_smp_pdl",
         "libbt-common",
+        "libbt-platform-protos-lite",
         "libchrome",
         "libcom.android.sysprop.bluetooth.wrapped",
         "libflatbuffers-cpp",
@@ -425,6 +428,8 @@
         ":BluetoothOsTestSources",
         ":BluetoothPacketTestSources",
         ":BluetoothStorageUnitTestSources",
+        ":TestCommonMockFunctions",
+        ":TestMockStackMetrics",
         "module_unittest.cc",
         "stack_manager_unittest.cc",
     ],
@@ -586,8 +591,16 @@
     name: "bluetooth_gd_acl_manager_fuzz_test",
     defaults: ["gd_fuzz_defaults"],
     srcs: [
+        ":TestCommonMockFunctions",
+        ":TestMockStackMetrics",
         "hci/fuzz/acl_manager_fuzz_test.cc",
     ],
+    include_dirs: [
+        "packages/modules/Bluetooth/system",
+    ],
+    static_libs: [
+        "libbt-platform-protos-lite",
+    ],
     fuzz_config: {
         cc: ["android-bluetooth-security@google.com"],
         componentid: 27441,
diff --git a/system/gd/hci/acl_manager/le_impl.h b/system/gd/hci/acl_manager/le_impl.h
index 093b9e7..00af9b7 100644
--- a/system/gd/hci/acl_manager/le_impl.h
+++ b/system/gd/hci/acl_manager/le_impl.h
@@ -41,6 +41,7 @@
 #include "os/alarm.h"
 #include "os/handler.h"
 #include "os/system_properties.h"
+#include "stack/include/stack_metrics_logging.h"
 
 namespace bluetooth {
 namespace hci {
@@ -404,6 +405,8 @@
       return;
     }
 
+    log_le_connection_status(address, true /* is_connect */, status);
+
     const bool in_filter_accept_list = is_device_in_accept_list(remote_address);
 
     if (role == hci::Role::CENTRAL) {
@@ -560,6 +563,7 @@
       arm_on_resume_ = true;
       add_device_to_accept_list(remote_address);
     }
+    log_le_connection_status(remote_address.GetAddress(), false /* is_connect */, reason);
   }
 
   void on_le_connection_update_complete(LeMetaEventView view) {
@@ -697,6 +701,7 @@
   }
 
   void add_device_to_accept_list(AddressWithType address_with_type) {
+    log_le_device_in_accept_list(address_with_type.GetAddress(), true /* is_add */);
     if (connections.alreadyConnected(address_with_type)) {
       log::info("Device already connected, return");
       return;
@@ -719,6 +724,7 @@
   }
 
   void remove_device_from_accept_list(AddressWithType address_with_type) {
+    log_le_device_in_accept_list(address_with_type.GetAddress(), false /* is_add */);
     if (accept_list.find(address_with_type) == accept_list.end()) {
       log::warn("Device not in acceptlist and cannot be removed: {}", address_with_type);
       return;
diff --git a/system/gd/hci/class_of_device.h b/system/gd/hci/class_of_device.h
index d3a57fc..d4d53eb 100644
--- a/system/gd/hci/class_of_device.h
+++ b/system/gd/hci/class_of_device.h
@@ -43,7 +43,7 @@
   inline const uint8_t* data() const override { return cod.data(); }
 
   // storage::Serializable methods
-  std::string ToString() const;
+  std::string ToString() const override;
   static std::optional<ClassOfDevice> FromString(const std::string& str);
   std::string ToLegacyConfigString() const override;
   static std::optional<ClassOfDevice> FromLegacyConfigString(const std::string& str);
diff --git a/system/gd/metrics/bluetooth_event.h b/system/gd/metrics/bluetooth_event.h
index 89fc138..acdb7a8 100644
--- a/system/gd/metrics/bluetooth_event.h
+++ b/system/gd/metrics/bluetooth_event.h
@@ -19,6 +19,7 @@
 #include "bta/include/bta_sec_api.h"
 #include "hci/address.h"
 #include "hci/hci_packets.h"
+#include "os/metrics.h"
 #include "stack/include/btm_status.h"
 #include "stack/include/hci_error_code.h"
 #include "types/raw_address.h"
@@ -47,5 +48,7 @@
 
 void LogLePairingFail(const RawAddress& raw_address, uint8_t failure_reason, bool is_outgoing);
 
+android::bluetooth::State MapErrorCodeToState(hci::ErrorCode reason);
+
 }  // namespace metrics
 }  // namespace bluetooth
diff --git a/system/main/shim/metrics_api.cc b/system/main/shim/metrics_api.cc
index 4ee87ce..65491b2 100644
--- a/system/main/shim/metrics_api.cc
+++ b/system/main/shim/metrics_api.cc
@@ -16,7 +16,6 @@
 
 #include "main/shim/metrics_api.h"
 
-#include "hci/address.h"
 #include "main/shim/entry.h"
 #include "main/shim/helpers.h"
 #include "metrics/bluetooth_event.h"
@@ -156,6 +155,33 @@
   bluetooth::metrics::LogLePairingFail(raw_address, failure_reason, is_outgoing);
 }
 
+void LogMetricLeConnectionStatus(hci::Address address, bool is_connect, hci::ErrorCode reason) {
+  bluetooth::os::LogMetricBluetoothEvent(
+          address,
+          is_connect ? android::bluetooth::EventType::GATT_CONNECT_NATIVE
+                     : android::bluetooth::EventType::GATT_DISCONNECT_NATIVE,
+          bluetooth::metrics::MapErrorCodeToState(reason));
+}
+
+void LogMetricLeDeviceInAcceptList(hci::Address address, bool is_add) {
+  bluetooth::os::LogMetricBluetoothEvent(
+          address, android::bluetooth::EventType::LE_DEVICE_IN_ACCEPT_LIST,
+          is_add ? android::bluetooth::State::START : android::bluetooth::State::END);
+}
+
+void LogMetricLeConnectionLifecycle(hci::Address address, bool is_connect, bool is_direct) {
+  if (is_connect) {
+    bluetooth::os::LogMetricBluetoothEvent(address,
+                                           android::bluetooth::EventType::GATT_CONNECT_NATIVE,
+                                           is_direct ? android::bluetooth::State::DIRECT_CONNECT
+                                                     : android::bluetooth::State::INDIRECT_CONNECT);
+  } else {
+    bluetooth::os::LogMetricBluetoothEvent(address,
+                                           android::bluetooth::EventType::GATT_DISCONNECT_NATIVE,
+                                           android::bluetooth::State::START);
+  }
+}
+
 bool CountCounterMetrics(int32_t key, int64_t count) {
   auto counter_metrics = GetCounterMetrics();
   if (counter_metrics == nullptr) {
diff --git a/system/main/shim/metrics_api.h b/system/main/shim/metrics_api.h
index c030d7c..c0165b0 100644
--- a/system/main/shim/metrics_api.h
+++ b/system/main/shim/metrics_api.h
@@ -20,6 +20,8 @@
 #include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h>
 #include <frameworks/proto_logging/stats/enums/bluetooth/le/enums.pb.h>
 
+#include "hci/address.h"
+#include "hci/hci_packets.h"
 #include "os/metrics.h"
 #include "types/raw_address.h"
 
@@ -256,6 +258,29 @@
 void LogMetricLePairingFail(const RawAddress& raw_address, uint8_t failure_reason,
                             bool is_outgoing);
 
+/**
+ * Logs GATT connect/disconnect status
+ * @param address Address of the device
+ * @param is_connect indicates connection or disconnection
+ * @param reason the reason/status for the connection event
+ */
+void LogMetricLeConnectionStatus(hci::Address address, bool is_connect, hci::ErrorCode reason);
+
+/**
+ * Logs LE filter accept list events
+ * @param address Address of the device
+ * @param is_add indicates addition or removal of the device in the accept list
+ */
+void LogMetricLeDeviceInAcceptList(hci::Address address, bool is_connect);
+
+/**
+ * Logs GATT lifecycle events
+ * @param address Address of the device
+ * @param is_connect indicates connection or disconnection
+ * @param is_direct indicates direct or background connection, ignored for disconnection
+ */
+void LogMetricLeConnectionLifecycle(hci::Address address, bool is_connect, bool is_direct);
+
 bool CountCounterMetrics(int32_t key, int64_t count);
 
 }  // namespace shim
diff --git a/system/stack/Android.bp b/system/stack/Android.bp
index 06b2ce1..fd80589 100644
--- a/system/stack/Android.bp
+++ b/system/stack/Android.bp
@@ -437,6 +437,7 @@
     static_libs: [
         "bluetooth_flags_c_lib",
         "libbluetooth-types",
+        "libbluetooth_hci_pdl",
         "libbluetooth_log",
         "libbt-platform-protos-lite",
     ],
@@ -1513,6 +1514,7 @@
         "libbluetooth_core_rs_bridge",
         "libbluetooth_crypto_toolbox",
         "libbluetooth_gd",
+        "libbluetooth_hci_pdl",
         "libbluetooth_log",
         "libbt-common",
         "libbt-platform-protos-lite",
@@ -1887,6 +1889,7 @@
         "libbase",
         "libbluetooth-types",
         "libbluetooth_crypto_toolbox",
+        "libbluetooth_hci_pdl",
         "libbluetooth_log",
         "libbt-common",
         "libbt-platform-protos-lite",
@@ -1961,6 +1964,7 @@
         "libbase",
         "libbluetooth-types",
         "libbluetooth_gd",
+        "libbluetooth_hci_pdl",
         "libbluetooth_log",
         "libbt-common",
         "libbt-platform-protos-lite",
@@ -2027,6 +2031,7 @@
         ":TestMockStackAcl",
         ":TestMockStackBtm",
         ":TestMockStackL2cap",
+        ":TestMockStackMetrics",
         ":TestMockStackSdp",
         ":TestMockStackSmp",
         "ais/ais_ble.cc",
@@ -2241,6 +2246,7 @@
         "libbluetooth-types",
         "libbluetooth_core_rs_bridge",
         "libbluetooth_gd",
+        "libbluetooth_hci_pdl",
         "libbluetooth_log",
         "libbt-common",
         "libbt-platform-protos-lite",
@@ -2418,6 +2424,7 @@
         "libbase",
         "libbluetooth-types",
         "libbluetooth_gd",
+        "libbluetooth_hci_pdl",
         "libbluetooth_log",
         "libbt-common",
         "libbt-platform-protos-lite",
diff --git a/system/stack/gatt/gatt_api.cc b/system/stack/gatt/gatt_api.cc
index 3f2c713..fa42e91 100644
--- a/system/stack/gatt/gatt_api.cc
+++ b/system/stack/gatt/gatt_api.cc
@@ -33,6 +33,7 @@
 
 #include "internal_include/bt_target.h"
 #include "internal_include/stack_config.h"
+#include "main/shim/helpers.h"
 #include "os/system_properties.h"
 #include "osi/include/allocator.h"
 #include "stack/arbiter/acl_arbiter.h"
@@ -47,6 +48,7 @@
 #include "stack/include/l2cap_interface.h"
 #include "stack/include/l2cdefs.h"
 #include "stack/include/sdp_api.h"
+#include "stack/include/stack_metrics_logging.h"
 #include "types/bluetooth/uuid.h"
 #include "types/bt_transport.h"
 #include "types/raw_address.h"
@@ -1472,6 +1474,8 @@
     return true;
   }
 
+  log_le_connection_lifecycle(ToGdAddress(bd_addr), true /* is_connect */, is_direct);
+
   bool ret = false;
   if (is_direct) {
     log::debug("Starting direct connect gatt_if={} address={} transport={}", gatt_if, bd_addr,
@@ -1619,6 +1623,9 @@
     return GATT_ILLEGAL_PARAMETER;
   }
 
+  log_le_connection_lifecycle(ToGdAddress(p_tcb->peer_bda), true /* is_connect */,
+                              false /* is_direct */);
+
   tGATT_IF gatt_if = gatt_get_gatt_if(conn_id);
   gatt_update_app_use_link_flag(gatt_if, p_tcb, false, true);
   return GATT_SUCCESS;
diff --git a/system/stack/include/stack_metrics_logging.h b/system/stack/include/stack_metrics_logging.h
index 912d5a5..dda02a0 100644
--- a/system/stack/include/stack_metrics_logging.h
+++ b/system/stack/include/stack_metrics_logging.h
@@ -21,6 +21,8 @@
 
 #include <cstdint>
 
+#include "hci/address.h"
+#include "hci/hci_packets.h"
 #include "types/raw_address.h"
 
 void log_classic_pairing_event(const RawAddress& address, uint16_t handle, uint32_t hci_cmd,
@@ -55,3 +57,10 @@
                                  int codec_type);
 
 void log_le_pairing_fail(const RawAddress& raw_address, uint8_t failure_reason, bool is_outgoing);
+
+void log_le_connection_status(bluetooth::hci::Address address, bool is_connect,
+                              bluetooth::hci::ErrorCode reason);
+
+void log_le_device_in_accept_list(bluetooth::hci::Address address, bool is_add);
+
+void log_le_connection_lifecycle(bluetooth::hci::Address address, bool is_connect, bool is_direct);
diff --git a/system/stack/metrics/stack_metrics_logging.cc b/system/stack/metrics/stack_metrics_logging.cc
index 4a6326f..ffe7a43 100644
--- a/system/stack/metrics/stack_metrics_logging.cc
+++ b/system/stack/metrics/stack_metrics_logging.cc
@@ -81,3 +81,16 @@
 void log_le_pairing_fail(const RawAddress& raw_address, uint8_t failure_reason, bool is_outgoing) {
   bluetooth::shim::LogMetricLePairingFail(raw_address, failure_reason, is_outgoing);
 }
+
+void log_le_connection_status(bluetooth::hci::Address address, bool is_connect,
+                              bluetooth::hci::ErrorCode reason) {
+  bluetooth::shim::LogMetricLeConnectionStatus(address, is_connect, reason);
+}
+
+void log_le_device_in_accept_list(bluetooth::hci::Address address, bool is_add) {
+  bluetooth::shim::LogMetricLeDeviceInAcceptList(address, is_add);
+}
+
+void log_le_connection_lifecycle(bluetooth::hci::Address address, bool is_connect, bool is_direct) {
+  bluetooth::shim::LogMetricLeConnectionLifecycle(address, is_connect, is_direct);
+}
diff --git a/system/test/mock/mock_main_shim_metrics_api.cc b/system/test/mock/mock_main_shim_metrics_api.cc
index ffe5a46..841cd75 100644
--- a/system/test/mock/mock_main_shim_metrics_api.cc
+++ b/system/test/mock/mock_main_shim_metrics_api.cc
@@ -55,6 +55,9 @@
 struct LogMetricSdpAttribute LogMetricSdpAttribute;
 struct LogMetricSocketConnectionState LogMetricSocketConnectionState;
 struct LogMetricManufacturerInfo LogMetricManufacturerInfo;
+struct LogMetricLeConnectionStatus LogMetricLeConnectionStatus;
+struct LogMetricLeDeviceInAcceptList LogMetricLeDeviceInAcceptList;
+struct LogMetricLeConnectionLifecycle LogMetricLeConnectionLifecycle;
 
 }  // namespace main_shim_metrics_api
 }  // namespace mock
@@ -190,4 +193,18 @@
   inc_func_call_count(__func__);
   return false;
 }
+void bluetooth::shim::LogMetricLeConnectionStatus(bluetooth::hci::Address address, bool is_connect,
+                                                  bluetooth::hci::ErrorCode reason) {
+  inc_func_call_count(__func__);
+  test::mock::main_shim_metrics_api::LogMetricLeConnectionStatus(address, is_connect, reason);
+}
+void bluetooth::shim::LogMetricLeDeviceInAcceptList(bluetooth::hci::Address address, bool is_add) {
+  inc_func_call_count(__func__);
+  test::mock::main_shim_metrics_api::LogMetricLeDeviceInAcceptList(address, is_add);
+}
+void bluetooth::shim::LogMetricLeConnectionLifecycle(bluetooth::hci::Address address,
+                                                     bool is_connect, bool is_direct) {
+  inc_func_call_count(__func__);
+  test::mock::main_shim_metrics_api::LogMetricLeConnectionLifecycle(address, is_connect, is_direct);
+}
 // END mockcify generation
diff --git a/system/test/mock/mock_main_shim_metrics_api.h b/system/test/mock/mock_main_shim_metrics_api.h
index 401b5a0..f5f177b 100644
--- a/system/test/mock/mock_main_shim_metrics_api.h
+++ b/system/test/mock/mock_main_shim_metrics_api.h
@@ -28,6 +28,8 @@
 // Original included files, if any
 // #include <frameworks/proto_logging/stats/enums/bluetooth/le/enums.pb.h>
 
+#include "hci/address.h"
+#include "hci/hci_packets.h"
 #include "os/metrics.h"
 #include "types/raw_address.h"
 
@@ -312,6 +314,42 @@
   }
 };
 extern struct LogMetricManufacturerInfo LogMetricManufacturerInfo;
+// Name: LogMetricLeConnectionStatus
+// Params: bluetooth::hci::Address address, bool is_connect, bluetooth::hci::ErrorCode reason
+// Returns: void
+struct LogMetricLeConnectionStatus {
+  std::function<void(bluetooth::hci::Address address, bool is_connect,
+                     bluetooth::hci::ErrorCode reason)>
+          body{[](bluetooth::hci::Address /* address */, bool /* is_connect */,
+                  bluetooth::hci::ErrorCode /* reason */) {}};
+  void operator()(bluetooth::hci::Address address, bool is_connect,
+                  bluetooth::hci::ErrorCode reason) {
+    body(address, is_connect, reason);
+  }
+};
+extern struct LogMetricLeConnectionStatus LogMetricLeConnectionStatus;
+// Name: LogMetricLeDeviceInAcceptList
+// Params: bluetooth::hci::Address address, bool is_add
+// Returns: void
+struct LogMetricLeDeviceInAcceptList {
+  std::function<void(bluetooth::hci::Address address, bool is_add)> body{
+          [](bluetooth::hci::Address /* address */, bool /* is_add */) {}};
+  void operator()(bluetooth::hci::Address address, bool is_add) { body(address, is_add); }
+};
+extern struct LogMetricLeDeviceInAcceptList LogMetricLeDeviceInAcceptList;
+
+// Name: LogMetricLeConnectionLifecycle
+// Params: bluetooth::hci::Address address, bool is_connect, bool is_direct
+// Returns: void
+struct LogMetricLeConnectionLifecycle {
+  std::function<void(bluetooth::hci::Address address, bool is_connect, bool is_direct)> body{
+          [](bluetooth::hci::Address /* address */, bool /* is_connect */, bool /* is_direct */) {
+          }};
+  void operator()(bluetooth::hci::Address address, bool is_connect, bool is_direct) {
+    body(address, is_connect, is_direct);
+  }
+};
+extern struct LogMetricLeConnectionLifecycle LogMetricLeConnectionLifecycle;
 
 }  // namespace main_shim_metrics_api
 }  // namespace mock
diff --git a/system/test/mock/mock_stack_metrics_logging.cc b/system/test/mock/mock_stack_metrics_logging.cc
index 76ddee2..f233666 100644
--- a/system/test/mock/mock_stack_metrics_logging.cc
+++ b/system/test/mock/mock_stack_metrics_logging.cc
@@ -52,6 +52,9 @@
 struct log_counter_metrics log_counter_metrics;
 struct log_hfp_audio_packet_loss_stats log_hfp_audio_packet_loss_stats;
 struct log_mmc_transcode_rtt_stats log_mmc_transcode_rtt_stats;
+struct log_le_connection_status log_le_connection_status;
+struct log_le_device_in_accept_list log_le_device_in_accept_list;
+struct log_le_connection_lifecycle log_le_connection_lifecycle;
 
 }  // namespace stack_metrics_logging
 }  // namespace mock
@@ -133,4 +136,20 @@
   test::mock::stack_metrics_logging::log_mmc_transcode_rtt_stats(maximum_rtt, mean_rtt,
                                                                  num_requests, codec_type);
 }
+
+void log_le_connection_status(bluetooth::hci::Address address, bool is_connect,
+                              bluetooth::hci::ErrorCode reason) {
+  inc_func_call_count(__func__);
+  test::mock::stack_metrics_logging::log_le_connection_status(address, is_connect, reason);
+}
+
+void log_le_device_in_accept_list(bluetooth::hci::Address address, bool is_add) {
+  inc_func_call_count(__func__);
+  test::mock::stack_metrics_logging::log_le_device_in_accept_list(address, is_add);
+}
+
+void log_le_connection_lifecycle(bluetooth::hci::Address address, bool is_connect, bool is_direct) {
+  inc_func_call_count(__func__);
+  test::mock::stack_metrics_logging::log_le_connection_lifecycle(address, is_connect, is_direct);
+}
 // END mockcify generation
diff --git a/system/test/mock/mock_stack_metrics_logging.h b/system/test/mock/mock_stack_metrics_logging.h
index beb3650..413cbea 100644
--- a/system/test/mock/mock_stack_metrics_logging.h
+++ b/system/test/mock/mock_stack_metrics_logging.h
@@ -27,6 +27,8 @@
 #include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
 #include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h>
 
+#include "hci/address.h"
+#include "hci/hci_packets.h"
 #include "types/raw_address.h"
 
 // Mocked compile conditionals, if any
@@ -199,6 +201,39 @@
   }
 };
 extern struct log_mmc_transcode_rtt_stats log_mmc_transcode_rtt_stats;
+
+// Name: log_le_connection_status
+struct log_le_connection_status {
+  std::function<void(bluetooth::hci::Address address, bool is_connect,
+                     bluetooth::hci::ErrorCode reason)>
+          body{[](bluetooth::hci::Address /* address */, bool /* is_connect */,
+                  bluetooth::hci::ErrorCode /* reason */) {}};
+  void operator()(bluetooth::hci::Address address, bool is_connect,
+                  bluetooth::hci::ErrorCode reason) {
+    body(address, is_connect, reason);
+  }
+};
+extern struct log_le_connection_status log_le_connection_status;
+
+// Name: log_le_device_in_accept_list
+struct log_le_device_in_accept_list {
+  std::function<void(bluetooth::hci::Address address, bool is_add)> body{
+          [](bluetooth::hci::Address /* address */, bool /* is_add */) {}};
+  void operator()(bluetooth::hci::Address address, bool is_add) { body(address, is_add); }
+};
+extern struct log_le_device_in_accept_list log_le_device_in_accept_list;
+
+// Name: log_le_connection_lifecycle
+struct log_le_connection_lifecycle {
+  std::function<void(bluetooth::hci::Address address, bool is_connect, bool is_direct)> body{
+          [](bluetooth::hci::Address /* address */, bool /* is_connect */, bool /* is_direct */) {
+          }};
+  void operator()(bluetooth::hci::Address address, bool is_connect, bool is_direct) {
+    body(address, is_connect, is_direct);
+  }
+};
+extern struct log_le_device_in_accept_list log_le_device_in_accept_list;
+
 }  // namespace stack_metrics_logging
 }  // namespace mock
 }  // namespace test