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

Commit 2aebbb14 authored by Chen Chen's avatar Chen Chen
Browse files

GD metrics: add logging definitions to GD

Test: atest bluetooth_test_gd
Bug: 181819141

Change-Id: I1a49859c6ca93e196e95f6e230c15af094fae57b
parent b2a587cd
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -143,6 +143,10 @@ cc_defaults {
                "libcutils",
                "libhidlbase",
                "libutils",
                "libstatslog",
            ],
            static_libs: [
                "libbt-platform-protos-lite",
            ],
        },
    },
@@ -175,10 +179,12 @@ cc_defaults {
        "libflatbuffers-cpp",
        "libgrpc++",
        "libgrpc_wrap",
        "libstatslog",
    ],
    static_libs: [
        "libbluetooth-protos",
        "libbluetooth_rust_interop",
        "libbt-platform-protos-lite",
    ],
    export_static_lib_headers: [ "libbluetooth_rust_interop" ],
}
@@ -385,10 +391,12 @@ cc_test {
    static_libs: [
        "libbluetooth_rust_interop",
        "libchrome",
        "libbt-platform-protos-lite",
    ],
    shared_libs: [
        "libgrpc++",
        "libgrpc_wrap",
        "libstatslog",
    ],
    target: {
        android: {
+11 −0
Original line number Diff line number Diff line
@@ -7,6 +7,16 @@ package {
    default_applicable_licenses: ["system_bt_license"],
}

filegroup {
    name: "BluetoothCommonSourcesForRootCanal",
    srcs: [
        "init_flags.cc",
        "metric_id_manager.cc",
        "strings.cc",
        "stop_watch.cc",
    ],
}

filegroup {
    name: "BluetoothCommonSources",
    srcs: [
@@ -14,6 +24,7 @@ filegroup {
        "metric_id_manager.cc",
        "strings.cc",
        "stop_watch.cc",
        "metrics.cc",
    ],
}

+5 −1
Original line number Diff line number Diff line
@@ -18,10 +18,14 @@ source_set("BluetoothCommonSources") {
  sources = [
    "init_flags.cc",
    "metric_id_manager.cc"
    "metrics_linux.cc",
    "stop_watch.cc",
    "strings.cc",
  ]

  configs += [ "//bt/gd:gd_defaults" ]
  deps = [ "//bt/gd:gd_default_deps" ]
  deps = [
    "//bt/gd:gd_default_deps",
    "//bt/third_party/proto_logging/stats:libbt-platform-protos"
  ]
}
+392 −0
Original line number Diff line number Diff line
/******************************************************************************
 *
 *  Copyright 2021 Google, Inc.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

#define LOG_TAG "BluetoothMetrics"

#include <statslog.h>

#include "common/metric_id_manager.h"
#include "common/strings.h"
#include "metrics.h"
#include "os/log.h"

namespace bluetooth {

namespace common {

using bluetooth::hci::Address;

/**
 * nullptr and size 0 represent missing value for obfuscated_id
 */
static const android::util::BytesField byteField(nullptr, 0);

void LogMetricLinkLayerConnectionEvent(
    const Address* address,
    uint32_t connection_handle,
    android::bluetooth::DirectionEnum direction,
    uint16_t link_type,
    uint32_t hci_cmd,
    uint16_t hci_event,
    uint16_t hci_ble_event,
    uint16_t cmd_status,
    uint16_t reason_code) {
  int metric_id = 0;
  if (address != nullptr) {
    metric_id = MetricIdManager::GetInstance().AllocateId(*address);
  }
  int ret = android::util::stats_write(
      android::util::BLUETOOTH_LINK_LAYER_CONNECTION_EVENT,
      byteField,
      connection_handle,
      direction,
      link_type,
      hci_cmd,
      hci_event,
      hci_ble_event,
      cmd_status,
      reason_code,
      metric_id);
  if (ret < 0) {
    LOG_WARN(
        "Failed to log status %s , reason %s, from cmd %s, event %s,  ble_event %s, for %s, handle %d, type %s, "
        "error %d",
        ToHexString(cmd_status).c_str(),
        ToHexString(reason_code).c_str(),
        ToHexString(hci_cmd).c_str(),
        ToHexString(hci_event).c_str(),
        ToHexString(hci_ble_event).c_str(),
        address->ToString().c_str(),
        connection_handle,
        ToHexString(link_type).c_str(),
        ret);
  }
}

void LogMetricHciTimeoutEvent(uint32_t hci_cmd) {
  int ret = android::util::stats_write(android::util::BLUETOOTH_HCI_TIMEOUT_REPORTED, static_cast<int64_t>(hci_cmd));
  if (ret < 0) {
    LOG_WARN("Failed for opcode %s, error %d", ToHexString(hci_cmd).c_str(), ret);
  }
}

void LogMetricRemoteVersionInfo(
    uint16_t handle, uint8_t status, uint8_t version, uint16_t manufacturer_name, uint16_t subversion) {
  int ret = android::util::stats_write(
      android::util::BLUETOOTH_REMOTE_VERSION_INFO_REPORTED, handle, status, version, manufacturer_name, subversion);
  if (ret < 0) {
    LOG_WARN(
        "Failed for handle %d, status %s, version %s, manufacturer_name %s, subversion %s, error %d",
        handle,
        ToHexString(status).c_str(),
        ToHexString(version).c_str(),
        ToHexString(manufacturer_name).c_str(),
        ToHexString(subversion).c_str(),
        ret);
  }
}

void LogMetricA2dpAudioUnderrunEvent(
    const Address& address, uint64_t encoding_interval_millis, int num_missing_pcm_bytes) {
  int metric_id = 0;
  if (!address.IsEmpty()) {
    metric_id = MetricIdManager::GetInstance().AllocateId(address);
  }
  int64_t encoding_interval_nanos = encoding_interval_millis * 1000000;
  int ret = android::util::stats_write(
      android::util::BLUETOOTH_A2DP_AUDIO_UNDERRUN_REPORTED,
      byteField,
      encoding_interval_nanos,
      num_missing_pcm_bytes,
      metric_id);
  if (ret < 0) {
    LOG_WARN(
        "Failed for %s, encoding_interval_nanos %s, num_missing_pcm_bytes %d, error %d",
        address.ToString().c_str(),
        std::to_string(encoding_interval_nanos).c_str(),
        num_missing_pcm_bytes,
        ret);
  }
}

void LogMetricA2dpAudioOverrunEvent(
    const Address& address,
    uint64_t encoding_interval_millis,
    int num_dropped_buffers,
    int num_dropped_encoded_frames,
    int num_dropped_encoded_bytes) {
  int metric_id = 0;
  if (!address.IsEmpty()) {
    metric_id = MetricIdManager::GetInstance().AllocateId(address);
  }

  int64_t encoding_interval_nanos = encoding_interval_millis * 1000000;
  int ret = android::util::stats_write(
      android::util::BLUETOOTH_A2DP_AUDIO_OVERRUN_REPORTED,
      byteField,
      encoding_interval_nanos,
      num_dropped_buffers,
      num_dropped_encoded_frames,
      num_dropped_encoded_bytes,
      metric_id);
  if (ret < 0) {
    LOG_WARN(
        "Failed to log for %s, encoding_interval_nanos %s, num_dropped_buffers %d, "
        "num_dropped_encoded_frames %d, num_dropped_encoded_bytes %d, error %d",
        address.ToString().c_str(),
        std::to_string(encoding_interval_nanos).c_str(),
        num_dropped_buffers,
        num_dropped_encoded_frames,
        num_dropped_encoded_bytes,
        ret);
  }
}

void LogMetricReadRssiResult(const Address& address, uint16_t handle, uint32_t cmd_status, int8_t rssi) {
  int metric_id = 0;
  if (!address.IsEmpty()) {
    metric_id = MetricIdManager::GetInstance().AllocateId(address);
  }
  int ret = android::util::stats_write(
      android::util::BLUETOOTH_DEVICE_RSSI_REPORTED, byteField, handle, cmd_status, rssi, metric_id);
  if (ret < 0) {
    LOG_WARN(
        "Failed for %s, handle %d, status %s, rssi %d dBm, error %d",
        address.ToString().c_str(),
        handle,
        ToHexString(cmd_status).c_str(),
        rssi,
        ret);
  }
}

void LogMetricReadFailedContactCounterResult(
    const Address& address, uint16_t handle, uint32_t cmd_status, int32_t failed_contact_counter) {
  int metric_id = 0;
  if (!address.IsEmpty()) {
    metric_id = MetricIdManager::GetInstance().AllocateId(address);
  }
  int ret = android::util::stats_write(
      android::util::BLUETOOTH_DEVICE_FAILED_CONTACT_COUNTER_REPORTED,
      byteField,
      handle,
      cmd_status,
      failed_contact_counter,
      metric_id);
  if (ret < 0) {
    LOG_WARN(
        "Failed for %s, handle %d, status %s, failed_contact_counter %d packets, error %d",
        address.ToString().c_str(),
        handle,
        ToHexString(cmd_status).c_str(),
        failed_contact_counter,
        ret);
  }
}

void LogMetricReadTxPowerLevelResult(
    const Address& address, uint16_t handle, uint32_t cmd_status, int32_t transmit_power_level) {
  int metric_id = 0;
  if (!address.IsEmpty()) {
    metric_id = MetricIdManager::GetInstance().AllocateId(address);
  }
  int ret = android::util::stats_write(
      android::util::BLUETOOTH_DEVICE_TX_POWER_LEVEL_REPORTED,
      byteField,
      handle,
      cmd_status,
      transmit_power_level,
      metric_id);
  if (ret < 0) {
    LOG_WARN(
        "Failed for %s, handle %d, status %s, transmit_power_level %d packets, error %d",
        address.ToString().c_str(),
        handle,
        ToHexString(cmd_status).c_str(),
        transmit_power_level,
        ret);
  }
}

void LogMetricSmpPairingEvent(
    const Address& address, uint8_t smp_cmd, android::bluetooth::DirectionEnum direction, uint8_t smp_fail_reason) {
  int metric_id = 0;
  if (!address.IsEmpty()) {
    metric_id = MetricIdManager::GetInstance().AllocateId(address);
  }
  int ret = android::util::stats_write(
      android::util::BLUETOOTH_SMP_PAIRING_EVENT_REPORTED, byteField, smp_cmd, direction, smp_fail_reason, metric_id);
  if (ret < 0) {
    LOG_WARN(
        "Failed for %s, smp_cmd %s, direction %d, smp_fail_reason %s, error %d",
        address.ToString().c_str(),
        ToHexString(smp_cmd).c_str(),
        direction,
        ToHexString(smp_fail_reason).c_str(),
        ret);
  }
}

void LogMetricClassicPairingEvent(
    const Address& address,
    uint16_t handle,
    uint32_t hci_cmd,
    uint16_t hci_event,
    uint16_t cmd_status,
    uint16_t reason_code,
    int64_t event_value) {
  int metric_id = 0;
  if (!address.IsEmpty()) {
    metric_id = MetricIdManager::GetInstance().AllocateId(address);
  }
  int ret = android::util::stats_write(
      android::util::BLUETOOTH_CLASSIC_PAIRING_EVENT_REPORTED,
      byteField,
      handle,
      hci_cmd,
      hci_event,
      cmd_status,
      reason_code,
      event_value,
      metric_id);
  if (ret < 0) {
    LOG_WARN(
        "Failed for %s, handle %d, hci_cmd %s, hci_event %s, cmd_status %s, "
        "reason %s, event_value %s, error %d",
        address.ToString().c_str(),
        handle,
        ToHexString(hci_cmd).c_str(),
        ToHexString(hci_event).c_str(),
        ToHexString(cmd_status).c_str(),
        ToHexString(reason_code).c_str(),
        std::to_string(event_value).c_str(),
        ret);
  }
}

void LogMetricSdpAttribute(
    const Address& address,
    uint16_t protocol_uuid,
    uint16_t attribute_id,
    size_t attribute_size,
    const char* attribute_value) {
  int metric_id = 0;
  if (!address.IsEmpty()) {
    metric_id = MetricIdManager::GetInstance().AllocateId(address);
  }
  android::util::BytesField attribute_field(attribute_value, attribute_size);
  int ret = android::util::stats_write(
      android::util::BLUETOOTH_SDP_ATTRIBUTE_REPORTED,
      byteField,
      protocol_uuid,
      attribute_id,
      attribute_field,
      metric_id);
  if (ret < 0) {
    LOG_WARN(
        "Failed for %s, protocol_uuid %s, attribute_id %s, error %d",
        address.ToString().c_str(),
        ToHexString(protocol_uuid).c_str(),
        ToHexString(attribute_id).c_str(),
        ret);
  }
}

void LogMetricSocketConnectionState(
    const Address& address,
    int port,
    int type,
    android::bluetooth::SocketConnectionstateEnum connection_state,
    int64_t tx_bytes,
    int64_t rx_bytes,
    int uid,
    int server_port,
    android::bluetooth::SocketRoleEnum socket_role) {
  int metric_id = 0;
  if (!address.IsEmpty()) {
    metric_id = MetricIdManager::GetInstance().AllocateId(address);
  }
  int ret = android::util::stats_write(
      android::util::BLUETOOTH_SOCKET_CONNECTION_STATE_CHANGED,
      byteField,
      port,
      type,
      connection_state,
      tx_bytes,
      rx_bytes,
      uid,
      server_port,
      socket_role,
      metric_id);
  if (ret < 0) {
    LOG_WARN(
        "Failed for %s, port %d, type %d, state %d, tx_bytes %s, rx_bytes %s, uid %d, server_port %d, "
        "socket_role %d, error %d",
        address.ToString().c_str(),
        port,
        type,
        connection_state,
        std::to_string(tx_bytes).c_str(),
        std::to_string(rx_bytes).c_str(),
        uid,
        server_port,
        socket_role,
        ret);
  }
}

void LogMetricManufacturerInfo(
    const Address& address,
    android::bluetooth::DeviceInfoSrcEnum source_type,
    const std::string& source_name,
    const std::string& manufacturer,
    const std::string& model,
    const std::string& hardware_version,
    const std::string& software_version) {
  int metric_id = 0;
  if (!address.IsEmpty()) {
    metric_id = MetricIdManager::GetInstance().AllocateId(address);
  }
  int ret = android::util::stats_write(
      android::util::BLUETOOTH_DEVICE_INFO_REPORTED,
      byteField,
      source_type,
      source_name.c_str(),
      manufacturer.c_str(),
      model.c_str(),
      hardware_version.c_str(),
      software_version.c_str(),
      metric_id);
  if (ret < 0) {
    LOG_WARN(
        "Failed for %s, source_type %d, source_name %s, manufacturer %s, model %s, hardware_version %s, "
        "software_version %s, error %d",
        address.ToString().c_str(),
        source_type,
        source_name.c_str(),
        manufacturer.c_str(),
        model.c_str(),
        hardware_version.c_str(),
        software_version.c_str(),
        ret);
  }
}

}  // namespace common

}  // namespace bluetooth
+247 −0
Original line number Diff line number Diff line
/******************************************************************************
 *
 *  Copyright 2021 Google, Inc.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

#pragma once

#include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
#include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h>

#include "hci/address.h"

namespace bluetooth {

namespace common {
/**
 * Unknown connection handle for metrics purpose
 */
static const uint32_t kUnknownConnectionHandle = 0xFFFF;

/**
 * Log link layer connection event
 *
 * @param address Stack wide consistent Bluetooth address of this event,
 *                nullptr if unknown
 * @param connection_handle connection handle of this event,
 *                          {@link kUnknownConnectionHandle} if unknown
 * @param direction direction of this connection
 * @param link_type type of the link
 * @param hci_cmd HCI command opecode associated with this event, if any
 * @param hci_event HCI event code associated with this event, if any
 * @param hci_ble_event HCI BLE event code associated with this event, if any
 * @param cmd_status Command status associated with this event, if any
 * @param reason_code Reason code associated with this event, if any
 */
void LogMetricLinkLayerConnectionEvent(
    const hci::Address* address,
    uint32_t connection_handle,
    android::bluetooth::DirectionEnum direction,
    uint16_t link_type,
    uint32_t hci_cmd,
    uint16_t hci_event,
    uint16_t hci_ble_event,
    uint16_t cmd_status,
    uint16_t reason_code);

/**
 * Logs when Bluetooth controller failed to reply with command status within
 * a timeout period after receiving an HCI command from the host
 *
 * @param hci_cmd opcode of HCI command that caused this timeout
 */
void LogMetricHciTimeoutEvent(uint32_t hci_cmd);

/**
 * Logs when we receive Bluetooth Read Remote Version Information Complete
 * Event from the remote device, as documented by the Bluetooth Core HCI
 * specification
 *
 * Reference: 5.0 Core Specification, Vol 2, Part E, Page 1118
 *
 * @param handle handle of associated ACL connection
 * @param status HCI command status of this event
 * @param version version code from read remote version complete event
 * @param manufacturer_name manufacturer code from read remote version complete
 *                          event
 * @param subversion subversion code from read remote version complete event
 */
void LogMetricRemoteVersionInfo(
    uint16_t handle, uint8_t status, uint8_t version, uint16_t manufacturer_name, uint16_t subversion);

/**
 * Log A2DP audio buffer underrun event
 *
 * @param address A2DP device associated with this event
 * @param encoding_interval_millis encoding interval in milliseconds
 * @param num_missing_pcm_bytes number of PCM bytes that cannot be read from
 *                              the source
 */
void LogMetricA2dpAudioUnderrunEvent(
    const hci::Address& address, uint64_t encoding_interval_millis, int num_missing_pcm_bytes);

/**
 * Log A2DP audio buffer overrun event
 *
 * @param address A2DP device associated with this event
 * @param encoding_interval_millis encoding interval in milliseconds
 * @param num_dropped_buffers number of encoded buffers dropped from Tx queue
 * @param num_dropped_encoded_frames number of encoded frames dropped from Tx
 *                                   queue
 * @param num_dropped_encoded_bytes number of encoded bytes dropped from Tx
 *                                  queue
 */
void LogMetricA2dpAudioOverrunEvent(
    const hci::Address& address,
    uint64_t encoding_interval_millis,
    int num_dropped_buffers,
    int num_dropped_encoded_frames,
    int num_dropped_encoded_bytes);

/**
 * Log read RSSI result
 *
 * @param address device associated with this event
 * @param handle connection handle of this event,
 *               {@link kUnknownConnectionHandle} if unknown
 * @param cmd_status command status from read RSSI command
 * @param rssi rssi value in dBm
 */
void LogMetricReadRssiResult(const hci::Address& address, uint16_t handle, uint32_t cmd_status, int8_t rssi);

/**
 * Log failed contact counter report
 *
 * @param address device associated with this event
 * @param handle connection handle of this event,
 *               {@link kUnknownConnectionHandle} if unknown
 * @param cmd_status command status from read failed contact counter command
 * @param failed_contact_counter Number of consecutive failed contacts for a
 *                               connection corresponding to the Handle
 */
void LogMetricReadFailedContactCounterResult(
    const hci::Address& address, uint16_t handle, uint32_t cmd_status, int32_t failed_contact_counter);

/**
 * Log transmit power level for a particular device after read
 *
 * @param address device associated with this event
 * @param handle connection handle of this event,
 *               {@link kUnknownConnectionHandle} if unknown
 * @param cmd_status command status from read failed contact counter command
 * @param transmit_power_level transmit power level for connection to this
 *                             device
 */
void LogMetricReadTxPowerLevelResult(
    const hci::Address& address, uint16_t handle, uint32_t cmd_status, int32_t transmit_power_level);

/**
 * Logs when there is an event related to Bluetooth Security Manager Protocol
 *
 * @param address address of associated device
 * @param smp_cmd SMP command code associated with this event
 * @param direction direction of this SMP command
 * @param smp_fail_reason SMP pairing failure reason code from SMP spec
 */
void LogMetricSmpPairingEvent(
    const hci::Address& address, uint8_t smp_cmd, android::bluetooth::DirectionEnum direction, uint8_t smp_fail_reason);

/**
 * Logs there is an event related Bluetooth classic pairing
 *
 * @param address address of associated device
 * @param handle connection handle of this event,
 *               {@link kUnknownConnectionHandle} if unknown
 * @param hci_cmd HCI command associated with this event
 * @param hci_event HCI event associated with this event
 * @param cmd_status Command status associated with this event
 * @param reason_code Reason code associated with this event
 * @param event_value A status value related to this specific event
 */
void LogMetricClassicPairingEvent(
    const hci::Address& address,
    uint16_t handle,
    uint32_t hci_cmd,
    uint16_t hci_event,
    uint16_t cmd_status,
    uint16_t reason_code,
    int64_t event_value);

/**
 * Logs when certain Bluetooth SDP attributes are discovered
 *
 * @param address address of associated device
 * @param protocol_uuid 16 bit protocol UUID from Bluetooth Assigned Numbers
 * @param attribute_id 16 bit attribute ID from Bluetooth Assigned Numbers
 * @param attribute_size size of this attribute
 * @param attribute_value pointer to the attribute data, must be larger than
 *                        attribute_size
 */
void LogMetricSdpAttribute(
    const hci::Address& address,
    uint16_t protocol_uuid,
    uint16_t attribute_id,
    size_t attribute_size,
    const char* attribute_value);

/**
 * Logs when there is a change in Bluetooth socket connection state
 *
 * @param address address of associated device, empty if this is a server port
 * @param port port of this socket connection
 * @param type type of socket
 * @param connection_state socket connection state
 * @param tx_bytes number of bytes transmitted
 * @param rx_bytes number of bytes received
 * @param server_port server port of this socket, if any. When both
 *        |server_port| and |port| fields are populated, |port| must be spawned
 *        by |server_port|
 * @param socket_role role of this socket, server or connection
 * @param uid socket owner's uid
 */
void LogMetricSocketConnectionState(
    const hci::Address& address,
    int port,
    int type,
    android::bluetooth::SocketConnectionstateEnum connection_state,
    int64_t tx_bytes,
    int64_t rx_bytes,
    int uid,
    int server_port,
    android::bluetooth::SocketRoleEnum socket_role);

/**
 * Logs when a Bluetooth device's manufacturer information is learnt
 *
 * @param address address of associated device
 * @param source_type where is this device info obtained from
 * @param source_name name of the data source, internal or external
 * @param manufacturer name of the manufacturer of this device
 * @param model model of this device
 * @param hardware_version hardware version of this device
 * @param software_version software version of this device
 */
void LogMetricManufacturerInfo(
    const hci::Address& address,
    android::bluetooth::DeviceInfoSrcEnum source_type,
    const std::string& source_name,
    const std::string& manufacturer,
    const std::string& model,
    const std::string& hardware_version,
    const std::string& software_version);
}  // namespace common

}  // namespace bluetooth
Loading