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

Commit e73b46ef authored by James Dong's avatar James Dong Committed by Android (Google) Code Review
Browse files

Merge "Media server death nodification"

parents f078d058 34bbc22c
Loading
Loading
Loading
Loading
+61 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 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_IMEDIADEATHNOTIFIER_H
#define ANDROID_IMEDIADEATHNOTIFIER_H

#include <utils/threads.h>
#include <media/IMediaPlayerService.h>
#include <utils/SortedVector.h>

namespace android {

class IMediaDeathNotifier: virtual public RefBase
{
public:
    IMediaDeathNotifier() { addObitRecipient(this); }
    virtual ~IMediaDeathNotifier() { removeObitRecipient(this); }

    virtual void died() = 0;
    static const sp<IMediaPlayerService>& getMediaPlayerService();

private:
    IMediaDeathNotifier &operator=(const IMediaDeathNotifier &);
    IMediaDeathNotifier(const IMediaDeathNotifier &);

    static void addObitRecipient(const wp<IMediaDeathNotifier>& recipient);
    static void removeObitRecipient(const wp<IMediaDeathNotifier>& recipient);

    class DeathNotifier: public IBinder::DeathRecipient
    {
    public:
                DeathNotifier() {}
        virtual ~DeathNotifier();

        virtual void binderDied(const wp<IBinder>& who);
    };

    friend class DeathNotifier;

    static  Mutex                                   sServiceLock;
    static  sp<IMediaPlayerService>                 sMediaPlayerService;
    static  sp<DeathNotifier>                       sDeathNotifier;
    static  SortedVector< wp<IMediaDeathNotifier> > sObitRecipients;
};

}; // namespace android

#endif // ANDROID_IMEDIADEATHNOTIFIER_H
+4 −24
Original line number Diff line number Diff line
@@ -21,8 +21,7 @@
#include <ui/Surface.h>
#include <media/IMediaPlayerClient.h>
#include <media/IMediaPlayer.h>
#include <media/IMediaPlayerService.h>
#include <utils/SortedVector.h>
#include <media/IMediaDeathNotifier.h>

namespace android {

@@ -123,12 +122,13 @@ public:
    virtual void notify(int msg, int ext1, int ext2) = 0;
};

class MediaPlayer : public BnMediaPlayerClient
class MediaPlayer : public BnMediaPlayerClient,
                    public virtual IMediaDeathNotifier
{
public:
    MediaPlayer();
    ~MediaPlayer();
            void            onFirstRef();
            void            died();
            void            disconnect();
            status_t        setDataSource(const char *url);
            status_t        setDataSource(int fd, int64_t offset, int64_t length);
@@ -164,19 +164,6 @@ private:
            status_t        getDuration_l(int *msec);
            status_t        setDataSource(const sp<IMediaPlayer>& player);

    static const sp<IMediaPlayerService>& getMediaPlayerService();
    static void addObitRecipient(const wp<MediaPlayer>& recipient);
    static void removeObitRecipient(const wp<MediaPlayer>& recipient);

    class DeathNotifier: public IBinder::DeathRecipient
    {
    public:
                DeathNotifier() {}
        virtual ~DeathNotifier();

        virtual void binderDied(const wp<IBinder>& who);
    };

    sp<IMediaPlayer>            mPlayer;
    thread_id_t                 mLockThreadId;
    Mutex                       mLock;
@@ -196,13 +183,6 @@ private:
    float                       mRightVolume;
    int                         mVideoWidth;
    int                         mVideoHeight;

    friend class DeathNotifier;

    static  Mutex                           sServiceLock;
    static  sp<IMediaPlayerService>         sMediaPlayerService;
    static  sp<DeathNotifier>               sDeathNotifier;
    static  SortedVector< wp<MediaPlayer> > sObitRecipients;
};

}; // namespace android
+4 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <utils/List.h>
#include <utils/Errors.h>
#include <media/IMediaPlayerClient.h>
#include <media/IMediaDeathNotifier.h>

