1192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta/*
2192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * Copyright (C) 2009 The Android Open Source Project
3192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta *
4192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * Licensed under the Apache License, Version 2.0 (the "License");
5192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * you may not use this file except in compliance with the License.
6192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * You may obtain a copy of the License at
7192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta *
8192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta *      http://www.apache.org/licenses/LICENSE-2.0
9192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta *
10192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * Unless required by applicable law or agreed to in writing, software
11192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * distributed under the License is distributed on an "AS IS" BASIS,
12192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * See the License for the specific language governing permissions and
14192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta * limitations under the License.
15192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta */
16192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
17192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta#ifndef TIMED_EVENT_QUEUE_H_
18192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
19192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta#define TIMED_EVENT_QUEUE_H_
20192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
21192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta#include <pthread.h>
22192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
23192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta#include <utils/List.h>
24192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta#include <utils/RefBase.h>
25192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta#include <utils/threads.h>
26192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta#include <powermanager/IPowerManager.h>
27192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
28192d793d2586b620027edd5b45ff4c72a86cc7beHemant Guptanamespace android {
29192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
30192d793d2586b620027edd5b45ff4c72a86cc7beHemant Guptastruct TimedEventQueue {
31192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
32192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    typedef int32_t event_id;
33192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
34192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    struct Event : public RefBase {
35192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta        Event()
36192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta            : mEventID(0) {
37192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta        }
38192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
39192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta        virtual ~Event() {}
40192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
41192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta        event_id eventID() {
42192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta            return mEventID;
43192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta        }
44192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
45192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    protected:
46192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta        virtual void fire(TimedEventQueue *queue, int64_t now_us) = 0;
47192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
48192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    private:
49192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta        friend struct TimedEventQueue;
50192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
51192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta        event_id mEventID;
52192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
53192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta        void setEventID(event_id id) {
54192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta            mEventID = id;
55192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta        }
56192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
57192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta        Event(const Event &);
58192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta        Event &operator=(const Event &);
59192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    };
60192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
61192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    class PMDeathRecipient : public IBinder::DeathRecipient {
62192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    public:
63192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta                    PMDeathRecipient(TimedEventQueue *queue) : mQueue(queue) {}
64192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta        virtual     ~PMDeathRecipient() {}
65192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
66192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta        // IBinder::DeathRecipient
67192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta        virtual     void        binderDied(const wp<IBinder>& who);
68192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
69192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    private:
70192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta                    PMDeathRecipient(const PMDeathRecipient&);
71192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta                    PMDeathRecipient& operator = (const PMDeathRecipient&);
72192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
73192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta                    TimedEventQueue *mQueue;
74192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    };
75192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
76192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    TimedEventQueue();
77192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    ~TimedEventQueue();
78192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
79192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    // Start executing the event loop.
80192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    void start();
81192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
82192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    // Stop executing the event loop, if flush is false, any pending
83192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    // events are discarded, otherwise the queue will stop (and this call
84192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    // return) once all pending events have been handled.
85192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    void stop(bool flush = false);
86192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta
87192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    // Posts an event to the front of the queue (after all events that
88192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    // have previously been posted to the front but before timed events).
89192d793d2586b620027edd5b45ff4c72a86cc7beHemant Gupta    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