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 25namespace android { 26 27// client singleton for binder interface to services 28Mutex IMediaDeathNotifier::sServiceLock; 29sp<IMediaPlayerService> IMediaDeathNotifier::sMediaPlayerService; 30sp<IMediaDeathNotifier::DeathNotifier> IMediaDeathNotifier::sDeathNotifier; 31SortedVector< wp<IMediaDeathNotifier> > IMediaDeathNotifier::sObitRecipients; 32 33// establish binder interface to MediaPlayerService 34/*static*/const sp<IMediaPlayerService>& 35IMediaDeathNotifier::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 62IMediaDeathNotifier::addObitRecipient(const wp<IMediaDeathNotifier>& recipient) 63{ 64 LOGV("addObitRecipient"); 65 Mutex::Autolock _l(sServiceLock); 66 sObitRecipients.add(recipient); 67} 68 69/*static*/ void 70IMediaDeathNotifier::removeObitRecipient(const wp<IMediaDeathNotifier>& recipient) 71{ 72 LOGV("removeObitRecipient"); 73 Mutex::Autolock _l(sServiceLock); 74 sObitRecipients.remove(recipient); 75} 76 77void 78IMediaDeathNotifier::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 101IMediaDeathNotifier::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