namespace android {

@@ -145,12 +146,14 @@ public:
    virtual void notify(int msg, int ext1, int ext2) = 0;
};

class MediaRecorder : public BnMediaPlayerClient
class MediaRecorder : public BnMediaPlayerClient,
                      public virtual IMediaDeathNotifier
{
public:
    MediaRecorder();
    ~MediaRecorder();

    void        died();
    status_t    initCheck();
    status_t    setCamera(const sp<ICamera>& camera);
    status_t    setPreviewSurface(const sp<Surface>& surface);
+2 −1
Original line number Diff line number Diff line
@@ -24,7 +24,8 @@ LOCAL_SRC_FILES:= \
    IAudioPolicyService.cpp \
    MediaScanner.cpp \
    MediaScannerClient.cpp \
    autodetect.cpp
    autodetect.cpp \
    IMediaDeathNotifier.cpp

LOCAL_SHARED_LIBRARIES := \
	libui libcutils libutils libbinder libsonivox libicuuc
+111 −0
Original line number Diff line number Diff line
/*
** Copyright 2010, 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 "IMediaDeathNotifier"
#include <utils/Log.h>

#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <media/IMediaDeathNotifier.h>

namespace android {

// client singleton for binder interface to services
Mutex IMediaDeathNotifier::sServiceLock;
sp<IMediaPlayerService> IMediaDeathNotifier::sMediaPlayerService;
sp<IMediaDeathNotifier::DeathNotifier> IMediaDeathNotifier::sDeathNotifier;
SortedVector< wp<IMediaDeathNotifier> > IMediaDeathNotifier::sObitRecipients;

// establish binder interface to MediaPlayerService
/*static*/const sp<IMediaPlayerService>&
IMediaDeathNotifier::getMediaPlayerService()
{
    LOGV("getMediaPlayerService");
    Mutex::Autolock _l(sServiceLock);
    if (sMediaPlayerService.get() == 0) {
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
        do {
            binder = sm->getService(String16("media.player"));
            if (binder != 0) {
                break;
             }
             LOGW("Media player service not published, waiting...");
             usleep(500000); // 0.5 s
        } while(true);

        if (sDeathNotifier == NULL) {
        sDeathNotifier = new DeathNotifier();
    }
    binder->linkToDeath(sDeathNotifier);
    sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
    }
    LOGE_IF(sMediaPlayerService == 0, "no media player service!?");
    return sMediaPlayerService;
}

/*static*/ void
IMediaDeathNotifier::addObitRecipient(const wp<IMediaDeathNotifier>& recipient)
{
    LOGV("addObitRecipient");
    Mutex::Autolock _l(sServiceLock);
    sObitRecipients.add(recipient);
}

/*static*/ void
IMediaDeathNotifier::removeObitRecipient(const wp<IMediaDeathNotifier>& recipient)
{
    LOGV("removeObitRecipient");
    Mutex::Autolock _l(sServiceLock);
    sObitRecipients.remove(recipient);
}

void
IMediaDeathNotifier::DeathNotifier::binderDied(const wp<IBinder>& who) {
    LOGW("media server died");

    // Need to do this with the lock held
    SortedVector< wp<IMediaDeathNotifier> > list;
    {
        Mutex::Autolock _l(sServiceLock);
        sMediaPlayerService.clear();
        list = sObitRecipients;
    }

    // Notify application when media server dies.
    // Don't hold the static lock during callback in case app
    // makes a call that needs the lock.
    size_t count = list.size();
    for (size_t iter = 0; iter < count; ++iter) {
        sp<IMediaDeathNotifier> notifier = list[iter].promote();
        if (notifier != 0) {
            notifier->died();
        }
    }
}

IMediaDeathNotifier::DeathNotifier::~DeathNotifier()
{
    LOGV("DeathNotifier::~DeathNotifier");
    Mutex::Autolock _l(sServiceLock);
    sObitRecipients.clear();
    if (sMediaPlayerService != 0) {
        sMediaPlayerService->asBinder()->unlinkToDeath(this);
    }
}

}; // namespace android
Loading