/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef TIMED_EVENT_QUEUE_H_

#define TIMED_EVENT_QUEUE_H_

#include <pthread.h>

#include <utils/List.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
#include <powermanager/IPowerManager.h>

namespace android {

struct TimedEventQueue {

    typedef int32_t event_id;

    struct Event : public RefBase {
        Event()
            : mEventID(0) {
        }

        virtual ~Event() {}

        event_id eventID() {
            return mEventID;
        }

    protected:
        virtual void fire(TimedEventQueue *queue, int64_t now_us) = 0;

    private:
        friend struct TimedEventQueue;

        event_id mEventID;

        void setEventID(event_id id) {
            mEventID = id;
        }

        Event(const Event &);
        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();

    // Start executing the event loop.
    void start();

    // Stop executing the event loop, if flush is false, any pending
    // events are discarded, otherwise the queue will stop (and this call
    // return) once all pending events have been handled.
    void stop(bool flush = false);

    // Posts an event to the front of the queue (after all events that
    // have previously been posted to the front but before timed events).
    event_id postEvent(const sp<Event> &event);

    event_id postEventToBack(const sp<Event> &event);

    // It is an error to post an event with a negative delay.
    event_id postEventWithDelay(const sp<Event> &event, int64_t delay_us);

    // If the event is to be posted at a time that has already passed,
    // it will fire as soon as possible.
    event_id postTimedEvent(const sp<Event> &event, int64_t realtime_us);

    // Returns true iff event is currently in the queue and has been
    // successfully cancelled. In this case the event will have been
    // removed from the queue and won't fire.
    bool cancelEvent(event_id id);

    // Cancel any pending event that satisfies the predicate.
    // If stopAfterFirstMatch is true, only cancels the first event
    // satisfying the predicate (if any).
    void cancelEvents(
            bool (*predicate)(void *cookie, const sp<Event> &event),
            void *cookie,
            bool stopAfterFirstMatch = false);

    static int64_t getRealTimeUs();

    void clearPowerManager();

private:
    struct QueueItem {
        sp<Event> event;
        int64_t realtime_us;
        bool has_wakelock;
    };

    struct StopEvent : public TimedEventQueue::Event {
        virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
            queue->mStopped = true;
        }
    };

    pthread_t mThread;
    List<QueueItem> mQueue;
    Mutex mLock;
    Condition mQueueNotEmptyCondition;
    Condition mQueueHeadChangedCondition;
    event_id mNextEventID;

    bool mRunning;
    bool mStopped;

    sp<IPowerManager>       mPowerManager;
    sp<IBinder>             mWakeLockToken;
    const sp<PMDeathRecipient> mDeathRecipient;
    uint32_t                mWakeLockCount;

    static void *ThreadWrapper(void *me);
    void threadEntry();

    sp<Event> removeEventFromQueue_l(event_id id, bool *wakeLocked);

    void acquireWakeLock_l();
    void releaseWakeLock_l(bool force = false);

    TimedEventQueue(const TimedEventQueue &);
    TimedEventQueue &operator=(const TimedEventQueue &);
};

}  // namespace android

#endif  // TIMED_EVENT_QUEUE_H_
