Make mediaserver listen to Codec2 services' deaths

Test: Kill media.extractor or mediaswcodec and observe logcat

Bug: 130071409

Change-Id: Ie785642da99dfe4ff13e78d878817dae3de9f34a
diff --git a/media/codec2/hidl/1.0/utils/Android.bp b/media/codec2/hidl/1.0/utils/Android.bp
index b2a5fee..b73f0c8 100644
--- a/media/codec2/hidl/1.0/utils/Android.bp
+++ b/media/codec2/hidl/1.0/utils/Android.bp
@@ -99,6 +99,7 @@
     export_shared_lib_headers: [
         "android.hardware.media.c2@1.0",
         "libcodec2",
+        "libcodec2_vndk",
         "libhidlbase",
         "libstagefright_bufferpool@2.0",
         "libui",
diff --git a/media/codec2/hidl/client/Android.bp b/media/codec2/hidl/client/Android.bp
index a174008..6038a40 100644
--- a/media/codec2/hidl/client/Android.bp
+++ b/media/codec2/hidl/client/Android.bp
@@ -31,6 +31,7 @@
     export_shared_lib_headers: [
         "libcodec2",
         "libcodec2_hidl_client@1.0",
+        "libcodec2_vndk",
     ],
 
 }
diff --git a/media/codec2/hidl/client/client.cpp b/media/codec2/hidl/client/client.cpp
index 53adbbc..6aca4a3 100644
--- a/media/codec2/hidl/client/client.cpp
+++ b/media/codec2/hidl/client/client.cpp
@@ -75,82 +75,11 @@
 // c2_status_t value that corresponds to hwbinder transaction failure.
 constexpr c2_status_t C2_TRANSACTION_FAILED = C2_CORRUPTED;
 
-// Returns the list of IComponentStore service names that are available on the
-// device. This list is specified at the build time in manifest files.
-// Note: A software service will have "_software" as a suffix.
-std::vector<std::string> const& getServiceNames() {
-    static std::vector<std::string> sServiceNames{[]() {
-        using ::android::hardware::media::c2::V1_0::IComponentStore;
-        using ::android::hidl::manager::V1_2::IServiceManager;
-
-        while (true) {
-            sp<IServiceManager> serviceManager = IServiceManager::getService();
-            CHECK(serviceManager) << "Hardware service manager is not running.";
-
-            // There are three categories of services based on names.
-            std::vector<std::string> defaultNames; // Prefixed with "default"
-            std::vector<std::string> vendorNames;  // Prefixed with "vendor"
-            std::vector<std::string> otherNames;   // Others
-            Return<void> transResult;
-            transResult = serviceManager->listManifestByInterface(
-                    IComponentStore::descriptor,
-                    [&defaultNames, &vendorNames, &otherNames](
-                            hidl_vec<hidl_string> const& instanceNames) {
-                        for (hidl_string const& instanceName : instanceNames) {
-                            char const* name = instanceName.c_str();
-                            if (strncmp(name, "default", 7) == 0) {
-                                defaultNames.emplace_back(name);
-                            } else if (strncmp(name, "vendor", 6) == 0) {
-                                vendorNames.emplace_back(name);
-                            } else {
-                                otherNames.emplace_back(name);
-                            }
-                        }
-                    });
-            if (transResult.isOk()) {
-                // Sort service names in each category.
-                std::sort(defaultNames.begin(), defaultNames.end());
-                std::sort(vendorNames.begin(), vendorNames.end());
-                std::sort(otherNames.begin(), otherNames.end());
-
-                // Concatenate the three lists in this order: default, vendor,
-                // other.
-                std::vector<std::string>& names = defaultNames;
-                names.reserve(names.size() + vendorNames.size() + otherNames.size());
-                names.insert(names.end(),
-                             std::make_move_iterator(vendorNames.begin()),
-                             std::make_move_iterator(vendorNames.end()));
-                names.insert(names.end(),
-                             std::make_move_iterator(otherNames.begin()),
-                             std::make_move_iterator(otherNames.end()));
-
-                // Summarize to logcat.
-                if (names.empty()) {
-                    LOG(INFO) << "No Codec2 services declared in the manifest.";
-                } else {
-                    std::stringstream stringOutput;
-                    stringOutput << "Available Codec2 services:";
-                    for (std::string const& name : names) {
-                        stringOutput << " \"" << name << "\"";
-                    }
-                    LOG(INFO) << stringOutput.str();
-                }
-
-                return names;
-            }
-            LOG(ERROR) << "Could not retrieve the list of service instances of "
-                       << IComponentStore::descriptor
-                       << ". Retrying...";
-        }
-    }()};
-    return sServiceNames;
-}
-
-// Searches for a name in getServiceNames() and returns the index found. If the
+// Searches for a name in GetServiceNames() and returns the index found. If the
 // name is not found, the returned index will be equal to
