From f3faab081a543ad43e86eec6d03cd7835ef5c712 Mon Sep 17 00:00:00 2001 From: William Escande Date: Tue, 9 May 2023 16:37:45 -0700 Subject: [PATCH] Fix deathRecipient of BluetoothAudioProvider The "provider" is managed with a shared_ptr but we do not hold it and instead are giving the raw inner pointer as binderDiedCallbackAidl. This can randomly generate crash as the provider may be freed outside of this code. Replacing the provider with a context that we can manually allocate and deallocate. Setup AIBinder_DeathRecipient_setOnUnlinked to clean the data allocated Bug: 245009140 Test: m android.hardware.bluetooth.audio-impl and start / stop session + manually kill bluetooth process during audio play Change-Id: I0c14c062a8bde7e532ff02f01991d66da33ec569 --- .../aidl/default/BluetoothAudioProvider.cpp | 44 ++++++++++++------- .../aidl/default/BluetoothAudioProvider.h | 3 -- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp index 2a88959af5..727453beca 100644 --- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp +++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp @@ -27,9 +27,31 @@ namespace hardware { namespace bluetooth { namespace audio { +struct BluetoothAudioProviderContext { + SessionType session_type; +}; + +static void binderUnlinkedCallbackAidl(void* cookie) { + LOG(INFO) << __func__; + BluetoothAudioProviderContext* ctx = + static_cast(cookie); + delete ctx; +} + +static void binderDiedCallbackAidl(void* cookie) { + LOG(INFO) << __func__; + BluetoothAudioProviderContext* ctx = + static_cast(cookie); + CHECK_NE(ctx, nullptr); + + BluetoothAudioSessionReport::OnSessionEnded(ctx->session_type); +} + BluetoothAudioProvider::BluetoothAudioProvider() { death_recipient_ = ::ndk::ScopedAIBinder_DeathRecipient( AIBinder_DeathRecipient_new(binderDiedCallbackAidl)); + AIBinder_DeathRecipient_setOnUnlinked(death_recipient_.get(), + binderUnlinkedCallbackAidl); } ndk::ScopedAStatus BluetoothAudioProvider::startSession( @@ -45,10 +67,11 @@ ndk::ScopedAStatus BluetoothAudioProvider::startSession( latency_modes_ = latencyModes; audio_config_ = std::make_unique(audio_config); stack_iface_ = host_if; - is_binder_died = false; + BluetoothAudioProviderContext* cookie = + new BluetoothAudioProviderContext{session_type_}; AIBinder_linkToDeath(stack_iface_->asBinder().get(), death_recipient_.get(), - this); + cookie); onSessionReady(_aidl_return); return ndk::ScopedAStatus::ok(); @@ -60,10 +83,8 @@ ndk::ScopedAStatus BluetoothAudioProvider::endSession() { if (stack_iface_ != nullptr) { BluetoothAudioSessionReport::OnSessionEnded(session_type_); - if (!is_binder_died) { - AIBinder_unlinkToDeath(stack_iface_->asBinder().get(), - death_recipient_.get(), this); - } + AIBinder_unlinkToDeath(stack_iface_->asBinder().get(), + death_recipient_.get(), this); } else { LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << " has NO session"; @@ -143,17 +164,6 @@ ndk::ScopedAStatus BluetoothAudioProvider::setLowLatencyModeAllowed( return ndk::ScopedAStatus::ok(); } -void BluetoothAudioProvider::binderDiedCallbackAidl(void* ptr) { - LOG(ERROR) << __func__ << " - BluetoothAudio Service died"; - auto provider = static_cast(ptr); - if (provider == nullptr) { - LOG(ERROR) << __func__ << ": Null AudioProvider HAL died"; - return; - } - provider->is_binder_died = true; - provider->endSession(); -} - } // namespace audio } // namespace bluetooth } // namespace hardware diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h index dbfff7d26c..b6e07a1783 100644 --- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h +++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h @@ -54,7 +54,6 @@ class BluetoothAudioProvider : public BnBluetoothAudioProvider { protected: virtual ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) = 0; - static void binderDiedCallbackAidl(void* cookie_ptr); ::ndk::ScopedAIBinder_DeathRecipient death_recipient_; @@ -62,9 +61,7 @@ class BluetoothAudioProvider : public BnBluetoothAudioProvider { std::unique_ptr audio_config_ = nullptr; SessionType session_type_; std::vector latency_modes_; - bool is_binder_died = false; }; - } // namespace audio } // namespace bluetooth } // namespace hardware