From c66d849aec0c5f3f95ca593bee756e1565b04f05 Mon Sep 17 00:00:00 2001
From: David Duarte <licorne@google.com>
Date: Tue, 15 Mar 2022 13:23:07 +0000
Subject: [PATCH] RootCanal: Fix device registration

Test: m root-canal
Change-Id: I8b2a7f18c84c699678a2936d139038c8cf483682
---
 tools/rootcanal/Android.bp                    | 102 +++++++++---------
 tools/rootcanal/model/setup/device_boutique.h |   8 --
 tools/rootcanal/model/setup/test_model.cc     |  31 +-----
 tools/rootcanal/model/setup/test_model.h      |   4 +-
 4 files changed, 56 insertions(+), 89 deletions(-)

diff --git a/tools/rootcanal/Android.bp b/tools/rootcanal/Android.bp
index 9ed1dd1dd4e..d2d893a7c07 100644
--- a/tools/rootcanal/Android.bp
+++ b/tools/rootcanal/Android.bp
@@ -12,13 +12,61 @@ package {
     ],
 }
 
-cc_library_static {
-    name: "libbt-rootcanal",
+cc_defaults {
+    name: "rootcanal_defaults",
     defaults: [
         "gd_defaults",
         "gd_clang_tidy",
         "gd_clang_tidy_ignore_android",
     ],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-fvisibility=hidden",
+    ],
+    local_include_dirs: [
+        "include",
+    ],
+    include_dirs: [
+        "packages/modules/Bluetooth/system",
+        "packages/modules/Bluetooth/system/gd",
+    ],
+    generated_headers: [
+        "RootCanalGeneratedPackets_h",
+        "BluetoothGeneratedPackets_h",
+        "libbt_init_flags_bridge_header",
+    ],
+}
+
+// Compile devices and device boutique into a single object to force the linker
+// to pick all the symbols for static registration to work
+cc_object {
+    name: "libbt-rootcanal-devices",
+    defaults: ["rootcanal_defaults"],
+    host_supported: true,
+    proprietary: true,
+    cflags: ["-fPIC"],
+    srcs: [
+        "model/devices/beacon.cc",
+        "model/devices/beacon_swarm.cc",
+        "model/devices/broken_adv.cc",
+        "model/devices/car_kit.cc",
+        "model/devices/classic.cc",
+        "model/devices/keyboard.cc",
+        "model/devices/loopback.cc",
+        "model/devices/scripted_beacon.cc",
+        "model/devices/sniffer.cc",
+        "model/setup/device_boutique.cc",
+    ],
+    static_libs: [
+        "libscriptedbeaconpayload-protos-lite",
+    ]
+}
+
+cc_library_static {
+    name: "libbt-rootcanal",
+    defaults: ["rootcanal_defaults"],
     host_supported: true,
     proprietary: true,
     srcs: [
@@ -30,11 +78,6 @@ cc_library_static {
         "model/controller/link_layer_controller.cc",
         "model/controller/sco_connection.cc",
         "model/controller/security_manager.cc",
-        "model/devices/beacon.cc",
-        "model/devices/beacon_swarm.cc",
-        "model/devices/broken_adv.cc",
-        "model/devices/car_kit.cc",
-        "model/devices/classic.cc",
         "model/devices/device.cc",
         "model/devices/device_properties.cc",
         "model/devices/h4_data_channel_packetizer.cc",
@@ -42,14 +85,9 @@ cc_library_static {
         "model/devices/h4_parser.cc",
         "model/devices/hci_protocol.cc",
         "model/devices/hci_socket_device.cc",
-        "model/devices/keyboard.cc",
         "model/devices/link_layer_socket_device.cc",
-        "model/devices/loopback.cc",
         "model/devices/remote_loopback_device.cc",
-        "model/devices/scripted_beacon.cc",
-        "model/devices/sniffer.cc",
         "model/setup/async_manager.cc",
-        "model/setup/device_boutique.cc",
         "model/setup/phy_layer_factory.cc",
         "model/setup/test_channel_transport.cc",
         "model/setup/test_command_handler.cc",
@@ -60,35 +98,17 @@ cc_library_static {
         ":BluetoothPacketSources",
         ":BluetoothHciClassSources",
         ":BluetoothCryptoToolboxSources",
-    ],
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-        "-fvisibility=hidden",
-    ],
-    local_include_dirs: [
-        "include",
+        ":libbt-rootcanal-devices",
     ],
     export_include_dirs: [
         "include",
         ".",
     ],
-    generated_headers: [
-        "RootCanalGeneratedPackets_h",
-        "BluetoothGeneratedPackets_h",
-        "libbt_init_flags_bridge_header",
-    ],
-    include_dirs: [
-        "packages/modules/Bluetooth/system",
-        "packages/modules/Bluetooth/system/gd",
-    ],
     shared_libs: [
         "liblog",
     ],
     static_libs: [
         "libjsoncpp",
-        "libscriptedbeaconpayload-protos-lite",
     ],
 }
 
@@ -149,9 +169,7 @@ cc_test_host {
 // Linux RootCanal Executable
 cc_binary_host {
     name: "root-canal",
-    defaults: [
-        "gd_clang_tidy",
-    ],
+    defaults: ["rootcanal_defaults"],
     srcs: [
         "desktop/root_canal_main.cc",
         "desktop/test_environment.cc",
@@ -159,17 +177,6 @@ cc_binary_host {
     header_libs: [
         "libbluetooth_headers",
     ],
-    local_include_dirs: [
-        "include",
-    ],
-    include_dirs: [
-        "packages/modules/Bluetooth/system",
-        "packages/modules/Bluetooth/system/gd",
-    ],
-    generated_headers: [
-        "RootCanalGeneratedPackets_h",
-        "BluetoothGeneratedPackets_h",
-    ],
     shared_libs: [
         "liblog",
         "libbacktrace",
@@ -182,11 +189,6 @@ cc_binary_host {
         "breakpad_client",
         "libgflags",
     ],
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
     sanitize: {
         address: true,
         all_undefined: true,
diff --git a/tools/rootcanal/model/setup/device_boutique.h b/tools/rootcanal/model/setup/device_boutique.h
index 51965c5c8fc..a07b48c5e04 100644
--- a/tools/rootcanal/model/setup/device_boutique.h
+++ b/tools/rootcanal/model/setup/device_boutique.h
@@ -39,14 +39,6 @@ class DeviceBoutique {
   // Call the constructor that matches arg[0], then call dev->Initialize(args).
   static std::shared_ptr<Device> Create(const std::vector<std::string>& args);
 
-  template <typename D>
-  struct Registrar {
-    explicit Registrar(std::string const& name) {
-      DeviceBoutique::Register(name, &D::Create);
-    }
-    static Registrar<D> registrar_;
-  };
-
  private:
   static std::unordered_map<std::string,
                             std::function<std::shared_ptr<Device>()>>&
diff --git a/tools/rootcanal/model/setup/test_model.cc b/tools/rootcanal/model/setup/test_model.cc
index 5fe6ff9c0bc..643a2b19d3d 100644
--- a/tools/rootcanal/model/setup/test_model.cc
+++ b/tools/rootcanal/model/setup/test_model.cc
@@ -24,30 +24,12 @@
 #include <type_traits>  // for remove_extent_t
 #include <utility>      // for move
 
-#include "include/phy.h"
-#include "include/phy.h"  // for Phy, Phy::Type
-#include "model/devices/hci_socket_device.h"
-#include "model/devices/link_layer_socket_device.h"
-#include "os/log.h"
-// TODO: Remove when registration works
-#include "model/devices/beacon.h"                    // for Beacon
-#include "model/devices/beacon_swarm.h"              // for BeaconSwarm
-#include "model/devices/car_kit.h"                   // for CarKit
-#include "model/devices/classic.h"                   // for Classic
+#include "include/phy.h"                             // for Phy, Phy::Type
 #include "model/devices/hci_socket_device.h"         // for HciSocketDevice
-#include "model/devices/keyboard.h"                  // for Keyboard
-#include "model/devices/link_layer_socket_device.h"  // for LinkLayerSocketD...
-#include "model/devices/remote_loopback_device.h"    // for RemoteLoopbackDe...
-#include "model/devices/scripted_beacon.h"           // for ScriptedBeacon
-#include "model/devices/sniffer.h"                   // for Sniffer
-#include "model/setup/phy_layer_factory.h"           // for PhyLayerFactory
-#include "model/setup/test_channel_transport.h"      // for AsyncDataChannel
-#include "net/async_data_channel.h"                  // for AsyncDataChannel
+#include "model/devices/link_layer_socket_device.h"  // for LinkLayerSocketDevice
 #include "os/log.h"                                  // for LOG_WARN, LOG_INFO
-#include "packets/link_layer_packets.h"              // for LinkLayerPacketView
 
 namespace rootcanal {
-class Device;
 
 TestModel::TestModel(
     std::function<AsyncUserId()> get_user_id,
@@ -70,15 +52,6 @@ TestModel::TestModel(
       cancel_tasks_from_user_(std::move(cancel_tasks_from_user)),
       connect_to_remote_(std::move(connect_to_remote)) {
   model_user_id_ = get_user_id_();
-  // TODO: Remove when registration works!
-  example_devices_.push_back(std::make_shared<Beacon>());
-  example_devices_.push_back(std::make_shared<BeaconSwarm>());
-  example_devices_.push_back(std::make_shared<Keyboard>());
-  example_devices_.push_back(std::make_shared<CarKit>());
-  example_devices_.push_back(std::make_shared<Classic>());
-  example_devices_.push_back(std::make_shared<Sniffer>());
-  example_devices_.push_back(std::make_shared<ScriptedBeacon>());
-  example_devices_.push_back(std::make_shared<RemoteLoopbackDevice>());
 }
 
 void TestModel::SetTimerPeriod(std::chrono::milliseconds new_period) {
diff --git a/tools/rootcanal/model/setup/test_model.h b/tools/rootcanal/model/setup/test_model.h
index 91ff42abe61..dd9681503c1 100644
--- a/tools/rootcanal/model/setup/test_model.h
+++ b/tools/rootcanal/model/setup/test_model.h
@@ -25,7 +25,6 @@
 #include <vector>      // for vector
 
 #include "hci/address.h"                       // for Address
-#include "model/devices/device_properties.h"   // for Address
 #include "model/setup/async_manager.h"         // for AsyncUserId, AsyncTaskId
 #include "net/async_data_channel.h"            // for AsyncDataChannel
 #include "net/async_data_channel_connector.h"  // for AsyncDataChannelConnector
@@ -36,6 +35,8 @@
 namespace rootcanal {
 class Device;
 
+using ::bluetooth::hci::Address;
+
 using android::net::AsyncDataChannel;
 using android::net::AsyncDataChannelConnector;
 
@@ -131,7 +132,6 @@ class TestModel {
   AsyncTaskId timer_tick_task_{kInvalidTaskId};
   std::chrono::milliseconds timer_period_{};
 
-  std::vector<std::shared_ptr<Device>> example_devices_;
   std::shared_ptr<AsyncDataChannelConnector> socket_connector_;
 };
 
-- 
GitLab