Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6dc3a3e2 authored by Marco Nelissen's avatar Marco Nelissen
Browse files

Report other servers' deaths in OnErrorListener too

otherwise applications will be unaware of those processes dying.

Bug: 22775369
Change-Id: I48577f787a97ee7627ae8e7f32e2f21ace243ed0
parent 35443e32
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -650,6 +650,28 @@ sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerT
    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 @@ sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
        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(),
+27 −0
Original line number Diff line number Diff line
@@ -229,6 +229,14 @@ public:

            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 @@ private:
                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 @@ private:
        // 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
+41 −1
Original line number Diff line number Diff line
@@ -335,6 +335,28 @@ MediaRecorderClient::~MediaRecorderClient()
    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 @@ status_t MediaRecorderClient::setListener(const sp<IMediaRecorderClient>& listen
        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) {
+20 −0
Original line number Diff line number Diff line
@@ -28,7 +28,23 @@ class ICameraRecordingProxy;
class IGraphicBufferProducer;

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 @@ private:
                                                               const String16& opPackageName);
    virtual                ~MediaRecorderClient();

    sp<IBinder::DeathRecipient> mCameraDeathListener;
    sp<IBinder::DeathRecipient> mCodecDeathListener;
    sp<IBinder::DeathRecipient> mAudioDeathListener;

    pid_t                  mPid;
    Mutex                  mLock;
    MediaRecorderBase      *mRecorder;