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 28 namespace android { 29 30 struct 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 117 private: 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