-// getServiceNames().size().
+// GetServiceNames().size().
 size_t getServiceIndex(char const* name) {
-    std::vector<std::string> const& names = getServiceNames();
+    std::vector<std::string> const& names = Codec2Client::GetServiceNames();
     size_t i = 0;
     for (; i < names.size(); ++i) {
         if (name == names[i]) {
@@ -175,17 +104,14 @@
     std::vector<C2Component::Traits> mTraits;
     std::once_flag mTraitsInitializationFlag;
 
-    // The index of the service. This is based on getServiceNames().
+    // The index of the service. This is based on GetServiceNames().
     size_t mIndex;
-    // A "valid" cache object must have its mIndex set with init().
-    bool mValid{false};
     // Called by s() exactly once to initialize the cache. The index must be a
-    // valid index into the vector returned by getServiceNames(). Calling
+    // valid index into the vector returned by GetServiceNames(). Calling
     // init(index) will associate the cache to the service with name
-    // getServiceNames()[index].
+    // GetServiceNames()[index].
     void init(size_t index) {
         mIndex = index;
-        mValid = true;
     }
 
 public:
@@ -195,7 +121,6 @@
     // If the service is unavailable but listed in the manifest, this function
     // will block indefinitely.
     std::shared_ptr<Codec2Client> getClient() {
-        CHECK(mValid) << "Uninitialized cache";
         std::scoped_lock lock{mClientMutex};
         if (!mClient) {
             mClient = Codec2Client::_CreateFromIndex(mIndex);
@@ -208,7 +133,6 @@
     //
     // Note: This function is called only by ForAllServices().
     void invalidate() {
-        CHECK(mValid) << "Uninitialized cache";
         std::scoped_lock lock{mClientMutex};
         mClient = nullptr;
     }
@@ -216,7 +140,6 @@
     // Returns a list of traits for components supported by the service. This
     // list is cached.
     std::vector<C2Component::Traits> const& getTraits() {
-        CHECK(mValid) << "Uninitialized cache";
         std::call_once(mTraitsInitializationFlag, [this]() {
             bool success{false};
             // Spin until _listComponents() is successful.
@@ -229,7 +152,7 @@
                 using namespace std::chrono_literals;
                 static constexpr auto kServiceRetryPeriod = 5s;
                 LOG(INFO) << "Failed to retrieve component traits from service "
-                             "\"" << getServiceNames()[mIndex] << "\". "
+                             "\"" << GetServiceNames()[mIndex] << "\". "
                              "Retrying...";
                 std::this_thread::sleep_for(kServiceRetryPeriod);
             }
@@ -240,7 +163,7 @@
     // List() returns the list of all caches.
     static std::vector<Cache>& List() {
         static std::vector<Cache> sCaches{[]() {
-            size_t numServices = getServiceNames().size();
+            size_t numServices = GetServiceNames().size();
             std::vector<Cache> caches(numServices);
             for (size_t i = 0; i < numServices; ++i) {
                 caches[i].init(i);
@@ -610,8 +533,12 @@
     }
 }
 
+sp<Codec2Client::Base> const& Codec2Client::getBase() const {
+    return mBase;
+}
+
 std::string const& Codec2Client::getServiceName() const {
-    return getServiceNames()[mServiceIndex];
+    return GetServiceNames()[mServiceIndex];
 }
 
 c2_status_t Codec2Client::createComponent(
@@ -807,15 +734,94 @@
     return std::make_shared<SimpleParamReflector>(mBase);
 };
 
+std::vector<std::string> const& Codec2Client::GetServiceNames() {
+    static std::vector<std::string> sServiceNames{[]() {
+        using ::android::hardware::media::c2::V1_0::IComponentStore;
+        using ::android::hidl::manager::V1_2::IServiceManager;
+
+        while (true) {
+            sp<IServiceManager> serviceManager = IServiceManager::getService();
+            CHECK(serviceManager) << "Hardware service manager is not running.";
+
+            // There are three categories of services based on names.
+            std::vector<std::string> defaultNames; // Prefixed with "default"
+            std::vector<std::string> vendorNames;  // Prefixed with "vendor"
+            std::vector<std::string> otherNames;   // Others
+            Return<void> transResult;
+            transResult = serviceManager->listManifestByInterface(
+                    IComponentStore::descriptor,
+                    [&defaultNames, &vendorNames, &otherNames](
+                            hidl_vec<hidl_string> const& instanceNames) {
+                        for (hidl_string const& instanceName : instanceNames) {
+                            char const* name = instanceName.c_str();
+                            if (strncmp(name, "default", 7) == 0) {
+                                defaultNames.emplace_back(name);
+                            } else if (strncmp(name, "vendor", 6) == 0) {
+                                vendorNames.emplace_back(name);
+                            } else {
+                                otherNames.emplace_back(name);
+                            }
+                        }
+                    });
+            if (transResult.isOk()) {
+                // Sort service names in each category.
+                std::sort(defaultNames.begin(), defaultNames.end());
+                std::sort(vendorNames.begin(), vendorNames.end());
+                std::sort(otherNames.begin(), otherNames.end());
+
+                // Concatenate the three lists in this order: default, vendor,
+                // other.
+                std::vector<std::string>& names = defaultNames;
+                names.reserve(names.size() + vendorNames.size() + otherNames.size());
+                names.insert(names.end(),
+                             std::make_move_iterator(vendorNames.begin()),
+                             std::make_move_iterator(vendorNames.end()));
+                names.insert(names.end(),
+                             std::make_move_iterator(otherNames.begin()),
+                             std::make_move_iterator(otherNames.end()));
+
+                // Summarize to logcat.
+                if (names.empty()) {
+                    LOG(INFO) << "No Codec2 services declared in the manifest.";
+                } else {
+                    std::stringstream stringOutput;
+                    stringOutput << "Available Codec2 services:";
+                    for (std::string const& name : names) {
+                        stringOutput << " \"" << name << "\"";
+                    }
+                    LOG(INFO) << stringOutput.str();
+                }
+
+                return names;
+            }
+            LOG(ERROR) << "Could not retrieve the list of service instances of "
+                       << IComponentStore::descriptor
+                       << ". Retrying...";
+        }
+    }()};
+    return sServiceNames;
+}
+
 std::shared_ptr<Codec2Client> Codec2Client::CreateFromService(
         const char* name) {
     size_t index = getServiceIndex(name);
-    return index == getServiceNames().size() ?
+    return index == GetServiceNames().size() ?
             nullptr : _CreateFromIndex(index);
 }
 
+std::vector<std::shared_ptr<Codec2Client>> Codec2Client::
+        CreateFromAllServices() {
+    std::vector<std::shared_ptr<Codec2Client>> clients(
+            GetServiceNames().size());
+    for (size_t i = GetServiceNames().size(); i > 0; ) {
+        --i;
+        clients[i] = _CreateFromIndex(i);
+    }
+    return clients;
+}
+
 std::shared_ptr<Codec2Client> Codec2Client::_CreateFromIndex(size_t index) {
-    std::string const& name = getServiceNames()[index];
+    std::string const& name = GetServiceNames()[index];
     LOG(INFO) << "Creating a Codec2 client to service \"" << name << "\"";
     sp<Base> baseStore = Base::getService(name);
     CHECK(baseStore) << "Codec2 service \"" << name << "\""
@@ -958,17 +964,17 @@
     if (inputSurfaceSetting == 0) {
         return nullptr;
     }
-    size_t index = getServiceNames().size();
+    size_t index = GetServiceNames().size();
     if (serviceName) {
         index = getServiceIndex(serviceName);
-        if (index == getServiceNames().size()) {
+        if (index == GetServiceNames().size()) {
             LOG(DEBUG) << "CreateInputSurface -- invalid service name: \""
                        << serviceName << "\"";
         }
     }
 
     std::shared_ptr<Codec2Client::InputSurface> inputSurface;
-    if (index != getServiceNames().size()) {
+    if (index != GetServiceNames().size()) {
         std::shared_ptr<Codec2Client> client = Cache::List()[index].getClient();
         if (client->createInputSurface(&inputSurface) == C2_OK) {
             return inputSurface;
diff --git a/media/codec2/hidl/client/include/codec2/hidl/client.h b/media/codec2/hidl/client/include/codec2/hidl/client.h
index 1851752..03db515 100644
--- a/media/codec2/hidl/client/include/codec2/hidl/client.h
+++ b/media/codec2/hidl/client/include/codec2/hidl/client.h
@@ -143,6 +143,8 @@
 
     typedef Codec2Client Store;
 
+    sp<Base> const& getBase() const;
+
     std::string const& getServiceName() const;
 
     c2_status_t createComponent(
@@ -165,8 +167,17 @@
 
     std::shared_ptr<C2ParamReflector> getParamReflector();
 
+    // Returns the list of IComponentStore service names that are available on
+    // the device. This list is specified at the build time in manifest files.
+    // Note: A software service will have "_software" as a suffix.
+    static std::vector<std::string> const& GetServiceNames();
+
+    // Create a service with a given service name.
     static std::shared_ptr<Codec2Client> CreateFromService(char const* name);
 
+    // Get clients to all services.
+    static std::vector<std::shared_ptr<Codec2Client>> CreateFromAllServices();
+
     // Try to create a component with a given name from all known
     // IComponentStore services.
     static std::shared_ptr<Component> CreateComponentByName(
diff --git a/media/libmediaplayerservice/Android.bp b/media/libmediaplayerservice/Android.bp
index 0776172..6709585 100644
--- a/media/libmediaplayerservice/Android.bp
+++ b/media/libmediaplayerservice/Android.bp
@@ -2,6 +2,7 @@
 
     srcs: [
         "ActivityManager.cpp",
+        "DeathNotifier.cpp",
         "MediaPlayerFactory.cpp",
         "MediaPlayerService.cpp",
         "MediaRecorderClient.cpp",
@@ -17,6 +18,7 @@
         "libaudioclient",
         "libbinder",
         "libcamera_client",
+        "libcodec2_client",
         "libcrypto",
         "libcutils",
         "libdl",
diff --git a/media/libmediaplayerservice/DeathNotifier.cpp b/media/libmediaplayerservice/DeathNotifier.cpp
new file mode 100644
index 0000000..d13bdf5
--- /dev/null
+++ b/media/libmediaplayerservice/DeathNotifier.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2019 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaPlayerService-DeathNotifier"
+#include <android-base/logging.h>
+
+#include "DeathNotifier.h"
+
+namespace android {
+
+class DeathNotifier::DeathRecipient :
+        public IBinder::DeathRecipient,
+        public hardware::hidl_death_recipient {
+public:
+    using Notify = DeathNotifier::Notify;
+
+    DeathRecipient(Notify const& notify): mNotify{notify} {
+    }
+
+    virtual void binderDied(wp<IBinder> const&) override {
+        mNotify();
+    }
+
+    virtual void serviceDied(uint64_t, wp<HBase> const&) override {
+        mNotify();
+    }
+
+private:
+    Notify mNotify;
+};
+
+DeathNotifier::DeathNotifier(sp<IBinder> const& service, Notify const& notify)
+      : mService{std::in_place_index<1>, service},
+        mDeathRecipient{new DeathRecipient(notify)} {
+    service->linkToDeath(mDeathRecipient);
+}
+
+DeathNotifier::DeathNotifier(sp<HBase> const& service, Notify const& notify)
+      : mService{std::in_place_index<2>, service},
+        mDeathRecipient{new DeathRecipient(notify)} {
+    service->linkToDeath(mDeathRecipient, 0);
+}
+
+DeathNotifier::DeathNotifier(DeathNotifier&& other)
+      : mService{other.mService}, mDeathRecipient{other.mDeathRecipient} {
+    other.mService.emplace<0>();
+    other.mDeathRecipient = nullptr;
+}
+
+DeathNotifier::~DeathNotifier() {
+    switch (mService.index()) {
+    case 0:
+        break;
+    case 1:
+        std::get<1>(mService)->unlinkToDeath(mDeathRecipient);
+        break;
+    case 2:
+        std::get<2>(mService)->unlinkToDeath(mDeathRecipient);
+        break;
+    default:
+        CHECK(false) << "Corrupted service type during destruction.";
+    }
+}
+
+} // namespace android
+
diff --git a/media/libmediaplayerservice/DeathNotifier.h b/media/libmediaplayerservice/DeathNotifier.h
new file mode 100644
index 0000000..7bc2611
--- /dev/null
+++ b/media/libmediaplayerservice/DeathNotifier.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2019 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.
+ */
+
+#ifndef ANDROID_MEDIASERVICE_DEATHNOTIFIER_H
+#define ANDROID_MEDIASERVICE_DEATHNOTIFIER_H
+
+#include <android/hidl/base/1.0/IBase.h>
+#include <binder/Binder.h>
+#include <hidl/HidlSupport.h>
+
+#include <variant>
+
+namespace android {
+
+class DeathNotifier {
+public:
+    using HBase = hidl::base::V1_0::IBase;
+    using Notify = std::function<void()>;
+
+    DeathNotifier(sp<IBinder> const& service, Notify const& notify);
+    DeathNotifier(sp<HBase> const& service, Notify const& notify);
+    DeathNotifier(DeathNotifier&& other);
+    ~DeathNotifier();
+
+private:
+    std::variant<std::monostate, sp<IBinder>, sp<HBase>> mService;
+
+    class DeathRecipient;
+    sp<DeathRecipient> mDeathRecipient;
+};
+
+} // namespace android
+
+#endif // ANDROID_MEDIASERVICE_DEATHNOTIFIER_H
+
diff --git a/media/libmediaplayerservice/DeathRecipient.h b/media/libmediaplayerservice/DeathRecipient.h
new file mode 100644
index 0000000..bf5ae5c
--- /dev/null
+++ b/media/libmediaplayerservice/DeathRecipient.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2019 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.
+ */
+
+#ifndef ANDROID_MEDIASERVICE_DEATHRECIPIENT_H
+#define ANDROID_MEDIASERVICE_DEATHRECIPIENT_H
+
+#include <binder/binder.h>
+#include <hidl/HidlSupport.h>
+
+#include <variant>
+
+class DeathNotifier :
+        public IBinder::DeathRecipient,
+        public ::android::hardware::hidl_death_recipient {
+public:
+    using Service = std::variant<
+            sp<IBinder> const&,
+            sp<android::hidl::base::V1_0::IBase> const&>;
+
+    DeathNotifier(std::variant<sp<IBinder> const&, 
+            const sp<IBinder>& service,
+            const sp<MediaPlayerBase>& listener,
+            int which,
+            const std::string& name);
+    DeathNotifier(
+            const sp<android::hidl::base::V1_0::IBase>& hService,
+            const sp<MediaPlayerBase>& listener,
+            int which,
+            const std::string& name);
+    virtual ~DeathNotifier() = default;
+    virtual void binderDied(const wp<IBinder>& who);
+    virtual void serviceDied(
+            uint64_t cookie,
+            const wp<::android::hidl::base::V1_0::IBase>& who);
+    void unlinkToDeath();
+
+private:
+    sp<IBinder> mService;
+    sp<android::hidl::base::V1_0::IBase> mHService; // HIDL service
+    wp<MediaPlayerBase> mListener;
+    int mWhich;
+    std::string mName;
+};
+
+#endif // ANDROID_MEDIASERVICE_DEATHRECIPIENT_H
+
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 5061024..dfd3933 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -34,7 +34,7 @@
 
 #include <utils/misc.h>
 
-#include <android/hardware/media/omx/1.0/IOmxStore.h>
+#include <android/hardware/media/omx/1.0/IOmx.h>
 #include <android/hardware/media/c2/1.0/IComponentStore.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
@@ -47,6 +47,7 @@
 #include <utils/Timers.h>
 #include <utils/Vector.h>
 
+#include <codec2/hidl/client.h>
 #include <media/IMediaHTTPService.h>
 #include <media/IRemoteDisplay.h>
 #include <media/IRemoteDisplayClient.h>
@@ -591,7 +592,6 @@
     if (mAudioAttributes != NULL) {
         free(mAudioAttributes);
     }
-    clearDeathNotifiers_l();
     mAudioDeviceUpdatedListener.clear();
 }
 
@@ -647,59 +647,6 @@
     return p;
 }
 
-MediaPlayerService::Client::ServiceDeathNotifier::ServiceDeathNotifier(
-        const sp<IBinder>& service,
-        const sp<MediaPlayerBase>& listener,
-        int which) {
-    mService = service;
-    mHService = nullptr;
-    mListener = listener;
-    mWhich = which;
-}
-
-MediaPlayerService::Client::ServiceDeathNotifier::ServiceDeathNotifier(
-        const sp<android::hidl::base::V1_0::IBase>& hService,
-        const sp<MediaPlayerBase>& listener,
-        int which) {
-    mService = nullptr;
-    mHService = hService;
-    mListener = listener;
-    mWhich = which;
-}
-
-MediaPlayerService::Client::ServiceDeathNotifier::~ServiceDeathNotifier() {
-}
-
-void MediaPlayerService::Client::ServiceDeathNotifier::binderDied(const wp<IBinder>& /*who*/) {
-    sp<MediaPlayerBase> listener = mListener.promote();
-    if (listener != NULL) {
-        listener->sendEvent(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
-    } else {
-        ALOGW("listener for process %d death is gone", mWhich);
-    }
-}
-
-void MediaPlayerService::Client::ServiceDeathNotifier::serviceDied(
-        uint64_t /* cookie */,
-        const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
-    sp<MediaPlayerBase> listener = mListener.promote();
-    if (listener != NULL) {
-        listener->sendEvent(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
-    } else {
-        ALOGW("listener for process %d death is gone", mWhich);
-    }
-}
-
-void MediaPlayerService::Client::ServiceDeathNotifier::unlinkToDeath() {
-    if (mService != nullptr) {
-        mService->unlinkToDeath(this);
-        mService = nullptr;
-    } else if (mHService != nullptr) {
-        mHService->unlinkToDeath(this);
-        mHService = nullptr;
-    }
-}
-
 void MediaPlayerService::Client::AudioDeviceUpdatedNotifier::onAudioDeviceUpdate(
         audio_io_handle_t audioIo,
         audio_port_handle_t deviceId) {
@@ -711,19 +658,6 @@
     }
 }
 
-void MediaPlayerService::Client::clearDeathNotifiers_l() {
-    if (mExtractorDeathListener != nullptr) {
-        mExtractorDeathListener->unlinkToDeath();
-        mExtractorDeathListener = nullptr;
-    }
-    for (const sp<ServiceDeathNotifier>& codecDeathListener : mCodecDeathListeners) {
-        if (codecDeathListener != nullptr) {
-            codecDeathListener->unlinkToDeath();
-        }
-    }
-    mCodecDeathListeners.clear();
-}
-
 sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
         player_type playerType)
 {
@@ -735,66 +669,83 @@
         return p;
     }
 
+    std::vector<DeathNotifier> deathNotifiers;
+
+    // Listen to death of media.extractor service
     sp<IServiceManager> sm = defaultServiceManager();
     sp<IBinder> binder = sm->getService(String16("media.extractor"));
     if (binder == NULL) {
         ALOGE("extractor service not available");
         return NULL;
     }
-    sp<ServiceDeathNotifier> extractorDeathListener =
-            new ServiceDeathNotifier(binder, p, MEDIAEXTRACTOR_PROCESS_DEATH);
-    binder->linkToDeath(extractorDeathListener);
+    deathNotifiers.emplace_back(
+            binder, [l = wp<MediaPlayerBase>(p)]() {
+        sp<MediaPlayerBase> listener = l.promote();
+        if (listener) {
+            ALOGI("media.extractor died. Sending death notification.");
+            listener->sendEvent(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+                                MEDIAEXTRACTOR_PROCESS_DEATH);
+        } else {
+            ALOGW("media.extractor died without a death handler.");
+        }
+    });
 
-    std::vector<sp<ServiceDeathNotifier>> codecDeathListeners;
     {
         using ::android::hidl::base::V1_0::IBase;
 
-        // Listen to OMX's IOmxStore/default
+        // Listen to death of OMX service
         {
-            sp<IBase> store = ::android::hardware::media::omx::V1_0::
-                    IOmxStore::getService();
-            if (store == nullptr) {
+            sp<IBase> base = ::android::hardware::media::omx::V1_0::
+                    IOmx::getService();
+            if (base == nullptr) {
                 ALOGD("OMX service is not available");
             } else {
-                sp<ServiceDeathNotifier> codecDeathListener =
-                        new ServiceDeathNotifier(store, p, MEDIACODEC_PROCESS_DEATH);
-                store->linkToDeath(codecDeathListener, 0);
-                codecDeathListeners.emplace_back(codecDeathListener);
+                deathNotifiers.emplace_back(
+                        base, [l = wp<MediaPlayerBase>(p)]() {
+                    sp<MediaPlayerBase> listener = l.promote();
+                    if (listener) {
+                        ALOGI("OMX service died. "
+                              "Sending death notification.");
+                        listener->sendEvent(
+                                MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+                                MEDIACODEC_PROCESS_DEATH);
+                    } else {
+                        ALOGW("OMX service died without a death handler.");
+                    }
+                });
             }
         }
 
-        // Listen to Codec2's IComponentStore/software
-        // TODO: Listen to all Codec2 services.
+        // Listen to death of Codec2 services
         {
-            sp<IBase> store = ::android::hardware::media::c2::V1_0::
-                    IComponentStore::getService();
-            if (store == nullptr) {
-                ALOGD("Codec2 system service is not available");
-            } else {
-                sp<ServiceDeathNotifier> codecDeathListener =
-                        new ServiceDeathNotifier(store, p, MEDIACODEC_PROCESS_DEATH);
-                store->linkToDeath(codecDeathListener, 0);
-                codecDeathListeners.emplace_back(codecDeathListener);
-            }
-
-            store = ::android::hardware::media::c2::V1_0::
-                    IComponentStore::getService("software");
-            if (store == nullptr) {
-                ALOGD("Codec2 swcodec service is not available");
-            } else {
-                sp<ServiceDeathNotifier> codecDeathListener =
-                        new ServiceDeathNotifier(store, p, MEDIACODEC_PROCESS_DEATH);
-                store->linkToDeath(codecDeathListener, 0);
-                codecDeathListeners.emplace_back(codecDeathListener);
+            for (std::shared_ptr<Codec2Client> const& client :
+                    Codec2Client::CreateFromAllServices()) {
+                sp<IBase> base = client->getBase();
+                deathNotifiers.emplace_back(
+                        base, [l = wp<MediaPlayerBase>(p),
+                               name = std::string(client->getServiceName())]() {
+                    sp<MediaPlayerBase> listener = l.promote();
+                    if (listener) {
+                        ALOGI("Codec2 service \"%s\" died. "
+                              "Sending death notification.",
+                              name.c_str());
+                        listener->sendEvent(
+                                MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+                                MEDIACODEC_PROCESS_DEATH);
+                    } else {
+                        ALOGW("Codec2 service \"%s\" died "
+                              "without a death handler.",
+                              name.c_str());
+                    }
+                });
             }
         }
     }
 
     Mutex::Autolock lock(mLock);
 
-    clearDeathNotifiers_l();
-    mExtractorDeathListener = extractorDeathListener;
-    mCodecDeathListeners.swap(codecDeathListeners);
+    mDeathNotifiers.clear();
+    mDeathNotifiers.swap(deathNotifiers);
     mAudioDeviceUpdatedListener = new AudioDeviceUpdatedNotifier(p);
 
     if (!p->hardwareOutput()) {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 26bfa71..49688ce 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -30,8 +30,6 @@
 #include <media/Metadata.h>
 #include <media/stagefright/foundation/ABase.h>
 
-#include <hidl/HidlSupport.h>
-
 #include <system/audio.h>
 
 namespace android {
@@ -39,6 +37,7 @@
 struct AudioPlaybackRate;
 class AudioTrack;
 struct AVSyncSettings;
+class DeathNotifier;
 class IDataSource;
 class IMediaRecorder;
 class IMediaMetadataRetriever;
@@ -388,33 +387,6 @@
         virtual status_t enableAudioDeviceCallback(bool enabled);
 
     private:
-        class ServiceDeathNotifier:
-                public IBinder::DeathRecipient,
-                public ::android::hardware::hidl_death_recipient
-        {
-        public:
-            ServiceDeathNotifier(
-                    const sp<IBinder>& service,
-                    const sp<MediaPlayerBase>& listener,
-                    int which);
-            ServiceDeathNotifier(
-                    const sp<android::hidl::base::V1_0::IBase>& hService,
-                    const sp<MediaPlayerBase>& listener,
-                    int which);
-            virtual ~ServiceDeathNotifier();
-            virtual void binderDied(const wp<IBinder>& who);
-            virtual void serviceDied(
-                    uint64_t cookie,
-                    const wp<::android::hidl::base::V1_0::IBase>& who);
-            void unlinkToDeath();
-
-        private:
-            int mWhich;
-            sp<IBinder> mService;
-            sp<android::hidl::base::V1_0::IBase> mHService; // HIDL service
-            wp<MediaPlayerBase> mListener;
-        };
-
         class AudioDeviceUpdatedNotifier: public AudioSystem::AudioDeviceCallback
         {
         public:
@@ -430,8 +402,6 @@
             wp<MediaPlayerBase> mListener;
         };
 
-        void clearDeathNotifiers_l();
-
         friend class MediaPlayerService;
                                 Client( const sp<MediaPlayerService>& service,
                                         pid_t pid,
@@ -506,8 +476,7 @@
         // getMetadata clears this set.
         media::Metadata::Filter mMetadataUpdated;  // protected by mLock
 
-        sp<ServiceDeathNotifier> mExtractorDeathListener;
-        std::vector<sp<ServiceDeathNotifier>> mCodecDeathListeners;
+        std::vector<DeathNotifier> mDeathNotifiers;
         sp<AudioDeviceUpdatedNotifier> mAudioDeviceUpdatedListener;
 #if CALLBACK_ANTAGONIZER
                     Antagonizer*                  mAntagonizer;
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 9f4265b..703da4b 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -18,27 +18,28 @@
 #define LOG_TAG "MediaRecorderService"
 #include <utils/Log.h>
 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <string.h>
-#include <cutils/atomic.h>
-#include <cutils/properties.h> // for property_get
+#include "MediaRecorderClient.h"
+#include "MediaPlayerService.h"
+#include "StagefrightRecorder.h"
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/c2/1.0/IComponentStore.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 #include <binder/MemoryHeapBase.h>
 #include <binder/MemoryBase.h>
-
+#include <codec2/hidl/client.h>
+#include <cutils/atomic.h>
+#include <cutils/properties.h> // for property_get
+#include <gui/IGraphicBufferProducer.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <system/audio.h>
 #include <utils/String16.h>
 
-#include <system/audio.h>
-
-#include "MediaRecorderClient.h"
-#include "MediaPlayerService.h"
-
-#include "StagefrightRecorder.h"
-#include <gui/IGraphicBufferProducer.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <string.h>
 
 namespace android {
 
@@ -339,7 +340,7 @@
         wp<MediaRecorderClient> client(this);
         mMediaPlayerService->removeMediaRecorderClient(client);
     }
-    clearDeathNotifiers_l();
+    mDeathNotifiers.clear();
     return NO_ERROR;
 }
 
@@ -358,59 +359,6 @@
     release();
 }
 
-MediaRecorderClient::ServiceDeathNotifier::ServiceDeathNotifier(
-        const sp<IBinder>& service,
-        const sp<IMediaRecorderClient>& listener,
-        int which) {
-    mService = service;
-    mOmx = nullptr;
-    mListener = listener;
-    mWhich = which;
-}
-
-MediaRecorderClient::ServiceDeathNotifier::ServiceDeathNotifier(
-        const sp<IOmx>& omx,
-        const sp<IMediaRecorderClient>& listener,
-        int which) {
-    mService = nullptr;
-    mOmx = omx;
-    mListener = listener;
-    mWhich = which;
-}
-
-MediaRecorderClient::ServiceDeathNotifier::~ServiceDeathNotifier() {
-}
-
-void MediaRecorderClient::ServiceDeathNotifier::binderDied(const wp<IBinder>& /*who*/) {
-    sp<IMediaRecorderClient> listener = mListener.promote();
-    if (listener != NULL) {
-        listener->notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
-    } else {
-        ALOGW("listener for process %d death is gone", mWhich);
-    }
-}
-
-void MediaRecorderClient::ServiceDeathNotifier::serviceDied(
-        uint64_t /* cookie */,
-        const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
-    sp<IMediaRecorderClient> listener = mListener.promote();
-    if (listener != NULL) {
-        listener->notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
-    } else {
-        ALOGW("listener for process %d death is gone", mWhich);
-    }
-}
-
-void MediaRecorderClient::ServiceDeathNotifier::unlinkToDeath() {
-    if (mService != nullptr) {
-        mService->unlinkToDeath(this);
-        mService = nullptr;
-    } else if (mOmx != nullptr) {
-        mOmx->unlinkToDeath(this);
-        mOmx = nullptr;
-    }
-}
-
 MediaRecorderClient::AudioDeviceUpdatedNotifier::AudioDeviceUpdatedNotifier(
         const sp<IMediaRecorderClient>& listener) {
     mListener = listener;
@@ -430,22 +378,11 @@
     }
 }
 
-void MediaRecorderClient::clearDeathNotifiers_l() {
-    if (mCameraDeathListener != nullptr) {
-        mCameraDeathListener->unlinkToDeath();
-        mCameraDeathListener = nullptr;
-    }
-    if (mCodecDeathListener != nullptr) {
-        mCodecDeathListener->unlinkToDeath();
-        mCodecDeathListener = nullptr;
-    }
-}
-
 status_t MediaRecorderClient::setListener(const sp<IMediaRecorderClient>& listener)
 {
     ALOGV("setListener");
     Mutex::Autolock lock(mLock);
-    clearDeathNotifiers_l();
+    mDeathNotifiers.clear();
     if (mRecorder == NULL) {
         ALOGE("recorder is not initialized");
         return NO_INIT;
@@ -463,20 +400,73 @@
     // If the device does not have a camera, do not create a death listener for it.
     if (binder != NULL) {
         sCameraVerified = true;
-        mCameraDeathListener = new ServiceDeathNotifier(binder, listener,
-                MediaPlayerService::CAMERA_PROCESS_DEATH);
-        binder->linkToDeath(mCameraDeathListener);
+        mDeathNotifiers.emplace_back(
+                binder, [l = wp<IMediaRecorderClient>(listener)](){
+            sp<IMediaRecorderClient> listener = l.promote();
+            if (listener) {
+                ALOGV("media.camera service died. "
+                      "Sending death notification.");
+                listener->notify(
+                        MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+                        MediaPlayerService::CAMERA_PROCESS_DEATH);
+            } else {
+                ALOGW("media.camera service died without a death handler.");
+            }
+        });
     }
     sCameraChecked = true;
 
-    sp<IOmx> omx = IOmx::getService();
-    if (omx == nullptr) {
-        ALOGE("IOmx service is not available");
-        return NO_INIT;
+    {
+        using ::android::hidl::base::V1_0::IBase;
+
+        // Listen to OMX's IOmxStore/default
+        {
+            sp<IBase> base = ::android::hardware::media::omx::V1_0::
+                    IOmx::getService();
+            if (base == nullptr) {
+                ALOGD("OMX service is not available");
+            } else {
+                mDeathNotifiers.emplace_back(
+                        base, [l = wp<IMediaRecorderClient>(listener)](){
+                    sp<IMediaRecorderClient> listener = l.promote();
+                    if (listener) {
+                        ALOGV("OMX service died. "
+                              "Sending death notification.");
+                        listener->notify(
+                                MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+                                MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
+                    } else {
+                        ALOGW("OMX service died without a death handler.");
+                    }
+                });
+            }
+        }
+
+        // Listen to Codec2's IComponentStore instances
+        {
+            for (std::shared_ptr<Codec2Client> const& client :
+                    Codec2Client::CreateFromAllServices()) {
+                sp<IBase> base = client->getBase();
+                mDeathNotifiers.emplace_back(
+                        base, [l = wp<IMediaRecorderClient>(listener),
+                               name = std::string(client->getServiceName())]() {
+                    sp<IMediaRecorderClient> listener = l.promote();
+                    if (listener) {
+                        ALOGV("Codec2 service \"%s\" died. "
+                              "Sending death notification",
+                              name.c_str());
+                        listener->notify(
+                                MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+                                MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
+                    } else {
+                        ALOGW("Codec2 service \"%s\" died "
+                              "without a death handler",
+                              name.c_str());
+                    }
+                });
+            }
+        }
     }
-    mCodecDeathListener = new ServiceDeathNotifier(omx, listener,
-            MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
-    omx->linkToDeath(mCodecDeathListener, 0);
 
     mAudioDeviceUpdatedNotifier = new AudioDeviceUpdatedNotifier(listener);
     mRecorder->setAudioDeviceCallback(mAudioDeviceUpdatedNotifier);
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index e698819..9e0f877 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -18,10 +18,12 @@
 #ifndef ANDROID_MEDIARECORDERCLIENT_H
 #define ANDROID_MEDIARECORDERCLIENT_H
 
+#include "DeathNotifier.h"
+
 #include <media/AudioSystem.h>
 #include <media/IMediaRecorder.h>
 
-#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <vector>
 
 namespace android {
 
@@ -31,34 +33,6 @@
 
 class MediaRecorderClient : public BnMediaRecorder
 {
-    typedef ::android::hardware::media::omx::V1_0::IOmx IOmx;
-
-    class ServiceDeathNotifier :
-            public IBinder::DeathRecipient,
-            public ::android::hardware::hidl_death_recipient
-    {
-    public:
-        ServiceDeathNotifier(
-                const sp<IBinder>& service,
-                const sp<IMediaRecorderClient>& listener,
-                int which);
-        ServiceDeathNotifier(
-                const sp<IOmx>& omx,
-                const sp<IMediaRecorderClient>& listener,
-                int which);
-        virtual ~ServiceDeathNotifier();
-        virtual void binderDied(const wp<IBinder>& who);
-        virtual void serviceDied(
-                uint64_t cookie,
-                const wp<::android::hidl::base::V1_0::IBase>& who);
-        void unlinkToDeath();
-    private:
-        int mWhich;
-        sp<IBinder> mService;
-        sp<IOmx> mOmx;
-        wp<IMediaRecorderClient> mListener;
-    };
-
     class AudioDeviceUpdatedNotifier: public AudioSystem::AudioDeviceCallback
     {
     public:
@@ -71,8 +45,6 @@
         wp<IMediaRecorderClient> mListener;
     };
 
-    void clearDeathNotifiers_l();
-
 public:
     virtual     status_t   setCamera(const sp<hardware::ICamera>& camera,
                                     const sp<ICameraRecordingProxy>& proxy);
@@ -122,8 +94,7 @@
                                                                const String16& opPackageName);
     virtual                ~MediaRecorderClient();
 
-    sp<ServiceDeathNotifier> mCameraDeathListener;
-    sp<ServiceDeathNotifier> mCodecDeathListener;
+    std::vector<DeathNotifier> mDeathNotifiers;
     sp<AudioDeviceUpdatedNotifier> mAudioDeviceUpdatedNotifier;
 
     pid_t                  mPid;