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>& 35 IMediaDeathNotifier::getMediaPlayerService() 36 { 37 LOGV("getMediaPlayerService"); 38 Mutex::Autolock _l(sServiceLock); 39 if (sMediaPlayerService.get() == 0) { 40 sp<IServiceManager> sm = defaultServiceManager(); 41 sp<IBinder> binder; 42 do { 43 binder = sm->getService(String16("media.player")); 44 if (binder != 0) { 45 break; 46 } 47 LOGW("Media player service not published, waiting..."); 48 usleep(500000); // 0.5 s 49 } while(true); 50 51 if (sDeathNotifier == NULL) { 52 sDeathNotifier = new DeathNotifier(); 53 } 54 binder->linkToDeath(sDeathNotifier); 55 sMediaPlayerService = interface_cast<IMediaPlayerService>(binder); 56 } 57 LOGE_IF(sMediaPlayerService == 0, "no media player service!?"); 58 return sMediaPlayerService; 59 } 60 61 /*static*/ void 62 IMediaDeathNotifier::addObitRecipient(const wp<IMediaDeathNotifier>& recipient) 63 { 64 LOGV("addObitRecipient"); 65 Mutex::Autolock _l(sServiceLock); 66 sObitRecipients.add(recipient); 67 } 68 69 /*static*/ void 70 IMediaDeathNotifier::removeObitRecipient(const wp<IMediaDeathNotifier>& recipient) 71 { 72 LOGV("removeObitRecipient"); 73 Mutex::Autolock _l(sServiceLock); 74 sObitRecipients.remove(recipient); 75 } 76 77 void 78 IMediaDeathNotifier::DeathNotifier::binderDied(const wp<IBinder>& who) { 79 LOGW("media server died"); 80 81 // Need to do this with the lock held 82 SortedVector< wp<IMediaDeathNotifier> > list; 83 { 84 Mutex::Autolock _l(sServiceLock); 85 sMediaPlayerService.clear(); 86 list = sObitRecipients; 87 } 88 89 // Notify application when media server dies. 90 // Don't hold the static lock during callback in case app 91 // makes a call that needs the lock. 92 size_t count = list.size(); 93 for (size_t iter = 0; iter < count; ++iter) { 94 sp<IMediaDeathNotifier> notifier = list[iter].promote(); 95 if (notifier != 0) { 96 notifier->died(); 97 } 98 } 99 } 100 101 IMediaDeathNotifier::DeathNotifier::~DeathNotifier() 102 { 103 LOGV("DeathNotifier::~DeathNotifier"); 104 Mutex::Autolock _l(sServiceLock); 105 sObitRecipients.clear(); 106 if (sMediaPlayerService != 0) { 107 sMediaPlayerService->asBinder()->unlinkToDeath(this); 108 } 109 } 110 111 }; // namespace android 112