From 2e4fd6f728a0a8ebc97efcb8e297b35a28f3ce5c Mon Sep 17 00:00:00 2001 From: Cheney Ni Date: Fri, 24 May 2019 14:59:43 +0800 Subject: [PATCH] Make sure the Hearing Aid source is ready before resuming or suspending calls Those calls to resume / suspend streaming are from the audio's IPC threads like HwBinder or UIPC, and calls to start / end session are from the stack main thread. There is timing that those threads may run in parallel, and trys to change the streaming state when the Hearing Aid source is not ready. This change checks the source state before resuming or suspending streaming, and breaks the deadlock between IPC threads and the stack main thread. Bug: 132860565 Test: 1. Connected to a Hearing Aids and disable the Bluetooth 2. Switch the active device manually Change-Id: I6ae11faab3d530c65f55ffa9b8a9f3cae2bde5f4 Merged-In: I6ae11faab3d530c65f55ffa9b8a9f3cae2bde5f4 (cherry picked from commit 39be24184d752b29d4a2b4cbcc537edfb4ee0acb) --- audio_hal_interface/client_interface.cc | 11 +++-------- audio_hal_interface/hearing_aid_software_encoding.cc | 10 +++++----- bta/hearing_aid/hearing_aid_audio_source.cc | 20 +++++++++++++------- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/audio_hal_interface/client_interface.cc b/audio_hal_interface/client_interface.cc index e6d6a6b6d..501e11359 100644 --- a/audio_hal_interface/client_interface.cc +++ b/audio_hal_interface/client_interface.cc @@ -172,8 +172,9 @@ class BluetoothAudioDeathRecipient // restart the session on the correct thread message_loop_->DoInThread( FROM_HERE, - base::BindOnce(&RenewAudioProviderAndSession, - base::Unretained(bluetooth_audio_clientif_))); + base::BindOnce( + &BluetoothAudioClientInterface::RenewAudioProviderAndSession, + base::Unretained(bluetooth_audio_clientif_))); } else { LOG(ERROR) << __func__ << ": BluetoothAudioClientInterface corrupted"; } @@ -182,12 +183,6 @@ class BluetoothAudioDeathRecipient private: BluetoothAudioClientInterface* bluetooth_audio_clientif_; bluetooth::common::MessageLoopThread* message_loop_; - static void RenewAudioProviderAndSession( - BluetoothAudioClientInterface* bluetooth_audio_clientif) { - if (bluetooth_audio_clientif != nullptr) { - bluetooth_audio_clientif->RenewAudioProviderAndSession(); - } - } }; BluetoothAudioClientInterface::BluetoothAudioClientInterface(IBluetoothTransportInstance* sink, diff --git a/audio_hal_interface/hearing_aid_software_encoding.cc b/audio_hal_interface/hearing_aid_software_encoding.cc index 0e348ed28..5107d46be 100644 --- a/audio_hal_interface/hearing_aid_software_encoding.cc +++ b/audio_hal_interface/hearing_aid_software_encoding.cc @@ -68,11 +68,11 @@ class HearingAidTransport void StopRequest() override { LOG(INFO) << __func__; - stream_cb_.on_suspend_(); - - // flush - uint8_t p_buf[AUDIO_STREAM_OUTPUT_BUFFER_SZ * 2]; - ::bluetooth::audio::hearing_aid::read(p_buf, sizeof(p_buf)); + if (stream_cb_.on_suspend_()) { + // flush + uint8_t p_buf[AUDIO_STREAM_OUTPUT_BUFFER_SZ * 2]; + ::bluetooth::audio::hearing_aid::read(p_buf, sizeof(p_buf)); + } } bool GetPresentationPosition(uint64_t* remote_delay_report_ns, diff --git a/bta/hearing_aid/hearing_aid_audio_source.cc b/bta/hearing_aid/hearing_aid_audio_source.cc index cd6d5fad5..3b92d41a8 100644 --- a/bta/hearing_aid/hearing_aid_audio_source.cc +++ b/bta/hearing_aid/hearing_aid_audio_source.cc @@ -38,8 +38,8 @@ int sample_rate = -1; int data_interval_ms = -1; int num_channels = 2; bluetooth::common::RepeatingTimer audio_timer; -HearingAidAudioReceiver* localAudioReceiver; -std::unique_ptr uipc_hearing_aid; +HearingAidAudioReceiver* localAudioReceiver = nullptr; +std::unique_ptr uipc_hearing_aid = nullptr; struct AudioHalStats { size_t media_read_total_underflow_bytes; @@ -85,7 +85,9 @@ void send_audio_data() { std::vector data(p_buf, p_buf + bytes_read); - localAudioReceiver->OnAudioDataReady(data); + if (localAudioReceiver != nullptr) { + localAudioReceiver->OnAudioDataReady(data); + } } void hearing_aid_send_ack(tHEARING_AID_CTRL_ACK status) { @@ -305,7 +307,7 @@ void hearing_aid_ctrl_cb(tUIPC_CH_ID, tUIPC_EVENT event) { bool hearing_aid_on_resume_req(bool start_media_task) { // hearing_aid_recv_ctrl_data(HEARING_AID_CTRL_CMD_START) - if (localAudioReceiver) { + if (localAudioReceiver != nullptr) { // Call OnAudioResume and block till it returns. std::promise do_resume_promise; std::future do_resume_future = do_resume_promise.get_future(); @@ -342,7 +344,7 @@ bool hearing_aid_on_resume_req(bool start_media_task) { bool hearing_aid_on_suspend_req() { // hearing_aid_recv_ctrl_data(HEARING_AID_CTRL_CMD_SUSPEND): stop_media_task stop_audio_ticks(); - if (localAudioReceiver) { + if (localAudioReceiver != nullptr) { // Call OnAudioSuspend and block till it returns. std::promise do_suspend_promise; std::future do_suspend_future = do_suspend_promise.get_future(); @@ -369,8 +371,7 @@ bool hearing_aid_on_suspend_req() { void HearingAidAudioSource::Start(const CodecConfiguration& codecConfiguration, HearingAidAudioReceiver* audioReceiver, uint16_t remote_delay_ms) { - localAudioReceiver = audioReceiver; - VLOG(2) << "Hearing Aid UIPC Open"; + LOG(INFO) << __func__ << ": Hearing Aid Source Open"; bit_rate = codecConfiguration.bit_rate; sample_rate = codecConfiguration.sample_rate; @@ -382,9 +383,13 @@ void HearingAidAudioSource::Start(const CodecConfiguration& codecConfiguration, bluetooth::audio::hearing_aid::start_session(); bluetooth::audio::hearing_aid::set_remote_delay(remote_delay_ms); } + localAudioReceiver = audioReceiver; } void HearingAidAudioSource::Stop() { + LOG(INFO) << __func__ << ": Hearing Aid Source Close"; + + localAudioReceiver = nullptr; if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) { bluetooth::audio::hearing_aid::end_session(); } @@ -409,6 +414,7 @@ void HearingAidAudioSource::CleanUp() { bluetooth::audio::hearing_aid::cleanup(); } else { UIPC_Close(*uipc_hearing_aid, UIPC_CH_ID_ALL); + uipc_hearing_aid = nullptr; } } -- 2.11.0