diff options
author | James Dong <jdong@google.com> | 2010-01-15 18:13:58 -0800 |
---|---|---|
committer | James Dong <jdong@google.com> | 2010-01-15 18:28:16 -0800 |
commit | dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675 (patch) | |
tree | 538c2d1505e11dbb55aa0839c3181d96e812868c /media | |
parent | 97419ed670a12f48a7609673da8ee5dc0376f075 (diff) | |
download | frameworks_av-dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675.zip frameworks_av-dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675.tar.gz frameworks_av-dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675.tar.bz2 |
Media server death nodification
Diffstat (limited to 'media')
-rw-r--r-- | media/libmedia/Android.mk | 3 | ||||
-rw-r--r-- | media/libmedia/IMediaDeathNotifier.cpp | 111 | ||||
-rw-r--r-- | media/libmedia/mediaplayer.cpp | 90 | ||||
-rw-r--r-- | media/libmedia/mediarecorder.cpp | 20 |
4 files changed, 129 insertions, 95 deletions
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index fc234ee..4ae4ec9 100644 --- a/media/libmedia/Android.mk +++ b/media/libmedia/Android.mk @@ -24,7 +24,8 @@ LOCAL_SRC_FILES:= \ IAudioPolicyService.cpp \ MediaScanner.cpp \ MediaScannerClient.cpp \ - autodetect.cpp + autodetect.cpp \ + IMediaDeathNotifier.cpp LOCAL_SHARED_LIBRARIES := \ libui libcutils libutils libbinder libsonivox libicuuc 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 diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index 040366b..c0664f3 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -34,48 +34,6 @@ namespace android { -// client singleton for binder interface to service -Mutex MediaPlayer::sServiceLock; -sp<IMediaPlayerService> MediaPlayer::sMediaPlayerService; -sp<MediaPlayer::DeathNotifier> MediaPlayer::sDeathNotifier; -SortedVector< wp<MediaPlayer> > MediaPlayer::sObitRecipients; - -// establish binder interface to service -const sp<IMediaPlayerService>& MediaPlayer::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("MediaPlayerService 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 MediaPlayerService!?"); - return sMediaPlayerService; -} - -void MediaPlayer::addObitRecipient(const wp<MediaPlayer>& recipient) -{ - Mutex::Autolock _l(sServiceLock); - sObitRecipients.add(recipient); -} - -void MediaPlayer::removeObitRecipient(const wp<MediaPlayer>& recipient) -{ - Mutex::Autolock _l(sServiceLock); - sObitRecipients.remove(recipient); -} - MediaPlayer::MediaPlayer() { LOGV("constructor"); @@ -94,15 +52,9 @@ MediaPlayer::MediaPlayer() mLockThreadId = 0; } -void MediaPlayer::onFirstRef() -{ - addObitRecipient(this); -} - MediaPlayer::~MediaPlayer() { LOGV("destructor"); - removeObitRecipient(this); disconnect(); IPCThreadState::self()->flushCommands(); } @@ -630,45 +582,13 @@ void MediaPlayer::notify(int msg, int ext1, int ext2) } } -void MediaPlayer::DeathNotifier::binderDied(const wp<IBinder>& who) { - LOGW("MediaPlayer server died!"); - - // Need to do this with the lock held - SortedVector< wp<MediaPlayer> > list; - { - Mutex::Autolock _l(MediaPlayer::sServiceLock); - MediaPlayer::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<MediaPlayer> player = list[iter].promote(); - if ((player != 0) && (player->mPlayer != 0)) { - player->notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, 0); - } - } -} - -MediaPlayer::DeathNotifier::~DeathNotifier() -{ - Mutex::Autolock _l(sServiceLock); - sObitRecipients.clear(); - if (sMediaPlayerService != 0) { - sMediaPlayerService->asBinder()->unlinkToDeath(this); - } -} - /*static*/ sp<IMemory> MediaPlayer::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) { LOGV("decode(%s)", url); sp<IMemory> p; const sp<IMediaPlayerService>& service = getMediaPlayerService(); if (service != 0) { - p = sMediaPlayerService->decode(url, pSampleRate, pNumChannels, pFormat); + p = service->decode(url, pSampleRate, pNumChannels, pFormat); } else { LOGE("Unable to locate media service"); } @@ -676,13 +596,19 @@ MediaPlayer::DeathNotifier::~DeathNotifier() } +void MediaPlayer::died() +{ + LOGV("died"); + notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, 0); +} + /*static*/ sp<IMemory> MediaPlayer::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) { LOGV("decode(%d, %lld, %lld)", fd, offset, length); sp<IMemory> p; const sp<IMediaPlayerService>& service = getMediaPlayerService(); if (service != 0) { - p = sMediaPlayerService->decode(fd, offset, length, pSampleRate, pNumChannels, pFormat); + p = service->decode(fd, offset, length, pSampleRate, pNumChannels, pFormat); } else { LOGE("Unable to locate media service"); } diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp index 6b63931..7b5dabb 100644 --- a/media/libmedia/mediarecorder.cpp +++ b/media/libmedia/mediarecorder.cpp @@ -24,6 +24,7 @@ #include <utils/String8.h> #include <media/IMediaPlayerService.h> #include <media/IMediaRecorder.h> +#include <media/mediaplayer.h> // for MEDIA_ERROR_SERVER_DIED namespace android { @@ -576,19 +577,8 @@ status_t MediaRecorder::release() MediaRecorder::MediaRecorder() { LOGV("constructor"); - sp<IServiceManager> sm = defaultServiceManager(); - sp<IBinder> binder; - do { - binder = sm->getService(String16("media.player")); - if (binder != NULL) { - break; - } - LOGW("MediaPlayerService not published, waiting..."); - usleep(500000); // 0.5 s - } while(true); - - sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); + const sp<IMediaPlayerService>& service(getMediaPlayerService()); if (service != NULL) { mMediaRecorder = service->createMediaRecorder(getpid()); } @@ -637,5 +627,11 @@ void MediaRecorder::notify(int msg, int ext1, int ext2) } } +void MediaRecorder::died() +{ + LOGV("died"); + notify(MEDIA_RECORDER_EVENT_ERROR, MEDIA_ERROR_SERVER_DIED, 0); +} + }; // namespace android |