1dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong/*
2dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong** Copyright 2010, The Android Open Source Project
3dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong**
4dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong** Licensed under the Apache License, Version 2.0 (the "License");
5dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong** you may not use this file except in compliance with the License.
6dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong** You may obtain a copy of the License at
7dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong**
8dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong**     http://www.apache.org/licenses/LICENSE-2.0
9dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong**
10dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong** Unless required by applicable law or agreed to in writing, software
11dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong** distributed under the License is distributed on an "AS IS" BASIS,
12dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong** See the License for the specific language governing permissions and
14dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong** limitations under the License.
15dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong*/
16dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong
17dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong//#define LOG_NDEBUG 0
18dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong#define LOG_TAG "IMediaDeathNotifier"
19dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong#include <utils/Log.h>
20dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong
21dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong#include <binder/IServiceManager.h>
22dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong#include <binder/IPCThreadState.h>
23dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong#include <media/IMediaDeathNotifier.h>
24dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong
25dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dongnamespace android {
26dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong
27dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong// client singleton for binder interface to services
28dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James DongMutex IMediaDeathNotifier::sServiceLock;
29dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dongsp<IMediaPlayerService> IMediaDeathNotifier::sMediaPlayerService;
30dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dongsp<IMediaDeathNotifier::DeathNotifier> IMediaDeathNotifier::sDeathNotifier;
31dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James DongSortedVector< wp<IMediaDeathNotifier> > IMediaDeathNotifier::sObitRecipients;
32dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong
33dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong// establish binder interface to MediaPlayerService
34dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong/*static*/const sp<IMediaPlayerService>&
35dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James DongIMediaDeathNotifier::getMediaPlayerService()
36dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong{
373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("getMediaPlayerService");
38dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    Mutex::Autolock _l(sServiceLock);
397fc9a6fdf146ded90b51c52f4a05d797294dcb85Glenn Kasten    if (sMediaPlayerService == 0) {
40dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong        sp<IServiceManager> sm = defaultServiceManager();
41dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong        sp<IBinder> binder;
42dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong        do {
43dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong            binder = sm->getService(String16("media.player"));
44dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong            if (binder != 0) {
45dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong                break;
46e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            }
47e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            ALOGW("Media player service not published, waiting...");
48e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            usleep(500000); // 0.5 s
49e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        } while (true);
50dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong
51dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong        if (sDeathNotifier == NULL) {
527c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten            sDeathNotifier = new DeathNotifier();
537c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        }
547c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        binder->linkToDeath(sDeathNotifier);
557c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
56dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    }
5729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");
58dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    return sMediaPlayerService;
59dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong}
60dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong
61dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong/*static*/ void
62dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James DongIMediaDeathNotifier::addObitRecipient(const wp<IMediaDeathNotifier>& recipient)
63dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong{
643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("addObitRecipient");
65dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    Mutex::Autolock _l(sServiceLock);
66dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    sObitRecipients.add(recipient);
67dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong}
68dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong
69dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong/*static*/ void
70dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James DongIMediaDeathNotifier::removeObitRecipient(const wp<IMediaDeathNotifier>& recipient)
71dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong{
723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("removeObitRecipient");
73dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    Mutex::Autolock _l(sServiceLock);
74dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    sObitRecipients.remove(recipient);
75dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong}
76dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong
77dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dongvoid
787c7be1e05634d96d08210efb4bdeb012ffba440dGlenn KastenIMediaDeathNotifier::DeathNotifier::binderDied(const wp<IBinder>& who __unused) {
795ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block    ALOGW("media server died");
80dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong
81dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    // Need to do this with the lock held
82dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    SortedVector< wp<IMediaDeathNotifier> > list;
83dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    {
84dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong        Mutex::Autolock _l(sServiceLock);
85dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong        sMediaPlayerService.clear();
86dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong        list = sObitRecipients;
87dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    }
88dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong
89dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    // Notify application when media server dies.
90dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    // Don't hold the static lock during callback in case app
91dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    // makes a call that needs the lock.
92dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    size_t count = list.size();
93dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    for (size_t iter = 0; iter < count; ++iter) {
94dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong        sp<IMediaDeathNotifier> notifier = list[iter].promote();
95dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong        if (notifier != 0) {
96dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong            notifier->died();
97dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong        }
98dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    }
99dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong}
100dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong
101dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James DongIMediaDeathNotifier::DeathNotifier::~DeathNotifier()
102dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong{
1033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("DeathNotifier::~DeathNotifier");
104dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    Mutex::Autolock _l(sServiceLock);
105dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    sObitRecipients.clear();
106dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    if (sMediaPlayerService != 0) {
10706b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen        IInterface::asBinder(sMediaPlayerService)->unlinkToDeath(this);
108dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    }
109dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong}
110dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong
11140bc906252974d0b389ae4a147232d0c9a97193fGlenn Kasten} // namespace android
112