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

Commit b912391e authored by Archie Pusaka's avatar Archie Pusaka
Browse files

floss: Send ChipsetInfo metrics

The behavior mimics BlueZ's: send on adapter state change and on
ACL (dis)connecting, but we do it on ACL (dis)connected instead
because the (dis)connecting event is not propagated to floss if the
initiator is system.

Bug: 240782197
Tag: #floss
Test: Verify chipset info is logged
BYPASS_LONG_LINES_REASON: Bluetooth likes 120 lines

Change-Id: Ib012068f03677053ddedbe32722cc1108a8f25ce
parent c62ebda0
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ void LogMetricsAdapterStateChanged(uint32_t state) {
      .SetIsFloss(true)
      .SetAdapterState(adapter_state)
      .Record();

  LogMetricsChipsetInfoReport();
}

void LogMetricsBondCreateAttempt(RawAddress* addr, uint32_t device_type) {
@@ -282,6 +284,35 @@ void LogMetricsAclConnectionStateChanged(
      .SetStateChangeType(event.state)
      .SetAclConnectionState(event.status)
      .Record();

  LogMetricsChipsetInfoReport();
}

void LogMetricsChipsetInfoReport() {
  static MetricsChipsetInfo* info = NULL;
  uint64_t chipset_string_hval = 0;
  std::string boot_id;

  if (!info) {
    info = (MetricsChipsetInfo*)calloc(1, sizeof(MetricsChipsetInfo));
    *info = GetMetricsChipsetInfo();
  }

  if (!GetBootId(&boot_id)) {
    return;
  }

  LOG_DEBUG("ChipsetInfoReport: 0x%x 0x%x %d %s", info->vid, info->pid, info->transport, info->chipset_string.c_str());

  if (IsChipsetInfoInAllowList(
          info->vid, info->pid, info->transport, info->chipset_string.c_str(), &chipset_string_hval)) {
    ::metrics::structured::events::bluetooth::BluetoothChipsetInfoReport()
        .SetBootId(boot_id.c_str())
        .SetVendorId(info->vid)
        .SetProductId(info->pid)
        .SetTransport(info->transport)
        .SetChipsetStringHashValue(chipset_string_hval);
  }
}

}  // namespace metrics
+82 −0
Original line number Diff line number Diff line
@@ -15,9 +15,17 @@
 */
#include "gd/metrics/chromeos/metrics_event.h"

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/strings/pattern.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>

#include <map>
#include <utility>

