Report other servers' deaths in OnErrorListener too

otherwise applications will be unaware of those processes dying.

Bug: 22775369
Change-Id: I48577f787a97ee7627ae8e7f32e2f21ace243ed0
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 9b081e9..0f983cd 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -650,6 +650,28 @@
     return p;
 }
 
+MediaPlayerService::Client::ServiceDeathNotifier::ServiceDeathNotifier(
+        const sp<IBinder>& service,
+        const sp<MediaPlayerBase>& listener,
+        int which) {
+    mService = service;
+    mListener = listener;
+    mWhich = which;
+}
+
+MediaPlayerService::Client::ServiceDeathNotifier::~ServiceDeathNotifier() {
+    mService->unlinkToDeath(this);
+}
+
+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);
+    }
+}
+
 sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
         player_type playerType)
 {
@@ -661,6 +683,19 @@
         return p;
     }
 
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16("media.extractor"));
+    mExtractorDeathListener = new ServiceDeathNotifier(binder, p, MEDIAEXTRACTOR_PROCESS_DEATH);
+    binder->linkToDeath(mExtractorDeathListener);
+
+    binder = sm->getService(String16("media.codec"));
+    mCodecDeathListener = new ServiceDeathNotifier(binder, p, MEDIACODEC_PROCESS_DEATH);
+    binder->linkToDeath(mCodecDeathListener);
+
+    binder = sm->getService(String16("media.audio_flinger"));
+    mAudioDeathListener = new ServiceDeathNotifier(binder, p, AUDIO_PROCESS_DEATH);
+    binder->linkToDeath(mAudioDeathListener);
+
     if (!p->hardwareOutput()) {
         Mutex::Autolock l(mLock);
         mAudioOutput = new AudioOutput(mAudioSessionId, IPCThreadState::self()->getCallingUid(),
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 80593b2..ef2819a 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -229,6 +229,14 @@
 
             void                removeClient(wp<Client> client);
 
+    enum {
+        MEDIASERVER_PROCESS_DEATH = 0,
+        MEDIAEXTRACTOR_PROCESS_DEATH = 1,
+        MEDIACODEC_PROCESS_DEATH = 2,
+        AUDIO_PROCESS_DEATH = 3,
+        CAMERA_PROCESS_DEATH = 4
+    };
+
     // For battery usage tracking purpose
     struct BatteryUsageInfo {
         // how many streams are being played by one UID
@@ -336,6 +344,22 @@
                 audio_session_t getAudioSessionId() { return mAudioSessionId; }
 
     private:
+        class ServiceDeathNotifier: public IBinder::DeathRecipient
+        {
+        public:
+            ServiceDeathNotifier(
+                    const sp<IBinder>& service,
+                    const sp<MediaPlayerBase>& listener,
+                    int which);
+            virtual ~ServiceDeathNotifier();
+            virtual void binderDied(const wp<IBinder>& who);
+
+        private:
+            int mWhich;
+            sp<IBinder> mService;
+            wp<MediaPlayerBase> mListener;
+        };
+
         friend class MediaPlayerService;
                                 Client( const sp<MediaPlayerService>& service,
                                         pid_t pid,
@@ -395,6 +419,9 @@
         // getMetadata clears this set.
         media::Metadata::Filter mMetadataUpdated;  // protected by mLock
 
+        sp<IBinder::DeathRecipient> mExtractorDeathListener;
+        sp<IBinder::DeathRecipient> mCodecDeathListener;
+        sp<IBinder::DeathRecipient> mAudioDeathListener;
 #if CALLBACK_ANTAGONIZER
                     Antagonizer*                mAntagonizer;
 #endif
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 3152e04..2832166 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -335,6 +335,28 @@
     release();
 }
 
+MediaRecorderClient::ServiceDeathNotifier::ServiceDeathNotifier(
+        const sp<IBinder>& service,
+        const sp<IMediaRecorderClient>& listener,
+        int which) {
+    mService = service;
+    mListener = listener;
+    mWhich = which;
+}
+
+MediaRecorderClient::ServiceDeathNotifier::~ServiceDeathNotifier() {
+    mService->unlinkToDeath(this);
+}
+
+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);
+    }
+}
+
 status_t MediaRecorderClient::setListener(const sp<IMediaRecorderClient>& listener)
 {
     ALOGV("setListener");
@@ -343,7 +365,25 @@
         ALOGE("recorder is not initialized");
         return NO_INIT;
     }
-    return mRecorder->setListener(listener);
+    mRecorder->setListener(listener);
+
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16("media.camera"));
+    mCameraDeathListener = new ServiceDeathNotifier(binder, listener,
+            MediaPlayerService::CAMERA_PROCESS_DEATH);
+    binder->linkToDeath(mCameraDeathListener);
+
+    binder = sm->getService(String16("media.codec"));
+    mCodecDeathListener = new ServiceDeathNotifier(binder, listener,
+            MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
+    binder->linkToDeath(mCodecDeathListener);
+
+    binder = sm->getService(String16("media.audio_flinger"));
+    mAudioDeathListener = new ServiceDeathNotifier(binder, listener,
+            MediaPlayerService::AUDIO_PROCESS_DEATH);
+    binder->linkToDeath(mAudioDeathListener);
+
+    return OK;
 }
 
 status_t MediaRecorderClient::setClientName(const String16& clientName) {
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index 5a080df..6e70194 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -29,6 +29,22 @@
 
 class MediaRecorderClient : public BnMediaRecorder
 {
+    class ServiceDeathNotifier: public IBinder::DeathRecipient
+    {
+    public:
+        ServiceDeathNotifier(
+                const sp<IBinder>& service,
+                const sp<IMediaRecorderClient>& listener,
+                int which);
+        virtual ~ServiceDeathNotifier();
+        virtual void binderDied(const wp<IBinder>& who);
+
+    private:
+        int mWhich;
+        sp<IBinder> mService;
+        wp<IMediaRecorderClient> mListener;
+    };
+
 public:
     virtual     status_t   setCamera(const sp<hardware::ICamera>& camera,
                                     const sp<ICameraRecordingProxy>& proxy);
@@ -69,6 +85,10 @@
                                                                const String16& opPackageName);
     virtual                ~MediaRecorderClient();
 
+    sp<IBinder::DeathRecipient> mCameraDeathListener;
+    sp<IBinder::DeathRecipient> mCodecDeathListener;
+    sp<IBinder::DeathRecipient> mAudioDeathListener;
+
     pid_t                  mPid;
     Mutex                  mLock;
     MediaRecorderBase      *mRecorder;