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