#include "gd/common/init_flags.h"
#include "hci/hci_packets.h"
#include "include/hardware/bluetooth.h"
#include "include/hardware/bt_av.h"
@@ -28,6 +36,14 @@
namespace bluetooth {
namespace metrics {

namespace {
// these consts path below are for getting the chipset info
constexpr char kChipsetInfoWlanDirPath[] = "/sys/class/net/wlan0/device";
constexpr char kChipsetInfoMlanDirPath[] = "/sys/class/net/mlan0/device";
constexpr char kChipsetInfoModaliasPath[] = "/sys/class/bluetooth/hci%d/device/modalias";
constexpr char kChipInfoModuleDirPath[] = "/sys/class/bluetooth/hci%d/device/driver/module";
}  // namespace

// topshim::btif::BtBondState is a copy of hardware/bluetooth.h:bt_bond_state_t
typedef bt_bond_state_t BtBondState;
// topshim::btif::BtAclState is a copy of hardware/bluetooth.h:bt_acl_state_t
@@ -612,5 +628,71 @@ AclConnectionEvent ToAclConnectionEvent(
  return event;
}

static int64_t GetChipsetInfoId(const char* path, const char* file) {
  std::string content;
  int64_t id;

  if (base::ReadFileToString(base::FilePath(path).Append(file), &content)) {
    if (base::HexStringToInt64(base::CollapseWhitespaceASCII(content, false), &id)) {
      return id;
    }
  }
  return 0;
}

static std::string GetChipsetInfoModuleName() {
  std::string module;
  int adapter_index = bluetooth::common::InitFlags::GetAdapterIndex();
  std::string path = base::StringPrintf(kChipsetInfoModaliasPath, adapter_index);

  if (base::ReadFileToString(base::FilePath(path), &module)) {
    return module;
  }
  return "";
}

static MetricTransportType GetChipsetInfoTransport(void) {
  MetricTransportType transport = MetricTransportType::TRANSPORT_TYPE_UNKNOWN;
  base::FilePath module_realpath;
  std::string module_name;
  int adapter_index = bluetooth::common::InitFlags::GetAdapterIndex();
  std::string path = base::StringPrintf(kChipInfoModuleDirPath, adapter_index);

  // examples of module_realpath: /sys/module/btusb and /sys/module/hci_uart
  module_realpath = base::MakeAbsoluteFilePath(base::FilePath(path));
  if (module_realpath.empty()) {
    return transport;
  }

  module_name = module_realpath.BaseName().value();
  if (base::MatchPattern(module_name, "*usb*"))
    transport = MetricTransportType::TRANSPORT_TYPE_USB;
  else if (base::MatchPattern(module_name, "*uart*"))
    transport = MetricTransportType::TRANSPORT_TYPE_UART;
  else if (base::MatchPattern(module_name, "*sdio*"))
    transport = MetricTransportType::TRANSPORT_TYPE_SDIO;

  return transport;
}

MetricsChipsetInfo GetMetricsChipsetInfo() {
  MetricsChipsetInfo info;

  info.vid = GetChipsetInfoId(kChipsetInfoWlanDirPath, "vendor");
  info.pid = GetChipsetInfoId(kChipsetInfoWlanDirPath, "device");

  if (!info.vid || !info.pid) {
    info.vid = GetChipsetInfoId(kChipsetInfoMlanDirPath, "vendor");
    info.pid = GetChipsetInfoId(kChipsetInfoMlanDirPath, "device");
  }

  if (!info.vid || !info.pid) {
    info.chipset_string = GetChipsetInfoModuleName();
  }

  info.transport = (int)GetChipsetInfoTransport();
  return info;
}

}  // namespace metrics
}  // namespace bluetooth
 No newline at end of file
+20 −0
Original line number Diff line number Diff line
@@ -186,6 +186,15 @@ enum class MetricAclConnectionInitiator : int64_t {
  ACL_CONNECTION_INITIATOR_SYSTEM = 2,
};

// ENUM definition for ACL disconnection status that in sync with ChromeOS structured metrics
// MetricTransportType and BlueZ's metrics_transport_type.
enum class MetricTransportType {
  TRANSPORT_TYPE_UNKNOWN = 0,
  TRANSPORT_TYPE_USB = 1,
  TRANSPORT_TYPE_UART = 2,
  TRANSPORT_TYPE_SDIO = 3,
};

// A struct holds the parsed profile connection event.
struct ProfileConnectionEvent {
  int64_t type;
@@ -222,5 +231,16 @@ void PendingAclConnectAttemptEvent(std::string addr, int64_t time, uint32_t acl_
AclConnectionEvent ToAclConnectionEvent(
    std::string addr, int64_t time, uint32_t acl_status, uint32_t acl_state, uint32_t direction, uint32_t hci_reason);

// A struct to hold the chipset info.
struct MetricsChipsetInfo {
  int64_t vid;
  int64_t pid;
  int64_t transport;
  std::string chipset_string;
};

// Get the info of the chipset.
MetricsChipsetInfo GetMetricsChipsetInfo();

}  // namespace metrics
}  // namespace bluetooth
+2 −0
Original line number Diff line number Diff line
@@ -49,5 +49,7 @@ void LogMetricsAclConnectionStateChanged(
    uint32_t direction,
    uint32_t hci_reason) {}

void LogMetricsChipsetInfoReport() {}

}  // namespace metrics
}  // namespace bluetooth
+1 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ void LogMetricsProfileConnectionStateChanged(RawAddress* addr, uint32_t profile,
void LogMetricsAclConnectAttempt(RawAddress* addr, uint32_t acl_state);
void LogMetricsAclConnectionStateChanged(
    RawAddress* addr, uint32_t transport, uint32_t status, uint32_t acl_state, uint32_t direction, uint32_t hci_reason);
void LogMetricsChipsetInfoReport();

}  // namespace metrics
}  // namespace bluetooth