libaudiohal@aidl: Add missing HAL death handler

The death handler is used when the HAL gets stopped
using 'sys.audio.restart.hal' system property.
In this case the HAL is restarted using 'stop / start'
sequence, and as a result, 'onrestart' event is not
triggered (that's intentional).

Bug: 328569315
Test: adb shell setprop sys.audio.restart.hal 1
      then check if both audioserver and HAL get restarted
Change-Id: I7368557d2a8cb37d758882e94b64d6446aa9a671
diff --git a/media/libaudiohal/impl/AidlUtils.cpp b/media/libaudiohal/impl/AidlUtils.cpp
new file mode 100644
index 0000000..a916802
--- /dev/null
+++ b/media/libaudiohal/impl/AidlUtils.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "AidlUtils.h"
+
+#define LOG_TAG "AIDLUtils"
+#include <utils/Log.h>
+
+namespace android {
+
+//static
+HalDeathHandler& HalDeathHandler::getInstance() {
+    // never-delete singleton
+    static HalDeathHandler* instance = new HalDeathHandler;
+    return *instance;
+}
+
+//static
+void HalDeathHandler::OnBinderDied(void*) {
+    ALOGE("HAL instance died, audio server is restarting");
+    _exit(1);  // Avoid calling atexit handlers, as this code runs on a thread from RPC threadpool.
+}
+
+HalDeathHandler::HalDeathHandler()
+        : mDeathRecipient(AIBinder_DeathRecipient_new(OnBinderDied)) {}
+
+bool HalDeathHandler::registerHandler(AIBinder* binder) {
+    binder_status_t status = AIBinder_linkToDeath(binder, mDeathRecipient.get(), nullptr);
+    if (status == STATUS_OK) return true;
+    ALOGE("%s: linkToDeath failed: %d", __func__, status);
+    return false;
+}
+
+}  // namespace android
diff --git a/media/libaudiohal/impl/AidlUtils.h b/media/libaudiohal/impl/AidlUtils.h
index 3d42b53..97a5bba 100644
--- a/media/libaudiohal/impl/AidlUtils.h
+++ b/media/libaudiohal/impl/AidlUtils.h
@@ -20,10 +20,24 @@
 #include <string>
 
 #include <android/binder_auto_utils.h>
+#include <android/binder_ibinder.h>
 #include <android/binder_manager.h>
 
 namespace android {
 
+class HalDeathHandler {
+  public:
+    static HalDeathHandler& getInstance();
+
+    bool registerHandler(AIBinder* binder);
+  private:
+    static void OnBinderDied(void*);
+
+    HalDeathHandler();
+
+    ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+};
+
 template<class Intf>
 std::shared_ptr<Intf> getServiceInstance(const std::string& instanceName) {
     const std::string serviceName =
@@ -37,6 +51,9 @@
         }
         // `fromBinder` may fail and return a nullptr if the service has died in the meantime.
         service = Intf::fromBinder(ndk::SpAIBinder(serviceBinder));
+        if (service != nullptr) {
+            HalDeathHandler::getInstance().registerHandler(serviceBinder);
+        }
     }
     return service;
 }
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index c7fa96e..dd8f021 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -262,6 +262,7 @@
     srcs: [
         ":audio_effect_hal_aidl_src_files",
         ":core_audio_hal_aidl_src_files",
+        "AidlUtils.cpp",
         "DevicesFactoryHalEntry.cpp",
         "EffectsFactoryHalEntry.cpp",
     ],