debug: make BT Activities an individual module

Bug: 429523093
Test: presubmit, atest bluetooth_hal_bluetooth_activities_test
Flag: EXEMPT, refactor
Change-Id: I30bc4cc77f819c6e41877ebcdcd8f733e1f23071
diff --git a/bluetooth/bluetooth_hal/debug/bluetooth_activities.cc b/bluetooth/bluetooth_hal/debug/bluetooth_activities.cc
index 01bf024..6323210 100644
--- a/bluetooth/bluetooth_hal/debug/bluetooth_activities.cc
+++ b/bluetooth/bluetooth_hal/debug/bluetooth_activities.cc
@@ -22,8 +22,12 @@
 #include <sys/types.h>
 
 #include <cstdint>
+#include <list>
+#include <memory>
+#include <mutex>
 #include <sstream>
 #include <string>
+#include <unordered_map>
 
 #include "android-base/logging.h"
 #include "bluetooth_hal/bluetooth_address.h"
@@ -31,6 +35,7 @@
 #include "bluetooth_hal/hal_packet.h"
 #include "bluetooth_hal/hal_types.h"
 #include "bluetooth_hal/hci_monitor.h"
+#include "bluetooth_hal/hci_router_client.h"
 #include "bluetooth_hal/util/logging.h"
 
 namespace bluetooth_hal {
@@ -38,6 +43,7 @@
 namespace {
 
 using ::bluetooth_hal::hci::BleMetaEventSubCode;
+using ::bluetooth_hal::hci::BluetoothAddress;
 using ::bluetooth_hal::hci::EventCode;
 using ::bluetooth_hal::hci::EventResultCode;
 using ::bluetooth_hal::hci::HalPacket;
@@ -66,7 +72,50 @@
 
 }  // namespace
 
-BluetoothActivities::BluetoothActivities()
+class BluetoothActivitiesImpl : public BluetoothActivities,
+                                public ::bluetooth_hal::hci::HciRouterClient {
+ public:
+  BluetoothActivitiesImpl();
+
+  bool HasConnectedDevice() const;
+  void HandleBleMetaEvent(const ::bluetooth_hal::hci::HalPacket& event);
+  void HandleConnectCompleteEvent(const ::bluetooth_hal::hci::HalPacket& event);
+  void HandleDisconnectCompleteEvent(
+      const ::bluetooth_hal::hci::HalPacket& event);
+
+  void OnCommandCallback(
+      [[maybe_unused]] const ::bluetooth_hal::hci::HalPacket& packet) override {
+  };
+  void OnMonitorPacketCallback(
+      ::bluetooth_hal::hci::MonitorMode mode,
+      const ::bluetooth_hal::hci::HalPacket& packet) override;
+  void OnBluetoothChipReady() override {};
+  void OnBluetoothChipClosed() override;
+  void OnBluetoothEnabled() override {};
+  void OnBluetoothDisabled() override {};
+
+ private:
+  struct ConnectionActivity {
+    uint16_t connection_handle;
+    BluetoothAddress bd_address;
+    std::string event;
+    std::string status;
+    std::string timestamp;
+  };
+
+  void UpdateConnectionHistory(const ConnectionActivity& device);
+
+  HciBleMetaEventMonitor ble_connection_complete_event_monitor_;
+  HciBleMetaEventMonitor ble_enhanced_connection_complete_v1_event_monitor_;
+  HciBleMetaEventMonitor ble_enhanced_connection_complete_v2_event_monitor_;
+  HciEventMonitor connection_complete_event_monitor_;
+  HciEventMonitor disconnection_complete_event_monitor_;
+
+  std::list<ConnectionActivity> connection_history_;
+  std::unordered_map<uint16_t, BluetoothAddress> connected_device_address_;
+};
+
+BluetoothActivitiesImpl::BluetoothActivitiesImpl()
     : ble_connection_complete_event_monitor_(HciBleMetaEventMonitor(
           static_cast<uint8_t>(BleMetaEventSubCode::kConnectionComplete))),
       ble_enhanced_connection_complete_v1_event_monitor_(
@@ -85,11 +134,31 @@
   RegisterMonitor(disconnection_complete_event_monitor_, MonitorMode::kMonitor);
 }
 
-bool BluetoothActivities::HasConnectedDevice() {
+std::unique_ptr<BluetoothActivities> BluetoothActivities::instance_;
+std::mutex BluetoothActivities::mutex_;
+
+void BluetoothActivities::Start() { BluetoothActivities::Get(); }
+
+BluetoothActivities& BluetoothActivities::Get() {
+  std::lock_guard<std::mutex> lock(mutex_);
+  if (!instance_) {
+    instance_ = std::make_unique<BluetoothActivitiesImpl>();
+  }
+  return *instance_;
+}
+
+void BluetoothActivities::Stop() {
+  if (!instance_) {
+    return;
+  }
+  instance_.reset();
+}
+
+bool BluetoothActivitiesImpl::HasConnectedDevice() const {
   return connected_device_address_.size() > 0;
 }
 
-void BluetoothActivities::OnMonitorPacketCallback(
+void BluetoothActivitiesImpl::OnMonitorPacketCallback(
     [[maybe_unused]] MonitorMode mode, const HalPacket& packet) {
   switch (packet.GetEventCode()) {
     case static_cast<uint8_t>(EventCode::kBleMeta):
@@ -104,7 +173,11 @@
   }
 }
 
-void BluetoothActivities::HandleBleMetaEvent(const HalPacket& event) {
+void BluetoothActivitiesImpl::OnBluetoothChipClosed() {
+  connected_device_address_.clear();
+}
+
+void BluetoothActivitiesImpl::HandleBleMetaEvent(const HalPacket& event) {
   uint8_t event_status = event.At(kBleConnectionEventStatusOffset);
   ConnectionActivity activity{
       .connection_handle =
@@ -125,7 +198,8 @@
   }
 }
 
-void BluetoothActivities::HandleConnectCompleteEvent(const HalPacket& event) {
+void BluetoothActivitiesImpl::HandleConnectCompleteEvent(
+    const HalPacket& event) {
   uint8_t event_status = event.At(kConnectionEventStatusOffset);
   ConnectionActivity activity{
       .connection_handle = event.AtUint16LittleEndian(kConnectionHandleOffset),
@@ -145,7 +219,7 @@
   }
 }
 
-void BluetoothActivities::HandleDisconnectCompleteEvent(
+void BluetoothActivitiesImpl::HandleDisconnectCompleteEvent(
     const HalPacket& event) {
   uint8_t event_status = event.At(kDisconnectionEventStatusOffset);
   ConnectionActivity activity{
@@ -167,7 +241,7 @@
   }
 }
 
-void BluetoothActivities::UpdateConnectionHistory(
+void BluetoothActivitiesImpl::UpdateConnectionHistory(
     const ConnectionActivity& device) {
   if (connection_history_.size() >= kBtMaxConnectHistoryRecord) {
     connection_history_.pop_front();
diff --git a/bluetooth/bluetooth_hal/debug/bluetooth_activities_test.cc b/bluetooth/bluetooth_hal/debug/bluetooth_activities_test.cc
index 449fad0..654ff6b 100644
--- a/bluetooth/bluetooth_hal/debug/bluetooth_activities_test.cc
+++ b/bluetooth/bluetooth_hal/debug/bluetooth_activities_test.cc
@@ -20,7 +20,7 @@
 #include <gtest/gtest.h>
 
 #include <cstdint>
-#include <memory>
+#include <utility>
 
 #include "bluetooth_hal/bluetooth_address.h"
 #include "bluetooth_hal/hal_packet.h"
@@ -41,7 +41,6 @@
 using ::bluetooth_hal::hci::MockHciRouterClientAgent;
 using ::bluetooth_hal::hci::MonitorMode;
 using ::testing::_;
-using ::testing::NotNull;
 using ::testing::Return;
 using ::testing::Test;
 
@@ -51,26 +50,6 @@
 constexpr size_t kBleEnhancedConnectionCompleteV1EventLength = 34;
 constexpr size_t kBleEnhancedConnectionCompleteV2EventLength = 37;
 
-class BluetoothActivitiesForTest : public BluetoothActivities {
- public:
-  void OnMonitorPacketCallback(MonitorMode mode,
-                               const HalPacket& packet) override {
-    BluetoothActivities::OnMonitorPacketCallback(mode, packet);
-  }
-
-  void EnableBluetooth() {
-    OnBluetoothChipReady();
-    OnBluetoothEnabled();
-    OnHalStateChanged(HalState::kRunning, HalState::kBtChipReady);
-    OnPacketCallback(HalPacket({0x04, 0x0E, 0x04, 0x01, 0x03, 0x0C, 0x00}));
-  }
-
-  void DisableBluetooth() {
-    OnBluetoothDisabled();
-    OnBluetoothChipClosed();
-  }
-};
-
 struct BtDeviceForTest {
   uint16_t connection_handle;
   BluetoothAddress bd_address;
@@ -155,21 +134,17 @@
  protected:
   void SetUp() override {
     MockHciRouterClientAgent::SetMockAgent(&mock_hci_router_client_agent_);
-    EXPECT_CALL(mock_hci_router_client_agent_, RegisterRouterClient(NotNull()))
-        .WillOnce(Return(true));
-
     MockHciRouter::SetMockRouter(&mock_hci_router_);
     ON_CALL(mock_hci_router_, Send(_)).WillByDefault(Return(true));
     ON_CALL(mock_hci_router_, SendCommand(_, _)).WillByDefault(Return(true));
 
-    bluetooth_activities = std::make_unique<BluetoothActivitiesForTest>();
+    BluetoothActivities::Start();
+    EnableBluetooth();
   }
 
   void TearDown() override {
-    EXPECT_CALL(mock_hci_router_client_agent_,
-                UnregisterRouterClient(bluetooth_activities.get()))
-        .WillOnce(Return(true));
-    bluetooth_activities.reset();
+    BluetoothActivities::Stop();
+    DisableBluetooth();
   }
 
   void EnableBluetooth() {
@@ -179,7 +154,6 @@
         .WillByDefault(Return(true));
     ON_CALL(mock_hci_router_client_agent_, IsBluetoothEnabled())
         .WillByDefault(Return(true));
-    bluetooth_activities->EnableBluetooth();
   }
 
   void DisableBluetooth() {
@@ -189,16 +163,13 @@
         .WillByDefault(Return(false));
     ON_CALL(mock_hci_router_client_agent_, IsBluetoothEnabled())
         .WillByDefault(Return(false));
-    bluetooth_activities->DisableBluetooth();
   }
   MockHciRouter mock_hci_router_;
   MockHciRouterClientAgent mock_hci_router_client_agent_;
-  std::unique_ptr<BluetoothActivitiesForTest> bluetooth_activities;
 };
 
 TEST_F(BluetoothActivitiesTest, InitialState) {
-  EnableBluetooth();
-  EXPECT_FALSE(bluetooth_activities->HasConnectedDevice());
+  EXPECT_FALSE(BluetoothActivities::Get().HasConnectedDevice());
 }
 
 class ConnectionAndDisconnectionTest
@@ -206,16 +177,15 @@
       public ::testing::WithParamInterface<HalPacket> {};
 
 TEST_P(ConnectionAndDisconnectionTest, ConnectionAndDisconnection) {
-  EnableBluetooth();
-  EXPECT_FALSE(bluetooth_activities->HasConnectedDevice());
+  EXPECT_FALSE(BluetoothActivities::Get().HasConnectedDevice());
 
-  bluetooth_activities->OnMonitorPacketCallback(MonitorMode::kMonitor,
-                                                GetParam());
-  EXPECT_TRUE(bluetooth_activities->HasConnectedDevice());
+  BluetoothActivities::Get().OnMonitorPacketCallback(MonitorMode::kMonitor,
+                                                     GetParam());
+  EXPECT_TRUE(BluetoothActivities::Get().HasConnectedDevice());
 
-  bluetooth_activities->OnMonitorPacketCallback(
+  BluetoothActivities::Get().OnMonitorPacketCallback(
       MonitorMode::kMonitor, CreateDisconnectionCompleteEvent(device_1, true));
-  EXPECT_FALSE(bluetooth_activities->HasConnectedDevice());
+  EXPECT_FALSE(BluetoothActivities::Get().HasConnectedDevice());
 }
 
 INSTANTIATE_TEST_SUITE_P(
@@ -234,24 +204,23 @@
        MultiDeviceConnectionsAndDisconnections) {
   const auto& [device_1_connection_event, device_2_connection_event] =
       GetParam();
-  EnableBluetooth();
-  EXPECT_FALSE(bluetooth_activities->HasConnectedDevice());
+  EXPECT_FALSE(BluetoothActivities::Get().HasConnectedDevice());
 
-  bluetooth_activities->OnMonitorPacketCallback(MonitorMode::kMonitor,
-                                                device_1_connection_event);
-  EXPECT_TRUE(bluetooth_activities->HasConnectedDevice());
+  BluetoothActivities::Get().OnMonitorPacketCallback(MonitorMode::kMonitor,
+                                                     device_1_connection_event);
+  EXPECT_TRUE(BluetoothActivities::Get().HasConnectedDevice());
 
-  bluetooth_activities->OnMonitorPacketCallback(MonitorMode::kMonitor,
-                                                device_2_connection_event);
-  EXPECT_TRUE(bluetooth_activities->HasConnectedDevice());
+  BluetoothActivities::Get().OnMonitorPacketCallback(MonitorMode::kMonitor,
+                                                     device_2_connection_event);
+  EXPECT_TRUE(BluetoothActivities::Get().HasConnectedDevice());
 
-  bluetooth_activities->OnMonitorPacketCallback(
+  BluetoothActivities::Get().OnMonitorPacketCallback(
       MonitorMode::kMonitor, CreateDisconnectionCompleteEvent(device_1, true));
-  EXPECT_TRUE(bluetooth_activities->HasConnectedDevice());
+  EXPECT_TRUE(BluetoothActivities::Get().HasConnectedDevice());
 
-  bluetooth_activities->OnMonitorPacketCallback(
+  BluetoothActivities::Get().OnMonitorPacketCallback(
       MonitorMode::kMonitor, CreateDisconnectionCompleteEvent(device_2, true));
-  EXPECT_FALSE(bluetooth_activities->HasConnectedDevice());
+  EXPECT_FALSE(BluetoothActivities::Get().HasConnectedDevice());
 }
 
 INSTANTIATE_TEST_SUITE_P(
@@ -278,12 +247,11 @@
                            public ::testing::WithParamInterface<HalPacket> {};
 
 TEST_P(ConnectionFailTest, ConnectionFail) {
-  EnableBluetooth();
-  EXPECT_FALSE(bluetooth_activities->HasConnectedDevice());
+  EXPECT_FALSE(BluetoothActivities::Get().HasConnectedDevice());
 
-  bluetooth_activities->OnMonitorPacketCallback(MonitorMode::kMonitor,
-                                                GetParam());
-  EXPECT_FALSE(bluetooth_activities->HasConnectedDevice());
+  BluetoothActivities::Get().OnMonitorPacketCallback(MonitorMode::kMonitor,
+                                                     GetParam());
+  EXPECT_FALSE(BluetoothActivities::Get().HasConnectedDevice());
 }
 
 INSTANTIATE_TEST_SUITE_P(
diff --git a/bluetooth/bluetooth_hal/include/public/bluetooth_hal/debug/bluetooth_activities.h b/bluetooth/bluetooth_hal/include/public/bluetooth_hal/debug/bluetooth_activities.h
index 28b4c1a..27495eb 100644
--- a/bluetooth/bluetooth_hal/include/public/bluetooth_hal/debug/bluetooth_activities.h
+++ b/bluetooth/bluetooth_hal/include/public/bluetooth_hal/debug/bluetooth_activities.h
@@ -16,68 +16,60 @@
 
 #pragma once
 
-#include <cstdint>
-#include <list>
-#include <string>
-#include <unordered_map>
+#include <memory>
+#include <mutex>
 
-#include "bluetooth_hal/bluetooth_address.h"
 #include "bluetooth_hal/hal_packet.h"
-#include "bluetooth_hal/hci_monitor.h"
-#include "bluetooth_hal/hci_router_client.h"
 
 namespace bluetooth_hal {
 namespace debug {
 
-class BluetoothActivities : public ::bluetooth_hal::hci::HciRouterClient {
+class BluetoothActivities {
  public:
-  BluetoothActivities();
+  virtual ~BluetoothActivities() = default;
+
+  /**
+   * @brief Start the activities monitoring process.
+   *
+   * This function should be called before any other functions in this class are
+   * used.
+   */
+  static void Start();
+
+  /**
+   * @brief Get the singleton instance of BluetoothActivities.
+   *
+   * @return The singleton instance of BluetoothActivities.
+   */
+  static BluetoothActivities& Get();
+
+  /**
+   * @brief Stop the activities monitoring process, and clear the connections.
+   *
+   * After calling this function, all of the current connections and the
+   * connection history will be cleared. The instance will be reset.
+   */
+  static void Stop();
 
   /**
    * @brief Checks if there are any connected Bluetooth devices.
    *
    * @return true if there is at least one connected device, false otherwise.
    */
-  bool HasConnectedDevice();
+  virtual bool HasConnectedDevice() const = 0;
+
+  virtual void OnMonitorPacketCallback(
+      ::bluetooth_hal::hci::MonitorMode mode,
+      const ::bluetooth_hal::hci::HalPacket& packet) = 0;
+
+  virtual void OnBluetoothChipClosed() = 0;
 
  protected:
-  void OnCommandCallback(
-      [[maybe_unused]] const ::bluetooth_hal::hci::HalPacket& packet) override {
-  };
-  void OnMonitorPacketCallback(
-      ::bluetooth_hal::hci::MonitorMode mode,
-      const ::bluetooth_hal::hci::HalPacket& packet) override;
-  void OnBluetoothChipReady() override {};
-  void OnBluetoothChipClosed() override {};
-  void OnBluetoothEnabled() override {};
-  void OnBluetoothDisabled() override {};
+  BluetoothActivities() = default;
 
  private:
-  struct ConnectionActivity {
-    uint16_t connection_handle;
-    ::bluetooth_hal::hci::BluetoothAddress bd_address;
-    std::string event;
-    std::string status;
-    std::string timestamp;
-  };
-
-  void UpdateConnectionHistory(const ConnectionActivity& device);
-  void HandleBleMetaEvent(const ::bluetooth_hal::hci::HalPacket& event);
-  void HandleConnectCompleteEvent(const ::bluetooth_hal::hci::HalPacket& event);
-  void HandleDisconnectCompleteEvent(
-      const ::bluetooth_hal::hci::HalPacket& event);
-
-  ::bluetooth_hal::hci::HciBleMetaEventMonitor
-      ble_connection_complete_event_monitor_;
-  ::bluetooth_hal::hci::HciBleMetaEventMonitor
-      ble_enhanced_connection_complete_v1_event_monitor_;
-  ::bluetooth_hal::hci::HciBleMetaEventMonitor
-      ble_enhanced_connection_complete_v2_event_monitor_;
-  ::bluetooth_hal::hci::HciEventMonitor connection_complete_event_monitor_;
-  ::bluetooth_hal::hci::HciEventMonitor disconnection_complete_event_monitor_;
-  std::list<ConnectionActivity> connection_history_;
-  std::unordered_map<uint16_t, ::bluetooth_hal::hci::BluetoothAddress>
-      connected_device_address_;
+  static std::unique_ptr<BluetoothActivities> instance_;
+  static std::mutex mutex_;
 };
 
 }  // namespace debug
diff --git a/bluetooth/bluetooth_hal/include/public/bluetooth_hal/debug/debug_central.h b/bluetooth/bluetooth_hal/include/public/bluetooth_hal/debug/debug_central.h
index b7b5f6c..daa6e71 100644
--- a/bluetooth/bluetooth_hal/include/public/bluetooth_hal/debug/debug_central.h
+++ b/bluetooth/bluetooth_hal/include/public/bluetooth_hal/debug/debug_central.h
@@ -32,7 +32,6 @@
 #include "bluetooth_hal/bqr/bqr_handler.h"
 #include "bluetooth_hal/bqr/bqr_root_inflammation_event.h"
 #include "bluetooth_hal/bqr/bqr_types.h"
-#include "bluetooth_hal/debug/bluetooth_activities.h"
 #include "bluetooth_hal/debug/debug_client.h"
 #include "bluetooth_hal/debug/debug_monitor.h"
 #include "bluetooth_hal/debug/debug_types.h"
@@ -235,7 +234,6 @@
   std::map<AnchorType, std::pair<std::string, std::string>> anchor_log_;
   ::bluetooth_hal::util::Timer debug_info_command_timer_;
   DebugMonitor debug_monitor_;
-  BluetoothActivities bluetooth_activities_;
   ::bluetooth_hal::bqr::BqrHandler bqr_handler_;
   std::unordered_set<DebugClient*> debug_clients_;
   bool is_coredump_generated_;