1 /*
2  * Copyright 2018 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 #pragma once
18 
19 #include <chrono>
20 #include <condition_variable>
21 #include <thread>
22 
23 #include <android-base/thread_annotations.h>
24 
25 namespace android {
26 namespace scheduler {
27 
28 /*
29  * Class that sets off a timer for a given interval, and fires a callback when the
30  * interval expires.
31  */
32 class IdleTimer {
33 public:
34     using Interval = std::chrono::milliseconds;
35     using ResetCallback = std::function<void()>;
36     using TimeoutCallback = std::function<void()>;
37 
38     IdleTimer(const Interval& interval, const ResetCallback& resetCallback,
39               const TimeoutCallback& timeoutCallback);
40     ~IdleTimer();
41 
42     // Initializes and turns on the idle timer.
43     void start();
44     // Stops the idle timer and any held resources.
45     void stop();
46     // Resets the wakeup time and fires the reset callback.
47     void reset();
48 
49 private:
50     // Enum to track in what state is the timer.
51     enum class TimerState {
52         // The internal timer thread has been destroyed, and no state is
53         // tracked.
54         // Possible state transitions: RESET
55         STOPPED = 0,
56         // An external thread has just reset this timer.
57         // If there is a reset callback, then that callback is fired.
58         // Possible state transitions: STOPPED, WAITING
59         RESET = 1,
60         // This timer is waiting for the timeout interval to expire.
61         // Possible state transaitions: STOPPED, RESET, IDLE
62         WAITING = 2,
63         // The timeout interval has expired, so we are sleeping now.
64         // Possible state transaitions: STOPPED, RESET
65         IDLE = 3
66     };
67 
68     // Function that loops until the condition for stopping is met.
69     void loop();
70 
71     // Thread waiting for timer to expire.
72     std::thread mThread;
73 
74     // Condition used to notify mThread.
75     std::condition_variable_any mCondition;
76 
77     // Lock used for synchronizing the waiting thread with the application thread.
78     std::mutex mMutex;
79 
80     // Current timer state
81     TimerState mState GUARDED_BY(mMutex) = TimerState::RESET;
82 
83     // Interval after which timer expires.
84     const Interval mInterval;
85 
86     // Callback that happens when timer resets.
87     const ResetCallback mResetCallback;
88 
89     // Callback that happens when timer expires.
90     const TimeoutCallback mTimeoutCallback;
91 };
92 
93 } // namespace scheduler
94 } // namespace android
95