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

Commit db2190a5 authored by Michael Sun's avatar Michael Sun
Browse files

floss: metrics: convert device type into BlueZ compatible type

When reporting device type for paring/bonding state changes, BlueZ uses
connection types (LE v.s., BREDR) instead of device type
(LE, BREDR, DUAL). Update the Floss metrics to use the same
conventions.

However, minimal information is available regarding the paring/bonding
over which connection type at the Floss. Even the bond initiator can
use the "auto" type without specifying LE v.s., BREDR. So the type
matching is through best effort. A previously recorded connection type
will apply to the following metrics event, and an "auto" connection or
DUAL type device will be categorized as  UNKNOWN before submission.

BUG: 240781725
Tag: #floss
Test: emerge-${BOARD} floss
BYPASS_LONG_LINES_REASON: Bluetooth likes 120 lines

Change-Id: I9063ed5039d671d3ad8c79a0167eb180edac4367
parent 4d93a6bd
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ void LogMetricsAdapterStateChanged(uint32_t state) {
}

void LogMetricsBondCreateAttempt(RawAddress* addr, uint32_t device_type) {
  ConnectionType connection_type;
  int64_t boot_time;
  std::string addr_string;
  std::string boot_id;
@@ -62,26 +63,28 @@ void LogMetricsBondCreateAttempt(RawAddress* addr, uint32_t device_type) {

  addr_string = addr->ToString();
  boot_time = bluetooth::common::time_get_os_boottime_us();
  connection_type = ToPairingDeviceType(addr_string, device_type);

  LOG_DEBUG(
      "PairingStateChanged: %s, %d, %s, %d, %d",
      boot_id.c_str(),
      boot_time,
      addr_string.c_str(),
      device_type,
      connection_type,
      PairingState::PAIR_STARTING);

  ::metrics::structured::events::bluetooth::BluetoothPairingStateChanged()
      .SetBootId(boot_id)
      .SetSystemTime(boot_time)
      .SetDeviceId(addr_string)
      .SetDeviceType(device_type)
      .SetDeviceType((int64_t)connection_type)
      .SetPairingState((int64_t)PairingState::PAIR_STARTING)
      .Record();
}

void LogMetricsBondStateChanged(
    RawAddress* addr, uint32_t device_type, uint32_t status, uint32_t bond_state, int32_t fail_reason) {
  ConnectionType connection_type;
  int64_t boot_time;
  PairingState pairing_state;
  std::string addr_string;
@@ -91,6 +94,7 @@ void LogMetricsBondStateChanged(

  addr_string = addr->ToString();
  boot_time = bluetooth::common::time_get_os_boottime_us();
  connection_type = ToPairingDeviceType(addr_string, device_type);
  pairing_state = ToPairingState(status, bond_state, fail_reason);

  // Ignore the start of pairing event as its logged separated above.
@@ -101,14 +105,14 @@ void LogMetricsBondStateChanged(
      boot_id.c_str(),
      boot_time,
      addr_string.c_str(),
      device_type,
      connection_type,
      pairing_state);

  ::metrics::structured::events::bluetooth::BluetoothPairingStateChanged()
      .SetBootId(boot_id)
      .SetSystemTime(boot_time)
      .SetDeviceId(addr_string)
      .SetDeviceType(device_type)
      .SetDeviceType((int64_t)connection_type)
      .SetPairingState((int64_t)pairing_state)
      .Record();
}
+30 −0
Original line number Diff line number Diff line
@@ -32,6 +32,14 @@ typedef bt_status_t BtStatus;
// topshim::profile::hid_host::BthhConnectionState is a copy of hardware/bluetooth.h:bthh_connection_state_t
typedef bthh_connection_state_t BthhConnectionState;

// A copy of topshim::btif::BtDeviceType
enum class BtDeviceType {
  Unknown = 0,
  Bredr,
  Ble,
  Dual,
};

// A normalized connection state ENUM definition all profiles
enum class ProfilesConnectionState {
  DISCONNECTED = 0,
@@ -199,6 +207,28 @@ AdapterState ToAdapterState(uint32_t state) {
  return state == 1 ? AdapterState::ON : AdapterState::OFF;
}

ConnectionType ToPairingDeviceType(std::string addr, uint32_t device_type) {
  // A map stores the pending ConnectionType used to match a pairing event with unknown type.
  // map<address, type>
  static std::map<std::string, ConnectionType> pending_type;

  switch ((BtDeviceType)device_type) {
    case BtDeviceType::Ble:
      pending_type[addr] = ConnectionType::CONN_TYPE_LE;
      return ConnectionType::CONN_TYPE_LE;
    case BtDeviceType::Bredr:
      pending_type[addr] = ConnectionType::CONN_TYPE_BREDR;
      return ConnectionType::CONN_TYPE_BREDR;
    case BtDeviceType::Dual:
    case BtDeviceType::Unknown:
      if (pending_type.find(addr) != pending_type.end()) {
        return pending_type[addr];
      } else {
        return ConnectionType::CONN_TYPE_UNKNOWN;
      }
  }
}

PairingState ToPairingState(uint32_t status, uint32_t bond_state, int32_t fail_reason) {
  PairingState pairing_state = PairingState::PAIR_FAIL_UNKNOWN;

+14 −0
Original line number Diff line number Diff line
@@ -25,6 +25,17 @@ namespace metrics {
// BluetoothAdapterStateChanged/AdapterState.
enum class AdapterState : int64_t { OFF = 0, ON = 1 };

// ENUM definition for device/connection type that in sync with ChromeOS structured metrics
// BluetoothPairingStateChanged/DeviceType and BlueZ metrics_conn_type. Note this is a non-optimal ENUM design that
// mixed the connection transport type with the device type. The connection can only be LE or Classic, but the device
// type can also be Dual.
enum class ConnectionType : int64_t {
  CONN_TYPE_UNKNOWN = 0,
  CONN_TYPE_BREDR = 1,
  CONN_TYPE_LE = 2,
  CONN_TYPE_END = 3,
};

// ENUM definition for pairing state that in sync with ChromeOS structured metrics
// BluetoothPairingStateChanged/PairingState and BlueZ metrics_pair_result.
enum class PairingState : int64_t {
@@ -131,6 +142,9 @@ struct ProfileConnectionEvent {
// Convert topshim::btif::BtState to AdapterState.
AdapterState ToAdapterState(uint32_t state);

// Convert topshim::btif::BtDeviceType to ConnectionType
ConnectionType ToPairingDeviceType(std::string addr, uint32_t device_type);

// Convert topshim::btif::bond_state info (status, addr, bond_state, and fail_reason) to PairingState
PairingState ToPairingState(uint32_t status, uint32_t bond_state, int32_t fail_reason);

+5 −1
Original line number Diff line number Diff line
@@ -1227,7 +1227,11 @@ impl IBluetooth for Bluetooth {
        }

        let address = addr.unwrap();
        let device_type = self.get_remote_type(device);
        let device_type = match transport {
            BtTransport::Bredr => BtDeviceType::Bredr,
            BtTransport::Le => BtDeviceType::Ble,
            _ => self.get_remote_type(device),
        };

        // We explicitly log the attempt to start the bonding separate from logging the bond state.
        // The start of the attempt is critical to help identify a bonding/pairing session.