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

Commit ee6d9012 authored by Jack He's avatar Jack He Committed by android-build-merger
Browse files

Merge "Multi-A2DP: Fix timing and codec measurement in metrics" am: 16d5d8bd

am: b29c1cd6

Change-Id: I308692737c575178f6463e7fe3fe65636ea5dbe3
parents a07eb4a5 b29c1cd6
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -133,6 +133,15 @@ message RFCommSession {
  optional int32 tx_bytes = 2;
}

enum A2dpSourceCodec {
  A2DP_SOURCE_CODEC_UNKNOWN = 0;
  A2DP_SOURCE_CODEC_SBC = 1;
  A2DP_SOURCE_CODEC_AAC = 2;
  A2DP_SOURCE_CODEC_APTX = 3;
  A2DP_SOURCE_CODEC_APTX_HD = 4;
  A2DP_SOURCE_CODEC_LDAC = 5;
}

// Session information that gets logged for A2DP session.
message A2DPSession {
  // Media timer in milliseconds.
@@ -158,6 +167,12 @@ message A2DPSession {

  // Total audio time in this A2DP session
  optional int64 audio_duration_millis = 8;

  // Audio codec used in this A2DP session in A2DP source role
  optional A2dpSourceCodec source_codec = 9;

  // Whether A2DP offload is enabled in this A2DP session
  optional bool is_a2dp_offload = 10;
}

message PairEvent {
+34 −22
Original line number Diff line number Diff line
@@ -132,6 +132,7 @@ class BtifMediaStats {
    media_read_total_underflow_bytes = 0;
    media_read_total_underflow_count = 0;
    media_read_last_underflow_us = 0;
    codec_index = -1;
  }

  uint64_t session_start_us;
@@ -160,6 +161,8 @@ class BtifMediaStats {
  size_t media_read_total_underflow_bytes;
  size_t media_read_total_underflow_count;
  uint64_t media_read_last_underflow_us;

  int codec_index = -1;
};

class BtWorkerThread {
@@ -380,6 +383,7 @@ void btif_a2dp_source_accumulate_stats(BtifMediaStats* src,
  dst->media_read_total_underflow_count +=
      src->media_read_total_underflow_count;
  dst->media_read_last_underflow_us = src->media_read_last_underflow_us;
  if (dst->codec_index < 0) dst->codec_index = src->codec_index;
  btif_a2dp_source_accumulate_scheduling_stats(&src->tx_queue_enqueue_stats,
                                               &dst->tx_queue_enqueue_stats);
  btif_a2dp_source_accumulate_scheduling_stats(&src->tx_queue_dequeue_stats,
@@ -427,8 +431,6 @@ static void btif_a2dp_source_startup_delayed(void) {
  raise_priority_a2dp(TASK_HIGH_MEDIA);
  btif_a2dp_control_init();
  btif_a2dp_source_cb.SetState(BtifA2dpSource::kStateRunning);
  BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
      system_bt_osi::CONNECTION_TECHNOLOGY_TYPE_BREDR, 0);
}

bool btif_a2dp_source_start_session(const RawAddress& peer_address) {
@@ -452,6 +454,8 @@ static void btif_a2dp_source_start_session_delayed(
  if (btif_av_is_a2dp_offload_enabled()) {
    btif_a2dp_audio_interface_start_session();
  }
  BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
      system_bt_osi::CONNECTION_TECHNOLOGY_TYPE_BREDR, 0);
}

bool btif_a2dp_source_restart_session(const RawAddress& old_peer_address,
@@ -499,6 +503,8 @@ static void btif_a2dp_source_end_session_delayed(
    const RawAddress& peer_address) {
  LOG_INFO(LOG_TAG, "%s: peer_address=%s", __func__,
           peer_address.ToString().c_str());
  BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionEnd(
      system_bt_osi::DISCONNECT_REASON_UNKNOWN, 0);
  if (btif_a2dp_source_cb.State() != BtifA2dpSource::kStateRunning) {
    LOG_ERROR(LOG_TAG, "%s: A2DP Source media task is not running", __func__);
    return;
@@ -538,8 +544,6 @@ static void btif_a2dp_source_shutdown_delayed(void) {
  btif_a2dp_source_cb.tx_audio_queue = nullptr;

  btif_a2dp_source_cb.SetState(BtifA2dpSource::kStateOff);
  BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionEnd(
      system_bt_osi::DISCONNECT_REASON_UNKNOWN, 0);
}

void btif_a2dp_source_cleanup(void) {
@@ -627,14 +631,6 @@ void btif_a2dp_source_start_audio_req(void) {

  btif_a2dp_source_thread.DoInThread(
      FROM_HERE, base::Bind(&btif_a2dp_source_audio_tx_start_event));
  btif_a2dp_source_cb.stats.Reset();
  // Assign session_start_us to 1 when time_get_os_boottime_us() is 0 to
  // indicate btif_a2dp_source_start_audio_req() has been called
  btif_a2dp_source_cb.stats.session_start_us = time_get_os_boottime_us();
  if (btif_a2dp_source_cb.stats.session_start_us == 0) {
    btif_a2dp_source_cb.stats.session_start_us = 1;
  }
  btif_a2dp_source_cb.stats.session_end_us = 0;
}

void btif_a2dp_source_stop_audio_req(void) {
@@ -642,11 +638,6 @@ void btif_a2dp_source_stop_audio_req(void) {

  btif_a2dp_source_thread.DoInThread(
      FROM_HERE, base::Bind(&btif_a2dp_source_audio_tx_stop_event));

  btif_a2dp_source_cb.stats.session_end_us = time_get_os_boottime_us();
  btif_a2dp_source_update_metrics();
  btif_a2dp_source_accumulate_stats(&btif_a2dp_source_cb.stats,
                                    &btif_a2dp_source_cb.accumulated_stats);
}

void btif_a2dp_source_encoder_user_config_update_req(
@@ -777,15 +768,32 @@ static void btif_a2dp_source_audio_tx_start_event(void) {
  alarm_set(btif_a2dp_source_cb.media_alarm,
            btif_a2dp_source_cb.encoder_interface->get_encoder_interval_ms(),
            btif_a2dp_source_alarm_cb, nullptr);

  btif_a2dp_source_cb.stats.Reset();
  // Assign session_start_us to 1 when time_get_os_boottime_us() is 0 to
  // indicate btif_a2dp_source_start_audio_req() has been called
  btif_a2dp_source_cb.stats.session_start_us = time_get_os_boottime_us();
  if (btif_a2dp_source_cb.stats.session_start_us == 0) {
    btif_a2dp_source_cb.stats.session_start_us = 1;
  }
  btif_a2dp_source_cb.stats.session_end_us = 0;
  A2dpCodecConfig* codec_config = bta_av_get_a2dp_current_codec();
  if (codec_config != nullptr) {
    btif_a2dp_source_cb.stats.codec_index = codec_config->codecIndex();
  }
}

static void btif_a2dp_source_audio_tx_stop_event(void) {
  LOG_INFO(LOG_TAG, "%s: media_alarm is %srunning, streaming %s", __func__,
           alarm_is_scheduled(btif_a2dp_source_cb.media_alarm) ? "" : "not ",
           btif_a2dp_source_is_streaming() ? "true" : "false");

  if (btif_av_is_a2dp_offload_enabled()) return;

  btif_a2dp_source_cb.stats.session_end_us = time_get_os_boottime_us();
  btif_a2dp_source_update_metrics();
  btif_a2dp_source_accumulate_stats(&btif_a2dp_source_cb.stats,
                                    &btif_a2dp_source_cb.accumulated_stats);

  uint8_t p_buf[AUDIO_STREAM_OUTPUT_BUFFER_SZ * 2];
  uint16_t event;

@@ -1212,18 +1220,22 @@ void btif_a2dp_source_debug_dump(int fd) {
}

static void btif_a2dp_source_update_metrics(void) {
  const BtifMediaStats& stats = btif_a2dp_source_cb.stats;
  const SchedulingStats& enqueue_stats = stats.tx_queue_enqueue_stats;
  BtifMediaStats stats = btif_a2dp_source_cb.stats;
  SchedulingStats enqueue_stats = stats.tx_queue_enqueue_stats;
  A2dpSessionMetrics metrics;
  metrics.codec_index = stats.codec_index;
  metrics.is_a2dp_offload = btif_av_is_a2dp_offload_enabled();
  // session_start_us is 0 when btif_a2dp_source_start_audio_req() is not called
  // mark the metric duration as invalid (-1) in this case
  if (stats.session_start_us != 0) {
    int64_t session_end_us = stats.session_end_us == 0
                                 ? time_get_os_boottime_us()
                                 : stats.session_end_us;
    if (static_cast<uint64_t>(session_end_us) > stats.session_start_us) {
      metrics.audio_duration_ms =
          (session_end_us - stats.session_start_us) / 1000;
    }
  }

  if (enqueue_stats.total_updates > 1) {
    metrics.media_timer_min_ms =
+2 −0
Original line number Diff line number Diff line
@@ -105,6 +105,8 @@ class A2dpSessionMetrics {
  int32_t buffer_overruns_total = -1;
  float buffer_underruns_average = -1;
  int32_t buffer_underruns_count = -1;
  int64_t codec_index = -1;
  bool is_a2dp_offload = false;
};

class BluetoothMetricsLogger {
+33 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@

#include <base/base64.h>
#include <base/logging.h>
#include <include/hardware/bt_av.h>

#include "bluetooth/metrics/bluetooth.pb.h"
#include "osi/include/leaky_bonded_queue.h"
@@ -42,6 +43,7 @@
namespace system_bt_osi {

using bluetooth::metrics::BluetoothMetricsProto::A2DPSession;
using bluetooth::metrics::BluetoothMetricsProto::A2dpSourceCodec;
using bluetooth::metrics::BluetoothMetricsProto::BluetoothLog;
using bluetooth::metrics::BluetoothMetricsProto::BluetoothSession;
using bluetooth::metrics::BluetoothMetricsProto::
@@ -140,6 +142,12 @@ void A2dpSessionMetrics::Update(const A2dpSessionMetrics& metrics) {
      buffer_underruns_count += metrics.buffer_underruns_count;
    }
  }
  if (codec_index < 0) {
    codec_index = metrics.codec_index;
  }
  if (!is_a2dp_offload) {
    is_a2dp_offload = metrics.is_a2dp_offload;
  }
}

bool A2dpSessionMetrics::operator==(const A2dpSessionMetrics& rhs) const {
@@ -151,7 +159,9 @@ bool A2dpSessionMetrics::operator==(const A2dpSessionMetrics& rhs) const {
         buffer_overruns_max_count == rhs.buffer_overruns_max_count &&
         buffer_overruns_total == rhs.buffer_overruns_total &&
         buffer_underruns_average == rhs.buffer_underruns_average &&
         buffer_underruns_count == rhs.buffer_underruns_count;
         buffer_underruns_count == rhs.buffer_underruns_count &&
         codec_index == rhs.codec_index &&
         is_a2dp_offload == rhs.is_a2dp_offload;
}

static DeviceInfo_DeviceType get_device_type(device_type_t type) {
@@ -230,6 +240,23 @@ static BluetoothSession_DisconnectReasonType get_disconnect_reason_type(
  }
}

static A2dpSourceCodec get_a2dp_source_codec(int64_t codec_index) {
  switch (codec_index) {
    case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
      return A2dpSourceCodec::A2DP_SOURCE_CODEC_SBC;
    case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
      return A2dpSourceCodec::A2DP_SOURCE_CODEC_AAC;
    case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
      return A2dpSourceCodec::A2DP_SOURCE_CODEC_APTX;
    case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
      return A2dpSourceCodec::A2DP_SOURCE_CODEC_APTX_HD;
    case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
      return A2dpSourceCodec::A2DP_SOURCE_CODEC_LDAC;
    default:
      return A2dpSourceCodec::A2DP_SOURCE_CODEC_UNKNOWN;
  }
}

struct BluetoothMetricsLogger::impl {
  impl(size_t max_bluetooth_session, size_t max_pair_event,
       size_t max_wake_event, size_t max_scan_event)
@@ -356,6 +383,7 @@ void BluetoothMetricsLogger::LogBluetoothSessionEnd(
      get_disconnect_reason_type(disconnect_reason));
  pimpl_->bt_session_queue_->Enqueue(pimpl_->bluetooth_session_);
  pimpl_->bluetooth_session_ = nullptr;
  pimpl_->a2dp_session_metrics_ = A2dpSessionMetrics();
  {
    std::lock_guard<std::recursive_mutex> log_lock(pimpl_->bluetooth_log_lock_);
    pimpl_->bluetooth_log_->set_num_bluetooth_session(
@@ -404,6 +432,10 @@ void BluetoothMetricsLogger::LogA2dpSession(
      pimpl_->a2dp_session_metrics_.buffer_underruns_average);
  a2dp_session->set_buffer_underruns_count(
      pimpl_->a2dp_session_metrics_.buffer_underruns_count);
  a2dp_session->set_source_codec(
      get_a2dp_source_codec(pimpl_->a2dp_session_metrics_.codec_index));
  a2dp_session->set_is_a2dp_offload(
      pimpl_->a2dp_session_metrics_.is_a2dp_offload);
}

void BluetoothMetricsLogger::LogHeadsetProfileRfcConnection(
+125 −6
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <gtest/gtest.h>

#include <base/logging.h>
#include <include/hardware/bt_av.h>

#include "bluetooth/metrics/bluetooth.pb.h"
#include "osi/include/metrics.h"
@@ -35,6 +36,7 @@
namespace testing {

using bluetooth::metrics::BluetoothMetricsProto::A2DPSession;
using bluetooth::metrics::BluetoothMetricsProto::A2dpSourceCodec;
using bluetooth::metrics::BluetoothMetricsProto::BluetoothLog;
using bluetooth::metrics::BluetoothMetricsProto::BluetoothSession;
using bluetooth::metrics::BluetoothMetricsProto::
@@ -111,7 +113,8 @@ ScanEvent* MakeScanEvent(ScanEvent_ScanEventType event_type,
  return event;
}

A2DPSession* MakeA2DPSession(const A2dpSessionMetrics& metrics) {
A2DPSession* MakeA2DPSession(const A2dpSessionMetrics& metrics,
                             A2dpSourceCodec source_codec) {
  A2DPSession* session = new A2DPSession();
  session->set_media_timer_min_millis(metrics.media_timer_min_ms);
  session->set_media_timer_max_millis(metrics.media_timer_max_ms);
@@ -121,6 +124,8 @@ A2DPSession* MakeA2DPSession(const A2dpSessionMetrics& metrics) {
  session->set_buffer_underruns_average(metrics.buffer_underruns_average);
  session->set_buffer_underruns_count(metrics.buffer_underruns_count);
  session->set_audio_duration_millis(metrics.audio_duration_ms);
  session->set_source_codec(source_codec);
  session->set_is_a2dp_offload(metrics.is_a2dp_offload);
  return session;
}

@@ -187,6 +192,8 @@ void GenerateWakeEvents(size_t start, size_t end,
                FloatNear((b).buffer_underruns_average, 0.01));              \
    (a).buffer_underruns_average = (b).buffer_underruns_average;             \
    EXPECT_EQ((a).buffer_underruns_count, (b).buffer_underruns_count);       \
    EXPECT_EQ((a).codec_index, (b).codec_index);                             \
    EXPECT_EQ((a).is_a2dp_offload, (b).is_a2dp_offload);                     \
  } while (0)

/*
@@ -220,6 +227,12 @@ TEST(BluetoothA2DPSessionMetricsTest, TestUpdateNormal) {
  metrics2.buffer_underruns_count = 2400;
  metrics_sum.buffer_underruns_average = 113.33333333;
  metrics_sum.buffer_underruns_count = 3600;
  metrics1.codec_index = -1;
  metrics2.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_AAC;
  metrics_sum.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_AAC;
  metrics1.is_a2dp_offload = false;
  metrics2.is_a2dp_offload = true;
  metrics_sum.is_a2dp_offload = true;
  metrics1.Update(metrics2);
  COMPARE_A2DP_METRICS(metrics1, metrics_sum);
  EXPECT_TRUE(metrics1 == metrics_sum);
@@ -246,6 +259,10 @@ TEST(BluetoothA2DPSessionMetricsTest, TestUpdateNew) {
  metrics2.buffer_underruns_count = 2400;
  metrics_sum.buffer_underruns_average = 130;
  metrics_sum.buffer_underruns_count = 2400;
  metrics2.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_APTX;
  metrics_sum.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_APTX;
  metrics2.is_a2dp_offload = true;
  metrics_sum.is_a2dp_offload = true;
  metrics1.Update(metrics2);
  COMPARE_A2DP_METRICS(metrics1, metrics_sum);
  EXPECT_TRUE(metrics1 == metrics_sum);
@@ -272,6 +289,10 @@ TEST(BluetoothA2DPSessionMetricsTest, TestNullUpdate) {
  metrics2.buffer_underruns_count = 2400;
  metrics_sum.buffer_underruns_average = 130;
  metrics_sum.buffer_underruns_count = 2400;
  metrics2.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD;
  metrics_sum.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD;
  metrics2.is_a2dp_offload = true;
  metrics_sum.is_a2dp_offload = true;
  metrics2.Update(metrics1);
  COMPARE_A2DP_METRICS(metrics2, metrics_sum);
  EXPECT_TRUE(metrics2 == metrics_sum);
@@ -560,10 +581,17 @@ TEST_F(BluetoothMetricsLoggerTest, A2DPSessionTwoUpdatesTest) {
  metrics2.buffer_underruns_count = 2400;
  metrics_sum.buffer_underruns_average = 113.33333333;
  metrics_sum.buffer_underruns_count = 3600;
  metrics1.codec_index = -1;
  metrics2.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_AAC;
  metrics_sum.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_AAC;
  metrics1.is_a2dp_offload = false;
  metrics2.is_a2dp_offload = true;
  metrics_sum.is_a2dp_offload = true;
  DeviceInfo* info = MakeDeviceInfo(
      BTM_COD_MAJOR_AUDIO_TEST,
      DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_BREDR);
  A2DPSession* session = MakeA2DPSession(metrics_sum);
  A2DPSession* session =
      MakeA2DPSession(metrics_sum, A2dpSourceCodec::A2DP_SOURCE_CODEC_AAC);
  bt_sessions_.push_back(MakeBluetoothSession(
      10,
      BluetoothSession_ConnectionTechnologyType::
@@ -618,10 +646,13 @@ TEST_F(BluetoothMetricsLoggerTest, A2DPSessionTwoUpdatesSeparatedbyDumpTest) {
  metrics1.buffer_underruns_count = 1200;
  metrics2.buffer_underruns_average = 130;
  metrics2.buffer_underruns_count = 2400;
  metrics1.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_SBC;
  metrics2.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_AAC;
  DeviceInfo* info = MakeDeviceInfo(
      BTM_COD_MAJOR_AUDIO_TEST,
      DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_BREDR);
  A2DPSession* session = MakeA2DPSession(metrics1);
  A2DPSession* session =
      MakeA2DPSession(metrics1, A2dpSourceCodec::A2DP_SOURCE_CODEC_SBC);
  bt_sessions_.push_back(MakeBluetoothSession(
      1,
      BluetoothSession_ConnectionTechnologyType::
@@ -643,7 +674,7 @@ TEST_F(BluetoothMetricsLoggerTest, A2DPSessionTwoUpdatesSeparatedbyDumpTest) {
  info = MakeDeviceInfo(
      BTM_COD_MAJOR_AUDIO_TEST,
      DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_BREDR);
  session = MakeA2DPSession(metrics2);
  session = MakeA2DPSession(metrics2, A2dpSourceCodec::A2DP_SOURCE_CODEC_AAC);
  bt_sessions_.push_back(MakeBluetoothSession(
      1,
      BluetoothSession_ConnectionTechnologyType::
@@ -661,6 +692,86 @@ TEST_F(BluetoothMetricsLoggerTest, A2DPSessionTwoUpdatesSeparatedbyDumpTest) {
  EXPECT_THAT(msg_str, StrEq(bt_log_str_));
}

/*
 * Test Case: A2DPSessionTwoUpdatesSeparatedbyEndTest
 *
 * 1. Create Instance
 * 2. LogBluetoothSessionStart
 * 3. LogA2dpSession
 * 4. LogBluetoothSessionEnd
 * 5. LogBluetoothSessionStart
 * 6. LogA2dpSession
 * 7. LogBluetoothSessionEnd
 * 8. WriteString
 *
 */
TEST_F(BluetoothMetricsLoggerTest, A2DPSessionTwoUpdatesSeparatedbyEndTest) {
  /* Same metrics from BluetoothA2DPSessionMetricsTest.TestUpdateNormal */
  A2dpSessionMetrics metrics1;
  metrics1.audio_duration_ms = 10;
  metrics1.media_timer_min_ms = 10;
  metrics1.media_timer_max_ms = 100;
  metrics1.media_timer_avg_ms = 50;
  metrics1.total_scheduling_count = 50;
  metrics1.buffer_overruns_max_count = 70;
  metrics1.buffer_underruns_average = 80;
  metrics1.buffer_underruns_count = 1200;
  metrics1.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_SBC;
  DeviceInfo* info = MakeDeviceInfo(
      BTM_COD_MAJOR_AUDIO_TEST,
      DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_BREDR);
  A2DPSession* session =
      MakeA2DPSession(metrics1, A2dpSourceCodec::A2DP_SOURCE_CODEC_SBC);
  bt_sessions_.push_back(MakeBluetoothSession(
      1,
      BluetoothSession_ConnectionTechnologyType::
          BluetoothSession_ConnectionTechnologyType_CONNECTION_TECHNOLOGY_TYPE_BREDR,
      BluetoothSession_DisconnectReasonType::
          BluetoothSession_DisconnectReasonType_UNKNOWN,
      info, nullptr, session));
  UpdateLog();
  BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
      system_bt_osi::CONNECTION_TECHNOLOGY_TYPE_BREDR, 0);
  BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionDeviceInfo(
      BTM_COD_MAJOR_AUDIO_TEST, system_bt_osi::DEVICE_TYPE_BREDR);
  BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics1);
  sleep_ms(1000);
  BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionEnd(
      system_bt_osi::DISCONNECT_REASON_UNKNOWN, 0);
  std::string msg_str;
  BluetoothMetricsLogger::GetInstance()->WriteString(&msg_str);
  EXPECT_THAT(msg_str, StrEq(bt_log_str_));
  ClearLog();
  A2dpSessionMetrics metrics2;
  metrics2.audio_duration_ms = 25;
  metrics2.media_timer_min_ms = 25;
  metrics2.media_timer_max_ms = 200;
  metrics2.media_timer_avg_ms = 100;
  metrics2.total_scheduling_count = 50;
  metrics2.buffer_overruns_max_count = 80;
  metrics2.buffer_underruns_average = 130;
  metrics2.buffer_underruns_count = 2400;
  metrics2.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_AAC;
  session = MakeA2DPSession(metrics2, A2dpSourceCodec::A2DP_SOURCE_CODEC_AAC);
  bt_sessions_.push_back(MakeBluetoothSession(
      1,
      BluetoothSession_ConnectionTechnologyType::
          BluetoothSession_ConnectionTechnologyType_CONNECTION_TECHNOLOGY_TYPE_BREDR,
      BluetoothSession_DisconnectReasonType::
          BluetoothSession_DisconnectReasonType_UNKNOWN,
      nullptr, nullptr, session));
  UpdateLog();
  BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
      system_bt_osi::CONNECTION_TECHNOLOGY_TYPE_BREDR, 0);
  sleep_ms(1000);
  BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics2);
  BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionEnd(
      system_bt_osi::DISCONNECT_REASON_UNKNOWN, 0);
  msg_str.clear();
  BluetoothMetricsLogger::GetInstance()->WriteString(&msg_str);
  EXPECT_THAT(msg_str, StrEq(bt_log_str_));
}

/*
 * Test Case 1: A2DPSessionOnlyTest
 *
@@ -700,10 +811,14 @@ TEST_F(BluetoothMetricsLoggerTest, A2DPSessionOnlyTest) {
  metrics2.buffer_underruns_count = 2400;
  metrics_sum.buffer_underruns_average = 113.33333333;
  metrics_sum.buffer_underruns_count = 3600;
  metrics1.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_SBC;
  metrics2.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_AAC;
  metrics_sum.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_SBC;
  DeviceInfo* info = MakeDeviceInfo(
      BTM_COD_MAJOR_AUDIO_TEST,
      DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_BREDR);
  A2DPSession* session = MakeA2DPSession(metrics_sum);
  A2DPSession* session =
      MakeA2DPSession(metrics_sum, A2dpSourceCodec::A2DP_SOURCE_CODEC_SBC);
  bt_sessions_.push_back(MakeBluetoothSession(
      1,
      BluetoothSession_ConnectionTechnologyType::
@@ -762,6 +877,9 @@ TEST_F(BluetoothMetricsLoggerTest, A2DPSessionDumpBeforeTwoUpdatesTest) {
  metrics2.buffer_underruns_count = 2400;
  metrics_sum.buffer_underruns_average = 113.33333333;
  metrics_sum.buffer_underruns_count = 3600;
  metrics1.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_SBC;
  metrics2.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_AAC;
  metrics_sum.codec_index = BTAV_A2DP_CODEC_INDEX_SOURCE_SBC;
  DeviceInfo* info = MakeDeviceInfo(
      BTM_COD_MAJOR_AUDIO_TEST,
      DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_BREDR);
@@ -785,7 +903,8 @@ TEST_F(BluetoothMetricsLoggerTest, A2DPSessionDumpBeforeTwoUpdatesTest) {
  info = MakeDeviceInfo(
      BTM_COD_MAJOR_AUDIO_TEST,
      DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_BREDR);
  A2DPSession* session = MakeA2DPSession(metrics_sum);
  A2DPSession* session =
      MakeA2DPSession(metrics_sum, A2dpSourceCodec::A2DP_SOURCE_CODEC_SBC);
  bt_sessions_.push_back(MakeBluetoothSession(
      1,
      BluetoothSession_ConnectionTechnologyType::