Loading media/libstagefright/Android.mk +1 −0 Original line number Original line Diff line number Diff line Loading @@ -89,6 +89,7 @@ LOCAL_SHARED_LIBRARIES := \ libutils \ libutils \ libvorbisidec \ libvorbisidec \ libz \ libz \ libpowermanager LOCAL_STATIC_LIBRARIES := \ LOCAL_STATIC_LIBRARIES := \ libstagefright_color_conversion \ libstagefright_color_conversion \ Loading media/libstagefright/TimedEventQueue.cpp +73 −3 Original line number Original line Diff line number Diff line Loading @@ -31,17 +31,24 @@ #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ALooper.h> #include <media/stagefright/foundation/ALooper.h> #include <binder/IServiceManager.h> #include <powermanager/PowerManager.h> namespace android { namespace android { TimedEventQueue::TimedEventQueue() TimedEventQueue::TimedEventQueue() : mNextEventID(1), : mNextEventID(1), mRunning(false), mRunning(false), mStopped(false) { mStopped(false), mDeathRecipient(new PMDeathRecipient(this)) { } } TimedEventQueue::~TimedEventQueue() { TimedEventQueue::~TimedEventQueue() { stop(); stop(); if (mPowerManager != 0) { sp<IBinder> binder = mPowerManager->asBinder(); binder->unlinkToDeath(mDeathRecipient); } } } void TimedEventQueue::start() { void TimedEventQueue::start() { Loading Loading @@ -76,6 +83,11 @@ void TimedEventQueue::stop(bool flush) { void *dummy; void *dummy; pthread_join(mThread, &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(); mQueue.clear(); mRunning = false; mRunning = false; Loading Loading @@ -117,6 +129,9 @@ TimedEventQueue::event_id TimedEventQueue::postTimedEvent( mQueueHeadChangedCondition.signal(); mQueueHeadChangedCondition.signal(); } } if (mQueue.empty()) { acquireWakeLock_l(); } mQueue.insert(it, item); mQueue.insert(it, item); mQueueNotEmptyCondition.signal(); mQueueNotEmptyCondition.signal(); Loading Loading @@ -172,7 +187,9 @@ void TimedEventQueue::cancelEvents( (*it).event->setEventID(0); (*it).event->setEventID(0); it = mQueue.erase(it); it = mQueue.erase(it); if (mQueue.empty()) { releaseWakeLock_l(); } if (stopAfterFirstMatch) { if (stopAfterFirstMatch) { return; return; } } Loading Loading @@ -280,7 +297,9 @@ sp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l( event->setEventID(0); event->setEventID(0); mQueue.erase(it); mQueue.erase(it); if (mQueue.empty()) { releaseWakeLock_l(); } return event; return event; } } } } Loading @@ -290,5 +309,56 @@ sp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l( return NULL; 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 } // namespace android media/libstagefright/include/TimedEventQueue.h +25 −0 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <utils/List.h> #include <utils/List.h> #include <utils/RefBase.h> #include <utils/RefBase.h> #include <utils/threads.h> #include <utils/threads.h> #include <powermanager/IPowerManager.h> namespace android { namespace android { Loading Loading @@ -57,6 +58,21 @@ struct TimedEventQueue { Event &operator=(const Event &); 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(); ~TimedEventQueue(); ~TimedEventQueue(); Loading Loading @@ -96,6 +112,8 @@ struct TimedEventQueue { static int64_t getRealTimeUs(); static int64_t getRealTimeUs(); void clearPowerManager(); private: private: struct QueueItem { struct QueueItem { sp<Event> event; sp<Event> event; Loading @@ -118,11 +136,18 @@ private: bool mRunning; bool mRunning; bool mStopped; bool mStopped; sp<IPowerManager> mPowerManager; sp<IBinder> mWakeLockToken; const sp<PMDeathRecipient> mDeathRecipient; static void *ThreadWrapper(void *me); static void *ThreadWrapper(void *me); void threadEntry(); void threadEntry(); sp<Event> removeEventFromQueue_l(event_id id); sp<Event> removeEventFromQueue_l(event_id id); void acquireWakeLock_l(); void releaseWakeLock_l(); TimedEventQueue(const TimedEventQueue &); TimedEventQueue(const TimedEventQueue &); TimedEventQueue &operator=(const TimedEventQueue &); TimedEventQueue &operator=(const TimedEventQueue &); }; }; Loading Loading
media/libstagefright/Android.mk +1 −0 Original line number Original line Diff line number Diff line Loading @@ -89,6 +89,7 @@ LOCAL_SHARED_LIBRARIES := \ libutils \ libutils \ libvorbisidec \ libvorbisidec \ libz \ libz \ libpowermanager LOCAL_STATIC_LIBRARIES := \ LOCAL_STATIC_LIBRARIES := \ libstagefright_color_conversion \ libstagefright_color_conversion \ Loading
media/libstagefright/TimedEventQueue.cpp +73 −3 Original line number Original line Diff line number Diff line Loading @@ -31,17 +31,24 @@ #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ALooper.h> #include <media/stagefright/foundation/ALooper.h> #include <binder/IServiceManager.h> #include <powermanager/PowerManager.h> namespace android { namespace android { TimedEventQueue::TimedEventQueue() TimedEventQueue::TimedEventQueue() : mNextEventID(1), : mNextEventID(1), mRunning(false), mRunning(false), mStopped(false) { mStopped(false), mDeathRecipient(new PMDeathRecipient(this)) { } } TimedEventQueue::~TimedEventQueue() { TimedEventQueue::~TimedEventQueue() { stop(); stop(); if (mPowerManager != 0) { sp<IBinder> binder = mPowerManager->asBinder(); binder->unlinkToDeath(mDeathRecipient); } } } void TimedEventQueue::start() { void TimedEventQueue::start() { Loading Loading @@ -76,6 +83,11 @@ void TimedEventQueue::stop(bool flush) { void *dummy; void *dummy; pthread_join(mThread, &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(); mQueue.clear(); mRunning = false; mRunning = false; Loading Loading @@ -117,6 +129,9 @@ TimedEventQueue::event_id TimedEventQueue::postTimedEvent( mQueueHeadChangedCondition.signal(); mQueueHeadChangedCondition.signal(); } } if (mQueue.empty()) { acquireWakeLock_l(); } mQueue.insert(it, item); mQueue.insert(it, item); mQueueNotEmptyCondition.signal(); mQueueNotEmptyCondition.signal(); Loading Loading @@ -172,7 +187,9 @@ void TimedEventQueue::cancelEvents( (*it).event->setEventID(0); (*it).event->setEventID(0); it = mQueue.erase(it); it = mQueue.erase(it); if (mQueue.empty()) { releaseWakeLock_l(); } if (stopAfterFirstMatch) { if (stopAfterFirstMatch) { return; return; } } Loading Loading @@ -280,7 +297,9 @@ sp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l( event->setEventID(0); event->setEventID(0); mQueue.erase(it); mQueue.erase(it); if (mQueue.empty()) { releaseWakeLock_l(); } return event; return event; } } } } Loading @@ -290,5 +309,56 @@ sp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l( return NULL; 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 } // namespace android
media/libstagefright/include/TimedEventQueue.h +25 −0 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <utils/List.h> #include <utils/List.h> #include <utils/RefBase.h> #include <utils/RefBase.h> #include <utils/threads.h> #include <utils/threads.h> #include <powermanager/IPowerManager.h> namespace android { namespace android { Loading Loading @@ -57,6 +58,21 @@ struct TimedEventQueue { Event &operator=(const Event &); 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(); ~TimedEventQueue(); ~TimedEventQueue(); Loading Loading @@ -96,6 +112,8 @@ struct TimedEventQueue { static int64_t getRealTimeUs(); static int64_t getRealTimeUs(); void clearPowerManager(); private: private: struct QueueItem { struct QueueItem { sp<Event> event; sp<Event> event; Loading @@ -118,11 +136,18 @@ private: bool mRunning; bool mRunning; bool mStopped; bool mStopped; sp<IPowerManager> mPowerManager; sp<IBinder> mWakeLockToken; const sp<PMDeathRecipient> mDeathRecipient; static void *ThreadWrapper(void *me); static void *ThreadWrapper(void *me); void threadEntry(); void threadEntry(); sp<Event> removeEventFromQueue_l(event_id id); sp<Event> removeEventFromQueue_l(event_id id); void acquireWakeLock_l(); void releaseWakeLock_l(); TimedEventQueue(const TimedEventQueue &); TimedEventQueue(const TimedEventQueue &); TimedEventQueue &operator=(const TimedEventQueue &); TimedEventQueue &operator=(const TimedEventQueue &); }; }; Loading