mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
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
This commit is contained in:
@@ -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<BluetoothAudioProviderContext*>(cookie);
|
||||
delete ctx;
|
||||
}
|
||||
|
||||
static void binderDiedCallbackAidl(void* cookie) {
|
||||
LOG(INFO) << __func__;
|
||||
BluetoothAudioProviderContext* ctx =
|
||||
static_cast<BluetoothAudioProviderContext*>(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<AudioConfiguration>(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<BluetoothAudioProvider*>(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
|
||||
|
||||
@@ -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<AudioConfiguration> audio_config_ = nullptr;
|
||||
SessionType session_type_;
|
||||
std::vector<LatencyMode> latency_modes_;
|
||||
bool is_binder_died = false;
|
||||
};
|
||||
|
||||
} // namespace audio
|
||||
} // namespace bluetooth
|
||||
} // namespace hardware
|
||||
|
||||
Reference in New Issue
Block a user