diff options
author | Eric Laurent <elaurent@google.com> | 2013-10-03 17:54:26 -0700 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2013-10-04 10:11:34 -0700 |
commit | 8db188489871c770d5d56cf67b0001222415db41 (patch) | |
tree | de046fba2feb599ddf5a1d6d76735634ebb1afa7 | |
parent | 19fffcbd89a51af797265af2e11c97be5820a07d (diff) | |
download | frameworks_av-8db188489871c770d5d56cf67b0001222415db41.zip frameworks_av-8db188489871c770d5d56cf67b0001222415db41.tar.gz frameworks_av-8db188489871c770d5d56cf67b0001222415db41.tar.bz2 |
TimedEventQueue takes a wake lock
Take a wake lock when events present in a TimedEventQueue
to prevent from going idle before all delayed events are
processed.
Bug: 11057387.
Change-Id: I26a17df68068fde5e879a2fe7568dec439fc540f
-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 &); }; |