diff options
author | Eric Laurent <elaurent@google.com> | 2013-11-10 16:25:19 -0800 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2013-11-10 16:25:19 -0800 |
commit | 5b5f76dcb29792830baca1f25e51a732b80241df (patch) | |
tree | 9d5d9b02aa8ca89867021afa459ed1b65ce4ec8f /media | |
parent | 86f79f2332efad4862a4dd56f9552c93bbb52bcf (diff) | |
parent | a72911563b0e5b21b196d40249b53975bf8d8f85 (diff) | |
download | frameworks_av-5b5f76dcb29792830baca1f25e51a732b80241df.zip frameworks_av-5b5f76dcb29792830baca1f25e51a732b80241df.tar.gz frameworks_av-5b5f76dcb29792830baca1f25e51a732b80241df.tar.bz2 |
am a7291156: Merge "TimedEventQueue: improve wakelock management" into klp-dev
* commit 'a72911563b0e5b21b196d40249b53975bf8d8f85':
TimedEventQueue: improve wakelock management
Diffstat (limited to 'media')
-rw-r--r-- | media/libstagefright/TimedEventQueue.cpp | 94 | ||||
-rw-r--r-- | media/libstagefright/include/TimedEventQueue.h | 4 |
2 files changed, 55 insertions, 43 deletions
diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp index 6a16bb4..1a9a26b 100644 --- a/media/libstagefright/TimedEventQueue.cpp +++ b/media/libstagefright/TimedEventQueue.cpp @@ -38,11 +38,14 @@ namespace android { +static int64_t kWakelockMinDelay = 100000ll; // 100ms + TimedEventQueue::TimedEventQueue() : mNextEventID(1), mRunning(false), mStopped(false), - mDeathRecipient(new PMDeathRecipient(this)) { + mDeathRecipient(new PMDeathRecipient(this)), + mWakeLockCount(0) { } TimedEventQueue::~TimedEventQueue() { @@ -87,9 +90,7 @@ void TimedEventQueue::stop(bool flush) { // 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(); - } + releaseWakeLock_l(true /*force*/); mQueue.clear(); mRunning = false; @@ -126,13 +127,15 @@ TimedEventQueue::event_id TimedEventQueue::postTimedEvent( QueueItem item; item.event = event; item.realtime_us = realtime_us; + item.has_wakelock = false; if (it == mQueue.begin()) { mQueueHeadChangedCondition.signal(); } - if (mQueue.empty()) { + if (realtime_us > ALooper::GetNowUs() + kWakelockMinDelay) { acquireWakeLock_l(); + item.has_wakelock = true; } mQueue.insert(it, item); @@ -188,10 +191,10 @@ void TimedEventQueue::cancelEvents( ALOGV("cancelling event %d", (*it).event->eventID()); (*it).event->setEventID(0); - it = mQueue.erase(it); - if (mQueue.empty()) { + if ((*it).has_wakelock) { releaseWakeLock_l(); } + it = mQueue.erase(it); if (stopAfterFirstMatch) { return; } @@ -297,11 +300,10 @@ sp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l( if ((*it).event->eventID() == id) { sp<Event> event = (*it).event; event->setEventID(0); - - mQueue.erase(it); - if (mQueue.empty()) { + if ((*it).has_wakelock) { releaseWakeLock_l(); } + mQueue.erase(it); return event; } } @@ -313,51 +315,59 @@ sp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l( 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 (mWakeLockCount++ == 0) { + CHECK(mWakeLockToken == 0); + 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(); - int64_t token = IPCThreadState::self()->clearCallingIdentity(); - status_t status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK, - binder, - String16("TimedEventQueue"), - String16("media")); - IPCThreadState::self()->restoreCallingIdentity(token); - if (status == NO_ERROR) { - mWakeLockToken = binder; + if (mPowerManager != 0) { + sp<IBinder> binder = new BBinder(); + int64_t token = IPCThreadState::self()->clearCallingIdentity(); + status_t status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK, + binder, + String16("TimedEventQueue"), + String16("media")); + IPCThreadState::self()->restoreCallingIdentity(token); + if (status == NO_ERROR) { + mWakeLockToken = binder; + } } } } -void TimedEventQueue::releaseWakeLock_l() +void TimedEventQueue::releaseWakeLock_l(bool force) { - if (mWakeLockToken == 0) { - return; + if (force) { + if (mWakeLockCount == 0) { + return; + } + // Force wakelock release below by setting reference count to 1. + mWakeLockCount = 1; } - if (mPowerManager != 0) { - int64_t token = IPCThreadState::self()->clearCallingIdentity(); - mPowerManager->releaseWakeLock(mWakeLockToken, 0); - IPCThreadState::self()->restoreCallingIdentity(token); + CHECK(mWakeLockCount != 0); + if (--mWakeLockCount == 0) { + CHECK(mWakeLockToken != 0); + if (mPowerManager != 0) { + int64_t token = IPCThreadState::self()->clearCallingIdentity(); + mPowerManager->releaseWakeLock(mWakeLockToken, 0); + IPCThreadState::self()->restoreCallingIdentity(token); + } + mWakeLockToken.clear(); } - mWakeLockToken.clear(); } void TimedEventQueue::clearPowerManager() { Mutex::Autolock _l(mLock); - releaseWakeLock_l(); + releaseWakeLock_l(true /*force*/); mPowerManager.clear(); } diff --git a/media/libstagefright/include/TimedEventQueue.h b/media/libstagefright/include/TimedEventQueue.h index 4e49c83..38a08b1 100644 --- a/media/libstagefright/include/TimedEventQueue.h +++ b/media/libstagefright/include/TimedEventQueue.h @@ -118,6 +118,7 @@ private: struct QueueItem { sp<Event> event; int64_t realtime_us; + bool has_wakelock; }; struct StopEvent : public TimedEventQueue::Event { @@ -139,6 +140,7 @@ private: sp<IPowerManager> mPowerManager; sp<IBinder> mWakeLockToken; const sp<PMDeathRecipient> mDeathRecipient; + uint32_t mWakeLockCount; static void *ThreadWrapper(void *me); void threadEntry(); @@ -146,7 +148,7 @@ private: sp<Event> removeEventFromQueue_l(event_id id); void acquireWakeLock_l(); - void releaseWakeLock_l(); + void releaseWakeLock_l(bool force = false); TimedEventQueue(const TimedEventQueue &); TimedEventQueue &operator=(const TimedEventQueue &); |