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