Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5180e69e authored by Archie Pusaka's avatar Archie Pusaka
Browse files

floss: metrics: gather and emit remote device info metrics

These are emitted when device is connected and when we receive a new
property. The behavior is a bit different than the existing one in
BlueZ, but it wouldn't matter much since duplicates are removed by
the backend service.

Bug: 240782193
Tag: #floss
Test: Verify DeviceInfoReport are logged upon connection and upon
      restarting floss.

BYPASS_LONG_LINES_REASON: Bluetooth likes 120 lines

Change-Id: I9d63cb04ae228a79033557d9d681c5a29d58438d
parent 45bfb168
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -27,6 +27,11 @@
namespace bluetooth {
namespace metrics {

static constexpr uint32_t DEVICE_MAJOR_CLASS_MASK = 0x1F00;
static constexpr uint32_t DEVICE_MAJOR_CLASS_BIT_OFFSET = 8;
static constexpr uint32_t DEVICE_CATEGORY_MASK = 0xFFC0;
static constexpr uint32_t DEVICE_CATEGORY_BIT_OFFSET = 6;

void LogMetricsAdapterStateChanged(uint32_t state) {
  int64_t adapter_state;
  int64_t boot_time;
@@ -107,5 +112,55 @@ void LogMetricsBondStateChanged(
      .Record();
}

void LogMetricsDeviceInfoReport(
    RawAddress* addr,
    uint32_t device_type,
    uint32_t class_of_device,
    uint32_t appearance,
    uint32_t vendor_id,
    uint32_t vendor_id_src,
    uint32_t product_id,
    uint32_t version) {
  int64_t boot_time;
  std::string addr_string;
  std::string boot_id;
  uint32_t major_class;
  uint32_t category;

  if (!GetBootId(&boot_id)) return;

  addr_string = addr->ToString();
  boot_time = bluetooth::common::time_get_os_boottime_us();

  major_class = (class_of_device & DEVICE_MAJOR_CLASS_MASK) >> DEVICE_MAJOR_CLASS_BIT_OFFSET;
  category = (appearance & DEVICE_CATEGORY_MASK) >> DEVICE_CATEGORY_BIT_OFFSET;

  LOG_DEBUG(
      "DeviceInfoReport %s %d %s %d %d %d %d %d %d %d",
      boot_id.c_str(),
      boot_time,
      addr_string.c_str(),
      device_type,
      major_class,
      category,
      vendor_id,
      vendor_id_src,
      product_id,
      version);

  ::metrics::structured::events::bluetooth::BluetoothDeviceInfoReport()
      .SetBootId(boot_id)
      .SetSystemTime(boot_time)
      .SetDeviceId(addr_string)
      .SetDeviceType(device_type)
      .SetDeviceClass(major_class)
      .SetDeviceCategory(category)
      .SetVendorId(vendor_id)
      .SetVendorIdSource(vendor_id_src)
      .SetProductId(product_id)
      .SetProductVersion(version)
      .Record();
}

}  // namespace metrics
}  // namespace bluetooth
+10 −0
Original line number Diff line number Diff line
@@ -27,5 +27,15 @@ void LogMetricsBondCreateAttempt(RawAddress* addr, uint32_t device_type) {}
void LogMetricsBondStateChanged(
    RawAddress* addr, uint32_t device_type, uint32_t status, uint32_t bond_state, int32_t fail_reason) {}

void LogMetricsDeviceInfoReport(
    RawAddress* addr,
    uint32_t device_type,
    uint32_t class_of_device,
    uint32_t appearance,
    uint32_t vendor_id,
    uint32_t vendor_id_src,
    uint32_t product_id,
    uint32_t version) {}

}  // namespace metrics
}  // namespace bluetooth
+9 −0
Original line number Diff line number Diff line
@@ -26,6 +26,15 @@ void LogMetricsAdapterStateChanged(uint32_t state);
void LogMetricsBondCreateAttempt(RawAddress* addr, uint32_t device_type);
void LogMetricsBondStateChanged(
    RawAddress* addr, uint32_t device_type, uint32_t status, uint32_t bond_state, int32_t fail_reason);
