diff options
author | Eric Laurent <elaurent@google.com> | 2013-10-04 17:47:25 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-10-04 17:47:26 +0000 |
commit | da0926afdb12794497c93d68eee296f2d92bfa7e (patch) | |
tree | a63b647bd1c277b34709352d03a9f2b1a95e6665 /media | |
parent | 385e7509eb563c983647e72b1232225c2200435f (diff) | |
parent | 8db188489871c770d5d56cf67b0001222415db41 (diff) | |
download | frameworks_av-da0926afdb12794497c93d68eee296f2d92bfa7e.zip frameworks_av-da0926afdb12794497c93d68eee296f2d92bfa7e.tar.gz frameworks_av-da0926afdb12794497c93d68eee296f2d92bfa7e.tar.bz2 |
Merge "TimedEventQueue takes a wake lock" into klp-dev
Diffstat (limited to 'media')
-rw-r--r-- | media/libstagefright/Android.mk | 1 | ||||
-rw-r--r-- | media/libstagefright/TimedEventQueue.cpp | 76 | ||||
-rw-r--r-- | media/libstagefright/include/TimedEventQueue.h | 25 |
3 files changed, 99 insertions, 3 deletions
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk index 1f68b51..6a2a696 100644 --- a/media/libstagefright/Android.mk +++ b/media/libstagefright/Android.mk @@ -89,6 +89,7 @@ LOCAL_SHARED_LIBRARIES := \ libutils \ libvorbisidec \ libz \ + libpowermanager LOCAL_STATIC_LIBRARIES := \ libstagefright_color_conversion \ diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp index 7e9c4bf..74c5905 100644 --- a/media/libstagefright/TimedEventQueue.cpp +++ b/media/libstagefright/TimedEventQueue.cpp @@ -31,17 +31,24 @@ #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ALooper.h> +#include <binder/IServiceManager.h> +#include <powermanager/PowerManager.h> namespace android { TimedEventQueue::TimedEventQueue() : mNextEventID(1), mRunning(false), - mStopped(false) { + mStopped(false), + mDeathRecipient(new PMDeathRecipient(this)) { } TimedEventQueue::~TimedEventQueue() { stop(); + if (mPowerManager != 0) { + sp<IBinder> binder = mPowerManager->asBinder(); + binder->unlinkToDeath(mDeathRecipient); + } } void TimedEventQueue::start() { @@ -76,6 +83,11 @@ void TimedEventQueue::stop(bool flush) { void *dummy; pthread_join(mThread, &dummy); + // some events may be left in the queue if we did not flush and the wake lock + // must be released. + if (!mQueue.empty()) { + releaseWakeLock_l(); + } mQueue.clear(); mRunning = false; @@ -117,6 +129,9 @@ TimedEventQueue::event_id TimedEventQueue::postTimedEvent( mQueueHeadChangedCondition.signal(); } + if (mQueue.empty()) { + acquireWakeLock_l(); + } mQueue.insert(it, item); mQueueNotEmptyCondition.signal(); @@ -172,7 +187,9 @@ void TimedEventQueue::cancelEvents( (*it).event->setEventID(0); it = mQueue.erase(it); - + if (mQueue.empty()) { + releaseWakeLock_l(); + } if (stopAfterFirstMatch) { return; } @@ -280,7 +297,9 @@ sp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l( event->setEventID(0); mQueue.erase(it); - + if (mQueue.empty()) { + releaseWakeLock_l(); + } return event; } } @@ -290,5 +309,56 @@ sp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l( return NULL; } +void TimedEventQueue::acquireWakeLock_l() +{ + if (mWakeLockToken != 0) { + return; + } + if (mPowerManager == 0) { + // use checkService() to avoid blocking if power service is not up yet + sp<IBinder> binder = + defaultServiceManager()->checkService(String16("power")); + if (binder == 0) { + ALOGW("cannot connect to the power manager service"); + } else { + mPowerManager = interface_cast<IPowerManager>(binder); + binder->linkToDeath(mDeathRecipient); + } + } + if (mPowerManager != 0) { + sp<IBinder> binder = new BBinder(); + status_t status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK, + binder, + String16("TimedEventQueue"), + String16("media")); + if (status == NO_ERROR) { + mWakeLockToken = binder; + } + } +} + +void TimedEventQueue::releaseWakeLock_l() +{ + if (mWakeLockToken == 0) { + return; + } + if (mPowerManager != 0) { + mPowerManager->releaseWakeLock(mWakeLockToken, 0); + } + mWakeLockToken.clear(); +} + +void TimedEventQueue::clearPowerManager() +{ + Mutex::Autolock _l(mLock); + releaseWakeLock_l(); + mPowerManager.clear(); +} + +void TimedEventQueue::PMDeathRecipient::binderDied(const wp<IBinder>& who) +{ + mQueue->clearPowerManager(); +} + } // namespace android diff --git a/media/libstagefright/include/TimedEventQueue.h b/media/libstagefright/include/TimedEventQueue.h index 11f844c..4e49c83 100644 --- a/media/libstagefright/include/TimedEventQueue.h +++ b/media/libstagefright/include/TimedEventQueue.h @@ -23,6 +23,7 @@ #include <utils/List.h> #include <utils/RefBase.h> #include <utils/threads.h> +#include <powermanager/IPowerManager.h> namespace android { @@ -57,6 +58,21 @@ struct TimedEventQueue { Event &operator=(const Event &); }; + class PMDeathRecipient : public IBinder::DeathRecipient { + public: + PMDeathRecipient(TimedEventQueue *queue) : mQueue(queue) {} + virtual ~PMDeathRecipient() {} + + // IBinder::DeathRecipient + virtual void binderDied(const wp<IBinder>& who); + + private: + PMDeathRecipient(const PMDeathRecipient&); + PMDeathRecipient& operator = (const PMDeathRecipient&); + + TimedEventQueue *mQueue; + }; + TimedEventQueue(); ~TimedEventQueue(); @@ -96,6 +112,8 @@ struct TimedEventQueue { static int64_t getRealTimeUs(); + void clearPowerManager(); + private: struct QueueItem { sp<Event> event; @@ -118,11 +136,18 @@ private: bool mRunning; bool mStopped; + sp<IPowerManager> mPowerManager; + sp<IBinder> mWakeLockToken; + const sp<PMDeathRecipient> mDeathRecipient; + static void *ThreadWrapper(void *me); void threadEntry(); sp<Event> removeEventFromQueue_l(event_id id); + void acquireWakeLock_l(); + void releaseWakeLock_l(); + TimedEventQueue(const TimedEventQueue &); TimedEventQueue &operator=(const TimedEventQueue &); }; |