• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()35 IMediaDeathNotifier::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)56 IMediaDeathNotifier::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)64 IMediaDeathNotifier::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)72 IMediaDeathNotifier::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()95 IMediaDeathNotifier::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