Loading system/btif/src/btif_a2dp_audio_interface.cc +99 −5 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ #define LOG_TAG "btif_a2dp_audio_interface" #include "btif_a2dp_audio_interface.h" #include <mutex> #include <a2dp_vendor.h> #include <a2dp_vendor_ldac_constants.h> #include <android/hardware/bluetooth/a2dp/1.0/IBluetoothAudioHost.h> Loading @@ -37,8 +40,12 @@ #include "btif_av.h" #include "btif_av_co.h" #include "btif_hf.h" #include "osi/include/metrics.h" #include "osi/include/osi.h" using system_bt_osi::A2dpSessionMetrics; using system_bt_osi::BluetoothMetricsLogger; using android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioOffload; using android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioHost; using android::hardware::bluetooth::a2dp::V1_0::Status; Loading @@ -65,12 +72,67 @@ uint8_t btif_a2dp_audio_process_request(uint8_t cmd); static void btif_a2dp_audio_send_start_req(); static void btif_a2dp_audio_send_suspend_req(); static void btif_a2dp_audio_send_stop_req(); static void btif_a2dp_audio_interface_init(); static void btif_a2dp_audio_interface_deinit(); static void btif_a2dp_audio_interface_restart_session(); // Delay reporting // static void btif_a2dp_audio_send_sink_latency(); class A2dpOffloadAudioStats { public: A2dpOffloadAudioStats() { Reset(); } void Reset() { std::lock_guard<std::recursive_mutex> lock(lock_); ResetPreserveSession(); codec_index_ = -1; } void ResetPreserveSession() { std::lock_guard<std::recursive_mutex> lock(lock_); audio_start_time_ms_ = -1; audio_stop_time_ms_ = -1; } void StoreMetrics() { std::lock_guard<std::recursive_mutex> lock(lock_); if (audio_start_time_ms_ < 0 || audio_stop_time_ms_ < 0) { return; } A2dpSessionMetrics metrics; metrics.codec_index = codec_index_; metrics.is_a2dp_offload = true; if (audio_stop_time_ms_ > audio_start_time_ms_) { metrics.audio_duration_ms = audio_stop_time_ms_ - audio_start_time_ms_; } BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics); } void LogAudioStart() { std::lock_guard<std::recursive_mutex> lock(lock_); audio_start_time_ms_ = time_get_os_boottime_ms(); } void LogAudioStop() { std::lock_guard<std::recursive_mutex> lock(lock_); audio_stop_time_ms_ = time_get_os_boottime_ms(); } void LogAudioStopMetricsAndReset() { std::lock_guard<std::recursive_mutex> lock(lock_); LogAudioStop(); StoreMetrics(); ResetPreserveSession(); } void SetCodecIndex(int64_t codec_index) { std::lock_guard<std::recursive_mutex> lock(lock_); codec_index_ = codec_index; } private: std::recursive_mutex lock_; int64_t audio_start_time_ms_ = -1; int64_t audio_stop_time_ms_ = -1; int64_t codec_index_ = -1; }; static A2dpOffloadAudioStats a2dp_offload_audio_stats; class BluetoothAudioHost : public IBluetoothAudioHost { public: Return<void> startStream() { Loading @@ -82,7 +144,7 @@ class BluetoothAudioHost : public IBluetoothAudioHost { return Void(); } Return<void> stopStream() { btif_a2dp_audio_process_request(A2DP_CTRL_CMD_STOP); btif_a2dp_audio_send_stop_req(); return Void(); } Loading Loading @@ -135,6 +197,7 @@ static void btif_a2dp_get_codec_configuration( a2dpCodecConfig->getCodecSpecificConfig(&a2dp_offload); btav_a2dp_codec_config_t codec_config; codec_config = a2dpCodecConfig->getCodecConfig(); a2dp_offload_audio_stats.SetCodecIndex(a2dpCodecConfig->codecIndex()); switch (codec_config.codec_type) { case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC: p_codec_info->codecType = Loading Loading @@ -235,6 +298,9 @@ static void btif_a2dp_audio_interface_deinit() { void btif_a2dp_audio_interface_start_session() { LOG_INFO(LOG_TAG, "%s", __func__); BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart( system_bt_osi::CONNECTION_TECHNOLOGY_TYPE_BREDR, 0); a2dp_offload_audio_stats.Reset(); btif_a2dp_audio_interface_init(); CHECK(btAudio != nullptr); CodecConfiguration codec_info; Loading @@ -245,6 +311,10 @@ void btif_a2dp_audio_interface_start_session() { void btif_a2dp_audio_interface_end_session() { LOG_INFO(LOG_TAG, "%s", __func__); a2dp_offload_audio_stats.LogAudioStopMetricsAndReset(); BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionEnd( system_bt_osi::DISCONNECT_REASON_UNKNOWN, 0); a2dp_offload_audio_stats.Reset(); if (btAudio == nullptr) return; auto ret = btAudio->endSession(); if (!ret.isOk()) { Loading @@ -270,7 +340,11 @@ void btif_a2dp_audio_on_started(tBTA_AV_STATUS status) { if (btAudio != nullptr) { if (a2dp_cmd_pending == A2DP_CTRL_CMD_START) { LOG_INFO(LOG_TAG, "%s: calling method onStarted", __func__); btAudio->streamStarted(mapToStatus(status)); auto hal_status = mapToStatus(status); btAudio->streamStarted(hal_status); if (hal_status == Status::SUCCESS) { a2dp_offload_audio_stats.LogAudioStart(); } } } } Loading @@ -280,7 +354,11 @@ void btif_a2dp_audio_on_suspended(tBTA_AV_STATUS status) { if (btAudio != nullptr) { if (a2dp_cmd_pending == A2DP_CTRL_CMD_SUSPEND) { LOG_INFO(LOG_TAG, "calling method onSuspended"); btAudio->streamSuspended(mapToStatus(status)); auto hal_status = mapToStatus(status); btAudio->streamSuspended(hal_status); if (hal_status == Status::SUCCESS) { a2dp_offload_audio_stats.LogAudioStopMetricsAndReset(); } } } } Loading @@ -291,6 +369,7 @@ void btif_a2dp_audio_on_stopped(tBTA_AV_STATUS status) { LOG_INFO(LOG_TAG, "%s: Remote disconnected when start under progress", __func__); btAudio->streamStarted(mapToStatus(A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS)); a2dp_offload_audio_stats.LogAudioStopMetricsAndReset(); } } void btif_a2dp_audio_send_start_req() { Loading @@ -298,7 +377,11 @@ void btif_a2dp_audio_send_start_req() { uint8_t resp; resp = btif_a2dp_audio_process_request(A2DP_CTRL_CMD_START); if (btAudio != nullptr) { auto ret = btAudio->streamStarted(mapToStatus(resp)); auto status = mapToStatus(resp); auto ret = btAudio->streamStarted(status); if (status == Status::SUCCESS) { a2dp_offload_audio_stats.LogAudioStart(); } if (!ret.isOk()) LOG_ERROR(LOG_TAG, "HAL server died"); } } Loading @@ -307,10 +390,21 @@ void btif_a2dp_audio_send_suspend_req() { uint8_t resp; resp = btif_a2dp_audio_process_request(A2DP_CTRL_CMD_SUSPEND); if (btAudio != nullptr) { auto ret = btAudio->streamSuspended(mapToStatus(resp)); auto status = mapToStatus(resp); auto ret = btAudio->streamSuspended(status); if (status == Status::SUCCESS) { a2dp_offload_audio_stats.LogAudioStopMetricsAndReset(); } if (!ret.isOk()) LOG_ERROR(LOG_TAG, "HAL server died"); } } void btif_a2dp_audio_send_stop_req() { LOG_INFO(LOG_TAG, "%s", __func__); btif_a2dp_audio_process_request(A2DP_CTRL_CMD_STOP); a2dp_offload_audio_stats.LogAudioStopMetricsAndReset(); } /*void btif_a2dp_audio_send_sink_latency() { LOG_INFO(LOG_TAG, "%s", __func__); Loading system/btif/src/btif_a2dp_source.cc +7 −4 Original line number Diff line number Diff line Loading @@ -470,10 +470,11 @@ static void btif_a2dp_source_start_session_delayed( } if (btif_av_is_a2dp_offload_enabled()) { btif_a2dp_audio_interface_start_session(); } } else { BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart( system_bt_osi::CONNECTION_TECHNOLOGY_TYPE_BREDR, 0); } } bool btif_a2dp_source_restart_session(const RawAddress& old_peer_address, const RawAddress& new_peer_address) { Loading Loading @@ -524,8 +525,10 @@ static void btif_a2dp_source_end_session_delayed( LOG_INFO(LOG_TAG, "%s: peer_address=%s state=%s", __func__, peer_address.ToString().c_str(), btif_a2dp_source_cb.StateStr().c_str()); if (!btif_av_is_a2dp_offload_enabled()) { BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionEnd( system_bt_osi::DISCONNECT_REASON_UNKNOWN, 0); } if (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateRunning) { btif_av_stream_stop(peer_address); } else { Loading Loading
system/btif/src/btif_a2dp_audio_interface.cc +99 −5 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ #define LOG_TAG "btif_a2dp_audio_interface" #include "btif_a2dp_audio_interface.h" #include <mutex> #include <a2dp_vendor.h> #include <a2dp_vendor_ldac_constants.h> #include <android/hardware/bluetooth/a2dp/1.0/IBluetoothAudioHost.h> Loading @@ -37,8 +40,12 @@ #include "btif_av.h" #include "btif_av_co.h" #include "btif_hf.h" #include "osi/include/metrics.h" #include "osi/include/osi.h" using system_bt_osi::A2dpSessionMetrics; using system_bt_osi::BluetoothMetricsLogger; using android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioOffload; using android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioHost; using android::hardware::bluetooth::a2dp::V1_0::Status; Loading @@ -65,12 +72,67 @@ uint8_t btif_a2dp_audio_process_request(uint8_t cmd); static void btif_a2dp_audio_send_start_req(); static void btif_a2dp_audio_send_suspend_req(); static void btif_a2dp_audio_send_stop_req(); static void btif_a2dp_audio_interface_init(); static void btif_a2dp_audio_interface_deinit(); static void btif_a2dp_audio_interface_restart_session(); // Delay reporting // static void btif_a2dp_audio_send_sink_latency(); class A2dpOffloadAudioStats { public: A2dpOffloadAudioStats() { Reset(); } void Reset() { std::lock_guard<std::recursive_mutex> lock(lock_); ResetPreserveSession(); codec_index_ = -1; } void ResetPreserveSession() { std::lock_guard<std::recursive_mutex> lock(lock_); audio_start_time_ms_ = -1; audio_stop_time_ms_ = -1; } void StoreMetrics() { std::lock_guard<std::recursive_mutex> lock(lock_); if (audio_start_time_ms_ < 0 || audio_stop_time_ms_ < 0) { return; } A2dpSessionMetrics metrics; metrics.codec_index = codec_index_; metrics.is_a2dp_offload = true; if (audio_stop_time_ms_ > audio_start_time_ms_) { metrics.audio_duration_ms = audio_stop_time_ms_ - audio_start_time_ms_; } BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics); } void LogAudioStart() { std::lock_guard<std::recursive_mutex> lock(lock_); audio_start_time_ms_ = time_get_os_boottime_ms(); } void LogAudioStop() { std::lock_guard<std::recursive_mutex> lock(lock_); audio_stop_time_ms_ = time_get_os_boottime_ms(); } void LogAudioStopMetricsAndReset() { std::lock_guard<std::recursive_mutex> lock(lock_); LogAudioStop(); StoreMetrics(); ResetPreserveSession(); } void SetCodecIndex(int64_t codec_index) { std::lock_guard<std::recursive_mutex> lock(lock_); codec_index_ = codec_index; } private: std::recursive_mutex lock_; int64_t audio_start_time_ms_ = -1; int64_t audio_stop_time_ms_ = -1; int64_t codec_index_ = -1; }; static A2dpOffloadAudioStats a2dp_offload_audio_stats; class BluetoothAudioHost : public IBluetoothAudioHost { public: Return<void> startStream() { Loading @@ -82,7 +144,7 @@ class BluetoothAudioHost : public IBluetoothAudioHost { return Void(); } Return<void> stopStream() { btif_a2dp_audio_process_request(A2DP_CTRL_CMD_STOP); btif_a2dp_audio_send_stop_req(); return Void(); } Loading Loading @@ -135,6 +197,7 @@ static void btif_a2dp_get_codec_configuration( a2dpCodecConfig->getCodecSpecificConfig(&a2dp_offload); btav_a2dp_codec_config_t codec_config; codec_config = a2dpCodecConfig->getCodecConfig(); a2dp_offload_audio_stats.SetCodecIndex(a2dpCodecConfig->codecIndex()); switch (codec_config.codec_type) { case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC: p_codec_info->codecType = Loading Loading @@ -235,6 +298,9 @@ static void btif_a2dp_audio_interface_deinit() { void btif_a2dp_audio_interface_start_session() { LOG_INFO(LOG_TAG, "%s", __func__); BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart( system_bt_osi::CONNECTION_TECHNOLOGY_TYPE_BREDR, 0); a2dp_offload_audio_stats.Reset(); btif_a2dp_audio_interface_init(); CHECK(btAudio != nullptr); CodecConfiguration codec_info; Loading @@ -245,6 +311,10 @@ void btif_a2dp_audio_interface_start_session() { void btif_a2dp_audio_interface_end_session() { LOG_INFO(LOG_TAG, "%s", __func__); a2dp_offload_audio_stats.LogAudioStopMetricsAndReset(); BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionEnd( system_bt_osi::DISCONNECT_REASON_UNKNOWN, 0); a2dp_offload_audio_stats.Reset(); if (btAudio == nullptr) return; auto ret = btAudio->endSession(); if (!ret.isOk()) { Loading @@ -270,7 +340,11 @@ void btif_a2dp_audio_on_started(tBTA_AV_STATUS status) { if (btAudio != nullptr) { if (a2dp_cmd_pending == A2DP_CTRL_CMD_START) { LOG_INFO(LOG_TAG, "%s: calling method onStarted", __func__); btAudio->streamStarted(mapToStatus(status)); auto hal_status = mapToStatus(status); btAudio->streamStarted(hal_status); if (hal_status == Status::SUCCESS) { a2dp_offload_audio_stats.LogAudioStart(); } } } } Loading @@ -280,7 +354,11 @@ void btif_a2dp_audio_on_suspended(tBTA_AV_STATUS status) { if (btAudio != nullptr) { if (a2dp_cmd_pending == A2DP_CTRL_CMD_SUSPEND) { LOG_INFO(LOG_TAG, "calling method onSuspended"); btAudio->streamSuspended(mapToStatus(status)); auto hal_status = mapToStatus(status); btAudio->streamSuspended(hal_status); if (hal_status == Status::SUCCESS) { a2dp_offload_audio_stats.LogAudioStopMetricsAndReset(); } } } } Loading @@ -291,6 +369,7 @@ void btif_a2dp_audio_on_stopped(tBTA_AV_STATUS status) { LOG_INFO(LOG_TAG, "%s: Remote disconnected when start under progress", __func__); btAudio->streamStarted(mapToStatus(A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS)); a2dp_offload_audio_stats.LogAudioStopMetricsAndReset(); } } void btif_a2dp_audio_send_start_req() { Loading @@ -298,7 +377,11 @@ void btif_a2dp_audio_send_start_req() { uint8_t resp; resp = btif_a2dp_audio_process_request(A2DP_CTRL_CMD_START); if (btAudio != nullptr) { auto ret = btAudio->streamStarted(mapToStatus(resp)); auto status = mapToStatus(resp); auto ret = btAudio->streamStarted(status); if (status == Status::SUCCESS) { a2dp_offload_audio_stats.LogAudioStart(); } if (!ret.isOk()) LOG_ERROR(LOG_TAG, "HAL server died"); } } Loading @@ -307,10 +390,21 @@ void btif_a2dp_audio_send_suspend_req() { uint8_t resp; resp = btif_a2dp_audio_process_request(A2DP_CTRL_CMD_SUSPEND); if (btAudio != nullptr) { auto ret = btAudio->streamSuspended(mapToStatus(resp)); auto status = mapToStatus(resp); auto ret = btAudio->streamSuspended(status); if (status == Status::SUCCESS) { a2dp_offload_audio_stats.LogAudioStopMetricsAndReset(); } if (!ret.isOk()) LOG_ERROR(LOG_TAG, "HAL server died"); } } void btif_a2dp_audio_send_stop_req() { LOG_INFO(LOG_TAG, "%s", __func__); btif_a2dp_audio_process_request(A2DP_CTRL_CMD_STOP); a2dp_offload_audio_stats.LogAudioStopMetricsAndReset(); } /*void btif_a2dp_audio_send_sink_latency() { LOG_INFO(LOG_TAG, "%s", __func__); Loading
system/btif/src/btif_a2dp_source.cc +7 −4 Original line number Diff line number Diff line Loading @@ -470,10 +470,11 @@ static void btif_a2dp_source_start_session_delayed( } if (btif_av_is_a2dp_offload_enabled()) { btif_a2dp_audio_interface_start_session(); } } else { BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart( system_bt_osi::CONNECTION_TECHNOLOGY_TYPE_BREDR, 0); } } bool btif_a2dp_source_restart_session(const RawAddress& old_peer_address, const RawAddress& new_peer_address) { Loading Loading @@ -524,8 +525,10 @@ static void btif_a2dp_source_end_session_delayed( LOG_INFO(LOG_TAG, "%s: peer_address=%s state=%s", __func__, peer_address.ToString().c_str(), btif_a2dp_source_cb.StateStr().c_str()); if (!btif_av_is_a2dp_offload_enabled()) { BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionEnd( system_bt_osi::DISCONNECT_REASON_UNKNOWN, 0); } if (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateRunning) { btif_av_stream_stop(peer_address); } else { Loading