Home | History | Annotate | Download | only in libmedia
      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