Loading proto/bluetooth/metrics/bluetooth.proto +15 −0 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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 { Loading system/btif/src/btif_a2dp_source.cc +34 −22 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 { Loading Loading @@ -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, Loading Loading @@ -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) { Loading @@ -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, Loading Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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) { Loading @@ -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( Loading Loading @@ -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; Loading Loading @@ -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 = Loading system/osi/include/metrics.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading system/osi/src/metrics.cc +33 −1 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -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:: Loading Loading @@ -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 { Loading @@ -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) { Loading Loading @@ -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) Loading Loading @@ -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( Loading Loading @@ -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( Loading system/osi/test/metrics_test.cc +125 −6 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -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:: Loading Loading @@ -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); Loading @@ -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; } Loading Loading @@ -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) /* Loading Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading Loading @@ -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:: Loading Loading @@ -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:: Loading @@ -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:: Loading @@ -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 * Loading Loading @@ -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:: Loading Loading @@ -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); Loading @@ -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:: Loading Loading
proto/bluetooth/metrics/bluetooth.proto +15 −0 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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 { Loading
system/btif/src/btif_a2dp_source.cc +34 −22 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 { Loading Loading @@ -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, Loading Loading @@ -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) { Loading @@ -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, Loading Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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) { Loading @@ -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( Loading Loading @@ -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; Loading Loading @@ -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 = Loading
system/osi/include/metrics.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading
system/osi/src/metrics.cc +33 −1 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -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:: Loading Loading @@ -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 { Loading @@ -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) { Loading Loading @@ -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) Loading Loading @@ -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( Loading Loading @@ -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( Loading
system/osi/test/metrics_test.cc +125 −6 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -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:: Loading Loading @@ -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); Loading @@ -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; } Loading Loading @@ -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) /* Loading Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading Loading @@ -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:: Loading Loading @@ -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:: Loading @@ -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:: Loading @@ -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 * Loading Loading @@ -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:: Loading Loading @@ -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); Loading @@ -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:: Loading