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