134bbc22cbca0004475788f06be2300fef23c6a52James Dong/*
234bbc22cbca0004475788f06be2300fef23c6a52James Dong** Copyright 2010, The Android Open Source Project
334bbc22cbca0004475788f06be2300fef23c6a52James Dong**
434bbc22cbca0004475788f06be2300fef23c6a52James Dong** Licensed under the Apache License, Version 2.0 (the "License");
534bbc22cbca0004475788f06be2300fef23c6a52James Dong** you may not use this file except in compliance with the License.
634bbc22cbca0004475788f06be2300fef23c6a52James Dong** You may obtain a copy of the License at
734bbc22cbca0004475788f06be2300fef23c6a52James Dong**
834bbc22cbca0004475788f06be2300fef23c6a52James Dong**     http://www.apache.org/licenses/LICENSE-2.0
934bbc22cbca0004475788f06be2300fef23c6a52James Dong**
1034bbc22cbca0004475788f06be2300fef23c6a52James Dong** Unless required by applicable law or agreed to in writing, software
1134bbc22cbca0004475788f06be2300fef23c6a52James Dong** distributed under the License is distributed on an "AS IS" BASIS,
1234bbc22cbca0004475788f06be2300fef23c6a52James Dong** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1334bbc22cbca0004475788f06be2300fef23c6a52James Dong** See the License for the specific language governing permissions and
1434bbc22cbca0004475788f06be2300fef23c6a52James Dong** limitations under the License.
1534bbc22cbca0004475788f06be2300fef23c6a52James Dong*/
1634bbc22cbca0004475788f06be2300fef23c6a52James Dong
1734bbc22cbca0004475788f06be2300fef23c6a52James Dong//#define LOG_NDEBUG 0
1834bbc22cbca0004475788f06be2300fef23c6a52James Dong#define LOG_TAG "IMediaDeathNotifier"
1934bbc22cbca0004475788f06be2300fef23c6a52James Dong#include <utils/Log.h>
2034bbc22cbca0004475788f06be2300fef23c6a52James Dong
2134bbc22cbca0004475788f06be2300fef23c6a52James Dong#include <binder/IServiceManager.h>
2234bbc22cbca0004475788f06be2300fef23c6a52James Dong#include <binder/IPCThreadState.h>
2334bbc22cbca0004475788f06be2300fef23c6a52James Dong#include <media/IMediaDeathNotifier.h>
2434bbc22cbca0004475788f06be2300fef23c6a52James Dong
2534bbc22cbca0004475788f06be2300fef23c6a52James Dongnamespace android {
2634bbc22cbca0004475788f06be2300fef23c6a52James Dong
2734bbc22cbca0004475788f06be2300fef23c6a52James Dong// client singleton for binder interface to services
2834bbc22cbca0004475788f06be2300fef23c6a52James DongMutex IMediaDeathNotifier::sServiceLock;
2934bbc22cbca0004475788f06be2300fef23c6a52James Dongsp<IMediaPlayerService> IMediaDeathNotifier::sMediaPlayerService;
3034bbc22cbca0004475788f06be2300fef23c6a52James Dongsp<IMediaDeathNotifier::DeathNotifier> IMediaDeathNotifier::sDeathNotifier;
3134bbc22cbca0004475788f06be2300fef23c6a52James DongSortedVector< wp<IMediaDeathNotifier> > IMediaDeathNotifier::sObitRecipients;
3234bbc22cbca0004475788f06be2300fef23c6a52James Dong
3334bbc22cbca0004475788f06be2300fef23c6a52James Dong// establish binder interface to MediaPlayerService
3434bbc22cbca0004475788f06be2300fef23c6a52James Dong/*static*/const sp<IMediaPlayerService>&
3534bbc22cbca0004475788f06be2300fef23c6a52James DongIMediaDeathNotifier::getMediaPlayerService()
3634bbc22cbca0004475788f06be2300fef23c6a52James Dong{
3734bbc22cbca0004475788f06be2300fef23c6a52James Dong    LOGV("getMediaPlayerService");
3834bbc22cbca0004475788f06be2300fef23c6a52James Dong    Mutex::Autolock _l(sServiceLock);
3934bbc22cbca0004475788f06be2300fef23c6a52James Dong    if (sMediaPlayerService.get() == 0) {
4034bbc22cbca0004475788f06be2300fef23c6a52James Dong        sp<IServiceManager> sm = defaultServiceManager();
4134bbc22cbca0004475788f06be2300fef23c6a52James Dong        sp<IBinder> binder;
4234bbc22cbca0004475788f06be2300fef23c6a52James Dong        do {
4334bbc22cbca0004475788f06be2300fef23c6a52James Dong            binder = sm->getService(String16("media.player"));
4434bbc22cbca0004475788f06be2300fef23c6a52James Dong            if (binder != 0) {
4534bbc22cbca0004475788f06be2300fef23c6a52James Dong                break;
4634bbc22cbca0004475788f06be2300fef23c6a52James Dong             }
4734bbc22cbca0004475788f06be2300fef23c6a52James Dong             LOGW("Media player service not published, waiting...");
4834bbc22cbca0004475788f06be2300fef23c6a52James Dong             usleep(500000); // 0.5 s
4934bbc22cbca0004475788f06be2300fef23c6a52James Dong        } while(true);
5034bbc22cbca0004475788f06be2300fef23c6a52James Dong
5134bbc22cbca0004475788f06be2300fef23c6a52James Dong        if (sDeathNotifier == NULL) {
5234bbc22cbca0004475788f06be2300fef23c6a52James Dong        sDeathNotifier = new DeathNotifier();
5334bbc22cbca0004475788f06be2300fef23c6a52James Dong    }
5434bbc22cbca0004475788f06be2300fef23c6a52James Dong    binder->linkToDeath(sDeathNotifier);
5534bbc22cbca0004475788f06be2300fef23c6a52James Dong    sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
5634bbc22cbca0004475788f06be2300fef23c6a52James Dong    }
5734bbc22cbca0004475788f06be2300fef23c6a52James Dong    LOGE_IF(sMediaPlayerService == 0, "no media player service!?");
5834bbc22cbca0004475788f06be2300fef23c6a52James Dong    return sMediaPlayerService;
5934bbc22cbca0004475788f06be2300fef23c6a52James Dong}
6034bbc22cbca0004475788f06be2300fef23c6a52James Dong
6134bbc22cbca0004475788f06be2300fef23c6a52James Dong/*static*/ void
6234bbc22cbca0004475788f06be2300fef23c6a52James DongIMediaDeathNotifier::addObitRecipient(const wp<IMediaDeathNotifier>& recipient)
6334bbc22cbca0004475788f06be2300fef23c6a52James Dong{
6434bbc22cbca0004475788f06be2300fef23c6a52James Dong    LOGV("addObitRecipient");
6534bbc22cbca0004475788f06be2300fef23c6a52James Dong    Mutex::Autolock _l(sServiceLock);
6634bbc22cbca0004475788f06be2300fef23c6a52James Dong    sObitRecipients.add(recipient);
6734bbc22cbca0004475788f06be2300fef23c6a52James Dong}
6834bbc22cbca0004475788f06be2300fef23c6a52James Dong
6934bbc22cbca0004475788f06be2300fef23c6a52James Dong/*static*/ void
7034bbc22cbca0004475788f06be2300fef23c6a52James DongIMediaDeathNotifier::removeObitRecipient(const wp<IMediaDeathNotifier>& recipient)
7134bbc22cbca0004475788f06be2300fef23c6a52James Dong{
7234bbc22cbca0004475788f06be2300fef23c6a52James Dong    LOGV("removeObitRecipient");
7334bbc22cbca0004475788f06be2300fef23c6a52James Dong    Mutex::Autolock _l(sServiceLock);
7434bbc22cbca0004475788f06be2300fef23c6a52James Dong    sObitRecipients.remove(recipient);
7534bbc22cbca0004475788f06be2300fef23c6a52James Dong}
7634bbc22cbca0004475788f06be2300fef23c6a52James Dong
7734bbc22cbca0004475788f06be2300fef23c6a52James Dongvoid
7834bbc22cbca0004475788f06be2300fef23c6a52James DongIMediaDeathNotifier::DeathNotifier::binderDied(const wp<IBinder>& who) {
7934bbc22cbca0004475788f06be2300fef23c6a52James Dong    LOGW("media server died");
8034bbc22cbca0004475788f06be2300fef23c6a52James Dong
8134bbc22cbca0004475788f06be2300fef23c6a52James Dong    // Need to do this with the lock held
8234bbc22cbca0004475788f06be2300fef23c6a52James Dong    SortedVector< wp<IMediaDeathNotifier> > list;
8334bbc22cbca0004475788f06be2300fef23c6a52James Dong    {
8434bbc22cbca0004475788f06be2300fef23c6a52James Dong        Mutex::Autolock _l(sServiceLock);
8534bbc22cbca0004475788f06be2300fef23c6a52James Dong        sMediaPlayerService.clear();
8634bbc22cbca0004475788f06be2300fef23c6a52James Dong        list = sObitRecipients;
8734bbc22cbca0004475788f06be2300fef23c6a52James Dong    }
8834bbc22cbca0004475788f06be2300fef23c6a52James Dong
8934bbc22cbca0004475788f06be2300fef23c6a52James Dong    // Notify application when media server dies.
9034bbc22cbca0004475788f06be2300fef23c6a52James Dong    // Don't hold the static lock during callback in case app
9134bbc22cbca0004475788f06be2300fef23c6a52James Dong    // makes a call that needs the lock.
9234bbc22cbca0004475788f06be2300fef23c6a52James Dong    size_t count = list.size();
9334bbc22cbca0004475788f06be2300fef23c6a52James Dong    for (size_t iter = 0; iter < count; ++iter) {
9434bbc22cbca0004475788f06be2300fef23c6a52James Dong        sp<IMediaDeathNotifier> notifier = list[iter].promote();
9534bbc22cbca0004475788f06be2300fef23c6a52James Dong        if (notifier != 0) {
9634bbc22cbca0004475788f06be2300fef23c6a52James Dong            notifier->died();
9734bbc22cbca0004475788f06be2300fef23c6a52James Dong        }
9834bbc22cbca0004475788f06be2300fef23c6a52James Dong    }
9934bbc22cbca0004475788f06be2300fef23c6a52James Dong}
10034bbc22cbca0004475788f06be2300fef23c6a52James Dong
10134bbc22cbca0004475788f06be2300fef23c6a52James DongIMediaDeathNotifier::DeathNotifier::~DeathNotifier()
10234bbc22cbca0004475788f06be2300fef23c6a52James Dong{
10334bbc22cbca0004475788f06be2300fef23c6a52James Dong    LOGV("DeathNotifier::~DeathNotifier");
10434bbc22cbca0004475788f06be2300fef23c6a52James Dong    Mutex::Autolock _l(sServiceLock);
10534bbc22cbca0004475788f06be2300fef23c6a52James Dong    sObitRecipients.clear();
10634bbc22cbca0004475788f06be2300fef23c6a52James Dong    if (sMediaPlayerService != 0) {
10734bbc22cbca0004475788f06be2300fef23c6a52James Dong        sMediaPlayerService->asBinder()->unlinkToDeath(this);
10834bbc22cbca0004475788f06be2300fef23c6a52James Dong    }
10934bbc22cbca0004475788f06be2300fef23c6a52James Dong}
11034bbc22cbca0004475788f06be2300fef23c6a52James Dong
11134bbc22cbca0004475788f06be2300fef23c6a52James Dong}; // namespace android
112