Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da0926af authored by Eric Laurent's avatar Eric Laurent Committed by Android (Google) Code Review
Browse files

Merge "TimedEventQueue takes a wake lock" into klp-dev

parents 385e7509 8db18848
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ LOCAL_SHARED_LIBRARIES := \
        libutils \
        libvorbisidec \
        libz \
        libpowermanager

LOCAL_STATIC_LIBRARIES := \
        libstagefright_color_conversion \
+73 −3
Original line number Diff line number Diff line
@@ -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
+25 −0
Original line number Diff line number Diff line
@@ -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 &);
};