TimedEventQueue.h revision d411b4ca2945cd8974a3a78199fce94646950128
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef TIMED_EVENT_QUEUE_H_
18
19#define TIMED_EVENT_QUEUE_H_
20
21#include <pthread.h>
22
23#include <utils/List.h>
24#include <utils/RefBase.h>
25#include <utils/threads.h>
26#include <powermanager/IPowerManager.h>
27
28namespace android {
29
30struct TimedEventQueue {
31
32    typedef int32_t event_id;
33
34    struct Event : public RefBase {
35        Event()
36            : mEventID(0) {
37        }
38
39        virtual ~Event() {}
40
41        event_id eventID() {
42            return mEventID;
43        }
44
45    protected:
46        virtual void fire(TimedEventQueue *queue, int64_t now_us) = 0;
47
48    private:
49        friend class TimedEventQueue;
50
51        event_id mEventID;
52
53        void setEventID(event_id id) {
54            mEventID = id;
55        }
56
57        Event(const Event &);
58        Event &operator=(const Event &);
59    };
60
61    class PMDeathRecipient : public IBinder::DeathRecipient {
62    public:
63                    PMDeathRecipient(TimedEventQueue *queue) : mQueue(queue) {}
64        virtual     ~PMDeathRecipient() {}
65
66        // IBinder::DeathRecipient
67        virtual     void        binderDied(const wp<IBinder>& who);
68
69    private:
70                    PMDeathRecipient(const PMDeathRecipient&);
71                    PMDeathRecipient& operator = (const PMDeathRecipient&);
72
73                    TimedEventQueue *mQueue;
74    };
75
76    TimedEventQueue();
77    ~TimedEventQueue();
78
79    // Start executing the event loop.
80    void start();
81
82    // Stop executing the event loop, if flush is false, any pending
83    // events are discarded, otherwise the queue will stop (and this call
84    // return) once all pending events have been handled.
85    void stop(bool flush = false);
86
87    // Posts an event to the front of the queue (after all events that
88    // have previously been posted to the front but before timed events).
89    event_id postEvent(const sp<Event> &event);
90
91    event_id postEventToBack(const sp<Event> &event);
92
93    // It is an error to post an event with a negative delay.
94    event_id postEventWithDelay(const sp<Event> &event, int64_t delay_us);
95
96    // If the event is to be posted at a time that has already passed,
97    // it will fire as soon as possible.
98    event_id postTimedEvent(const sp<Event> &event, int64_t realtime_us);
99
100    // Returns true iff event is currently in the queue and has been
101    // successfully cancelled. In this case the event will have been
102    // removed from the queue and won't fire.
103    bool cancelEvent(event_id id);
104
105    // Cancel any pending event that satisfies the predicate.
106    // If stopAfterFirstMatch is true, only cancels the first event
107    // satisfying the predicate (if any).
108    void cancelEvents(
109            bool (*predicate)(void *cookie, const sp<Event> &event),
110            void *cookie,
111            bool stopAfterFirstMatch = false);
112
113    static int64_t getRealTimeUs();
114
115    void clearPowerManager();
116
117private:
118    struct QueueItem {
119        sp<Event> event;
120        int64_t realtime_us;
121        bool has_wakelock;
122    };
123
124    struct StopEvent : public TimedEventQueue::Event {
125        virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
126            queue->mStopped = true;
127        }
128    };
129
130    pthread_t mThread;
131    List<QueueItem> mQueue;
132    Mutex mLock;
133    Condition mQueueNotEmptyCondition;
134    Condition mQueueHeadChangedCondition;
135    event_id mNextEventID;
136
137    bool mRunning;
138    bool mStopped;
139
140    sp<IPowerManager>       mPowerManager;
141    sp<IBinder>             mWakeLockToken;
142    const sp<PMDeathRecipient> mDeathRecipient;
143    uint32_t                mWakeLockCount;
144
145    static void *ThreadWrapper(void *me);
146    void threadEntry();
147
148    sp<Event> removeEventFromQueue_l(event_id id, bool *wakeLocked);
149
150    void acquireWakeLock_l();
151    void releaseWakeLock_l(bool force = false);
152
153    TimedEventQueue(const TimedEventQueue &);
154    TimedEventQueue &operator=(const TimedEventQueue &);
155};
156
157}  // namespace android
158
159#endif  // TIMED_EVENT_QUEUE_H_
160