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
Merged-In: I45e83aea0fb95301e6ceadee74661dd55f8c0f66
(cherry picked from commit 5c80c8653a61780f8047413d5ad9f939a8a397f3)
diff --git a/btif/Android.bp b/btif/Android.bp
index f9177a7..4b2dc30 100644
--- a/btif/Android.bp
+++ b/btif/Android.bp
@@ -121,6 +121,7 @@
     header_libs: ["libbluetooth_headers"],
     shared_libs: [
         "libaudioclient",
+        "android.hardware.bluetooth.a2dp@1.0",
         "libhidlbase",
         "liblog",
         "libprotobuf-cpp-lite",
@@ -132,7 +133,9 @@
         "libbtcore",
         "libbt-stack",
         "libbt-sbc-encoder",
+        "libbt-utils",
         "libFraunhoferAAC",
+        "libg722codec",
         "libbtdevice",
         "libbt-hci",
         "libudrv-uipc",
diff --git a/btif/src/btif_a2dp_audio_interface.cc b/btif/src/btif_a2dp_audio_interface.cc
index 56adb9b..b74dca7 100644
--- a/btif/src/btif_a2dp_audio_interface.cc
+++ b/btif/src/btif_a2dp_audio_interface.cc
@@ -50,8 +50,10 @@
 using android::hardware::ProcessState;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
+using ::android::hardware::hidl_death_recipient;
 using ::android::hardware::hidl_vec;
 using ::android::sp;
+using ::android::wp;
 android::sp<IBluetoothAudioOffload> btAudio;
 
 #define CASE_RETURN_STR(const) \
@@ -65,6 +67,7 @@
 static void btif_a2dp_audio_send_suspend_req();
 static void btif_a2dp_audio_interface_init();
 static void btif_a2dp_audio_interface_deinit();
+static void btif_a2dp_audio_interface_restart_session();
 // Delay reporting
 // static void btif_a2dp_audio_send_sink_latency();
 
@@ -91,6 +94,20 @@
       }*/
 };
 
+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) {
   switch (resp) {
     case A2DP_CTRL_ACK_SUCCESS:
@@ -190,6 +207,12 @@
   btAudio = IBluetoothAudioOffload::getService();
   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_TAG, "%s: IBluetoothAudioOffload::getService() returned %p (%s)",
       __func__, btAudio.get(), (btAudio->isRemote() ? "remote" : "local"));
@@ -199,6 +222,14 @@
 
 static void btif_a2dp_audio_interface_deinit() {
   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;
 }
 
@@ -222,6 +253,18 @@
   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) {
   LOG_INFO(LOG_TAG, "%s: status = %d", __func__, status);
   if (btAudio != nullptr) {