void LogMetricsDeviceInfoReport(
    RawAddress* addr,
    uint32_t device_type,
    uint32_t class_of_device,
    uint32_t appearance,
    uint32_t vendor_id,
    uint32_t vendor_id_src,
    uint32_t product_id,
    uint32_t version);

}  // namespace metrics
}  // namespace bluetooth
+39 −2
Original line number Diff line number Diff line
@@ -3,8 +3,8 @@
use bt_topshim::btif::{
    BaseCallbacks, BaseCallbacksDispatcher, BluetoothInterface, BluetoothProperty, BtAclState,
    BtBondState, BtConnectionState, BtDeviceType, BtDiscoveryState, BtHciErrorCode, BtPinCode,
    BtPropertyType, BtScanMode, BtSspVariant, BtState, BtStatus, BtTransport, RawAddress, Uuid,
    Uuid128Bit,
    BtPropertyType, BtScanMode, BtSspVariant, BtState, BtStatus, BtTransport, BtVendorProductInfo,
    RawAddress, Uuid, Uuid128Bit,
};
use bt_topshim::{
    metrics,
@@ -527,6 +527,40 @@ impl Bluetooth {
            self.internal_le_rand_queue.push_back(promise);
        }
    }

    fn send_metrics_remote_device_info(device: &BluetoothDeviceContext) {
        if device.bond_state != BtBondState::Bonded && device.acl_state != BtAclState::Connected {
            return;
        }

        let addr = RawAddress::from_string(device.info.address.clone()).unwrap();
        let mut class_of_device = 0u32;
        let mut device_type = BtDeviceType::Unknown;
        let mut appearance = 0u16;
        let mut vpi =
            BtVendorProductInfo { vendor_id_src: 0, vendor_id: 0, product_id: 0, version: 0 };

        for prop in device.properties.values() {
            match prop {
                BluetoothProperty::TypeOfDevice(p) => device_type = p.clone(),
                BluetoothProperty::ClassOfDevice(p) => class_of_device = p.clone(),
                BluetoothProperty::Appearance(p) => appearance = p.clone(),
                BluetoothProperty::VendorProductInfo(p) => vpi = p.clone(),
                _ => (),
            }
        }

        metrics::device_info_report(
            addr,
            device_type,
            class_of_device,
            appearance,
            vpi.vendor_id,
            vpi.vendor_id_src,
            vpi.product_id,
            vpi.version,
        );
    }
}

#[btif_callbacks_dispatcher(Bluetooth, dispatch_base_callbacks, BaseCallbacks)]
@@ -869,6 +903,8 @@ impl BtifBluetoothCallbacks for Bluetooth {
                d.update_properties(properties);
                d.seen();

                Bluetooth::send_metrics_remote_device_info(d);

                let info = d.info.clone();
                let uuids = self.get_remote_uuids(info.clone());
                if self.wait_to_connect && uuids.len() > 0 {
@@ -921,6 +957,7 @@ impl BtifBluetoothCallbacks for Bluetooth {

                    match state {
                        BtAclState::Connected => {
                            Bluetooth::send_metrics_remote_device_info(found);
                            self.connection_callbacks.for_all_callbacks(|callback| {
                                callback.on_device_connected(device.clone());
                            });
+15 −0
Original line number Diff line number Diff line
@@ -44,6 +44,21 @@ void bond_state_changed(
  metrics::LogMetricsBondStateChanged(&addr, device_type, status, bond_state, fail_reason);
}

void device_info_report(
    RustRawAddress bt_addr,
    uint32_t device_type,
    uint32_t class_of_device,
    uint32_t appearance,
    uint32_t vendor_id,
    uint32_t vendor_id_src,
    uint32_t product_id,
    uint32_t version) {
  RawAddress addr = rusty::CopyFromRustAddress(bt_addr);

  metrics::LogMetricsDeviceInfoReport(
      &addr, device_type, class_of_device, appearance, vendor_id, vendor_id_src, product_id, version);
}

}  // namespace rust
}  // namespace topshim
}  // namespace bluetooth
Loading