summaryrefslogtreecommitdiffstats
path: root/media/libmedia/IMediaDeathNotifier.cpp
diff options
context:
space:
mode:
authorJames Dong <jdong@google.com>2010-01-15 18:13:58 -0800
committerJames Dong <jdong@google.com>2010-01-15 18:28:16 -0800
commitdd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675 (patch)
tree538c2d1505e11dbb55aa0839c3181d96e812868c /media/libmedia/IMediaDeathNotifier.cpp
parent97419ed670a12f48a7609673da8ee5dc0376f075 (diff)
downloadframeworks_av-dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675.zip
frameworks_av-dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675.tar.gz
frameworks_av-dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675.tar.bz2
Media server death nodification
Diffstat (limited to 'media/libmedia/IMediaDeathNotifier.cpp')
-rw-r--r--media/libmedia/IMediaDeathNotifier.cpp111
1 files changed, 111 insertions, 0 deletions
diff --git a/media/libmedia/IMediaDeathNotifier.cpp b/media/libmedia/IMediaDeathNotifier.cpp
new file mode 100644
index 0000000..39ac076
--- /dev/null
+++ b/media/libmedia/IMediaDeathNotifier.cpp
@@ -0,0 +1,111 @@
+/*
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "IMediaDeathNotifier"
+#include <utils/Log.h>
+
+#include <binder/IServiceManager.h>
+#include <binder/IPCThreadState.h>
+#include <media/IMediaDeathNotifier.h>
+
+namespace android {
+
+// client singleton for binder interface to services
+Mutex IMediaDeathNotifier::sServiceLock;
+sp<IMediaPlayerService> IMediaDeathNotifier::sMediaPlayerService;
+sp<IMediaDeathNotifier::DeathNotifier> IMediaDeathNotifier::sDeathNotifier;
+SortedVector< wp<IMediaDeathNotifier> > IMediaDeathNotifier::sObitRecipients;
+
+// establish binder interface to MediaPlayerService
+/*static*/const sp<IMediaPlayerService>&
+IMediaDeathNotifier::getMediaPlayerService()
+{
+ LOGV("getMediaPlayerService");
+ Mutex::Autolock _l(sServiceLock);
+ if (sMediaPlayerService.get() == 0) {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder;
+ do {
+ binder = sm->getService(String16("media.player"));
+ if (binder != 0) {
+ break;
+ }
+ LOGW("Media player service not published, waiting...");
+ usleep(500000); // 0.5 s
+ } while(true);
+
+ if (sDeathNotifier == NULL) {
+ sDeathNotifier = new DeathNotifier();
+ }
+ binder->linkToDeath(sDeathNotifier);
+ sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
+ }
+ LOGE_IF(sMediaPlayerService == 0, "no media player service!?");
+ return sMediaPlayerService;
+}
+
+/*static*/ void
+IMediaDeathNotifier::addObitRecipient(const wp<IMediaDeathNotifier>& recipient)
+{
+ LOGV("addObitRecipient");
+ Mutex::Autolock _l(sServiceLock);
+ sObitRecipients.add(recipient);
+}
+
+/*static*/ void
+IMediaDeathNotifier::removeObitRecipient(const wp<IMediaDeathNotifier>& recipient)
+{
+ LOGV("removeObitRecipient");
+ Mutex::Autolock _l(sServiceLock);
+ sObitRecipients.remove(recipient);
+}
+
+void
+IMediaDeathNotifier::DeathNotifier::binderDied(const wp<IBinder>& who) {
+ LOGW("media server died");
+
+ // Need to do this with the lock held
+ SortedVector< wp<IMediaDeathNotifier> > list;
+ {
+ Mutex::Autolock _l(sServiceLock);
+ sMediaPlayerService.clear();
+ list = sObitRecipients;
+ }
+
+ // Notify application when media server dies.
+ // Don't hold the static lock during callback in case app
+ // makes a call that needs the lock.
+ size_t count = list.size();
+ for (size_t iter = 0; iter < count; ++iter) {
+ sp<IMediaDeathNotifier> notifier = list[iter].promote();
+ if (notifier != 0) {
+ notifier->died();
+ }
+ }
+}
+
+IMediaDeathNotifier::DeathNotifier::~DeathNotifier()
+{
+ LOGV("DeathNotifier::~DeathNotifier");
+ Mutex::Autolock _l(sServiceLock);
+ sObitRecipients.clear();
+ if (sMediaPlayerService != 0) {
+ sMediaPlayerService->asBinder()->unlinkToDeath(this);
+ }
+}
+
+}; // namespace android