Skip to content
Snippets Groups Projects
Commit 4a80a8e5 authored by Pavlin Radoslavov's avatar Pavlin Radoslavov
Browse files

Gracefully handle A2DP hardware offload Audio HAL service death

Register for Audio HAL service death, and restart the Audio HAL session
if necessary.

Bug: 77926419
Test: Manual: stream Bluetooth audio and kill -9 the audioserver
Change-Id: I45e83aea0fb95301e6ceadee74661dd55f8c0f66
parent fc22b0f4
No related branches found
No related tags found
No related merge requests found
...@@ -121,6 +121,7 @@ cc_test { ...@@ -121,6 +121,7 @@ cc_test {
header_libs: ["libbluetooth_headers"], header_libs: ["libbluetooth_headers"],
shared_libs: [ shared_libs: [
"libaudioclient", "libaudioclient",
"android.hardware.bluetooth.a2dp@1.0",
"libhidlbase", "libhidlbase",
"liblog", "liblog",
"libprotobuf-cpp-lite", "libprotobuf-cpp-lite",
...@@ -132,7 +133,9 @@ cc_test { ...@@ -132,7 +133,9 @@ cc_test {
"libbtcore", "libbtcore",
"libbt-stack", "libbt-stack",
"libbt-sbc-encoder", "libbt-sbc-encoder",
"libbt-utils",
"libFraunhoferAAC", "libFraunhoferAAC",
"libg722codec",
"libbtdevice", "libbtdevice",
"libbt-hci", "libbt-hci",
"libudrv-uipc", "libudrv-uipc",
......
...@@ -57,8 +57,10 @@ using android::hardware::bluetooth::a2dp::V1_0::ChannelMode; ...@@ -57,8 +57,10 @@ using android::hardware::bluetooth::a2dp::V1_0::ChannelMode;
using android::hardware::ProcessState; using android::hardware::ProcessState;
using ::android::hardware::Return; using ::android::hardware::Return;
using ::android::hardware::Void; using ::android::hardware::Void;
using ::android::hardware::hidl_death_recipient;
using ::android::hardware::hidl_vec; using ::android::hardware::hidl_vec;
using ::android::sp; using ::android::sp;
using ::android::wp;
android::sp<IBluetoothAudioOffload> btAudio; android::sp<IBluetoothAudioOffload> btAudio;
#define CASE_RETURN_STR(const) \ #define CASE_RETURN_STR(const) \
...@@ -73,6 +75,7 @@ static void btif_a2dp_audio_send_suspend_req(); ...@@ -73,6 +75,7 @@ static void btif_a2dp_audio_send_suspend_req();
static void btif_a2dp_audio_send_stop_req(); static void btif_a2dp_audio_send_stop_req();
static void btif_a2dp_audio_interface_init(); static void btif_a2dp_audio_interface_init();
static void btif_a2dp_audio_interface_deinit(); static void btif_a2dp_audio_interface_deinit();
static void btif_a2dp_audio_interface_restart_session();
// Delay reporting // Delay reporting
// static void btif_a2dp_audio_send_sink_latency(); // static void btif_a2dp_audio_send_sink_latency();
...@@ -153,6 +156,20 @@ class BluetoothAudioHost : public IBluetoothAudioHost { ...@@ -153,6 +156,20 @@ class BluetoothAudioHost : public IBluetoothAudioHost {
}*/ }*/
}; };
class BluetoothAudioDeathRecipient : public hidl_death_recipient {
public:
virtual void serviceDied(
uint64_t /*cookie*/,
const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
LOG_ERROR(LOG_TAG, "%s", __func__);
// Restart the session on the correct thread
do_in_bta_thread(FROM_HERE,
base::Bind(&btif_a2dp_audio_interface_restart_session));
}
};
sp<BluetoothAudioDeathRecipient> bluetoothAudioDeathRecipient =
new BluetoothAudioDeathRecipient();
static Status mapToStatus(uint8_t resp) { static Status mapToStatus(uint8_t resp) {
switch (resp) { switch (resp) {
case A2DP_CTRL_ACK_SUCCESS: case A2DP_CTRL_ACK_SUCCESS:
...@@ -253,6 +270,12 @@ static void btif_a2dp_audio_interface_init() { ...@@ -253,6 +270,12 @@ static void btif_a2dp_audio_interface_init() {
btAudio = IBluetoothAudioOffload::getService(); btAudio = IBluetoothAudioOffload::getService();
CHECK(btAudio != nullptr); CHECK(btAudio != nullptr);
auto death_link = btAudio->linkToDeath(bluetoothAudioDeathRecipient, 0);
if (!death_link.isOk()) {
LOG_ERROR(LOG_TAG, "%s: Cannot observe the Bluetooth Audio HAL's death",
__func__);
}
LOG_DEBUG( LOG_DEBUG(
LOG_TAG, "%s: IBluetoothAudioOffload::getService() returned %p (%s)", LOG_TAG, "%s: IBluetoothAudioOffload::getService() returned %p (%s)",
__func__, btAudio.get(), (btAudio->isRemote() ? "remote" : "local")); __func__, btAudio.get(), (btAudio->isRemote() ? "remote" : "local"));
...@@ -262,6 +285,14 @@ static void btif_a2dp_audio_interface_init() { ...@@ -262,6 +285,14 @@ static void btif_a2dp_audio_interface_init() {
static void btif_a2dp_audio_interface_deinit() { static void btif_a2dp_audio_interface_deinit() {
LOG_INFO(LOG_TAG, "%s: start", __func__); LOG_INFO(LOG_TAG, "%s: start", __func__);
if (btAudio != nullptr) {
auto death_unlink = btAudio->unlinkToDeath(bluetoothAudioDeathRecipient);
if (!death_unlink.isOk()) {
LOG_ERROR(LOG_TAG,
"%s: Error unlinking death observer from Bluetooth Audio HAL",
__func__);
}
}
btAudio = nullptr; btAudio = nullptr;
} }
...@@ -292,6 +323,18 @@ void btif_a2dp_audio_interface_end_session() { ...@@ -292,6 +323,18 @@ void btif_a2dp_audio_interface_end_session() {
btif_a2dp_audio_interface_deinit(); btif_a2dp_audio_interface_deinit();
} }
// Conditionally restart the session only if it was started before
static void btif_a2dp_audio_interface_restart_session() {
LOG_INFO(LOG_TAG, "%s", __func__);
if (btAudio == nullptr) {
LOG_INFO(LOG_TAG, "%s: nothing to restart - session was not started",
__func__);
return;
}
btAudio = nullptr;
btif_a2dp_audio_interface_start_session();
}
void btif_a2dp_audio_on_started(tBTA_AV_STATUS status) { void btif_a2dp_audio_on_started(tBTA_AV_STATUS status) {
LOG_INFO(LOG_TAG, "%s: status = %d", __func__, status); LOG_INFO(LOG_TAG, "%s: status = %d", __func__, status);
if (btAudio != nullptr) { if (btAudio != nullptr) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment