OSDN Git Service

Make sure the Hearing Aid source is ready before resuming or suspending calls
authorCheney Ni <cheneyni@google.com>
Fri, 24 May 2019 06:59:43 +0000 (14:59 +0800)
committerCheney Ni <cheneyni@google.com>
Tue, 28 May 2019 18:41:29 +0000 (02:41 +0800)
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

audio_hal_interface/client_interface.cc
audio_hal_interface/hearing_aid_software_encoding.cc
bta/hearing_aid/hearing_aid_audio_source.cc

index bf3d068..9f1be24 100644 (file)
@@ -174,8 +174,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";
     }
@@ -184,12 +185,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,
index 0e348ed..5107d46 100644 (file)
@@ -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,
index cd6d5fa..3b92d41 100644 (file)
@@ -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<tUIPC_STATE> uipc_hearing_aid;
+HearingAidAudioReceiver* localAudioReceiver = nullptr;
+std::unique_ptr<tUIPC_STATE> uipc_hearing_aid = nullptr;
 
 struct AudioHalStats {
   size_t media_read_total_underflow_bytes;
@@ -85,7 +85,9 @@ void send_audio_data() {
 
   std::vector<uint8_t> 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<void> do_resume_promise;
     std::future<void> 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<void> do_suspend_promise;
     std::future<void> 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;
   }
 }