1 /* 2 * Copyright (C) 2020 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 ANDROID_VIBRATOR_CALLBACK_SCHEDULER_H 18 #define ANDROID_VIBRATOR_CALLBACK_SCHEDULER_H 19 20 #include <android-base/thread_annotations.h> 21 #include <chrono> 22 #include <condition_variable> 23 #include <queue> 24 #include <thread> 25 26 namespace android { 27 28 namespace vibrator { 29 30 // Wrapper for a callback to be executed after a delay. 31 class DelayedCallback { 32 public: 33 using Timestamp = std::chrono::time_point<std::chrono::steady_clock>; 34 DelayedCallback(std::function<void ()> callback,std::chrono::milliseconds delay)35 DelayedCallback(std::function<void()> callback, std::chrono::milliseconds delay) 36 : mCallback(callback), mExpiration(std::chrono::steady_clock::now() + delay) {} 37 ~DelayedCallback() = default; 38 39 void run() const; 40 bool isExpired() const; 41 Timestamp getExpiration() const; 42 43 // Compare by expiration time, where A < B when A expires first. 44 bool operator<(const DelayedCallback& other) const; 45 bool operator>(const DelayedCallback& other) const; 46 47 private: 48 std::function<void()> mCallback; 49 Timestamp mExpiration; 50 }; 51 52 // Schedules callbacks to be executed after a delay. 53 class CallbackScheduler { 54 public: CallbackScheduler()55 CallbackScheduler() : mCallbackThread(nullptr), mFinished(false) {} 56 virtual ~CallbackScheduler(); 57 58 virtual void schedule(std::function<void()> callback, std::chrono::milliseconds delay); 59 60 private: 61 std::condition_variable_any mCondition; 62 std::mutex mMutex; 63 64 // Lazily instantiated only at the first time this scheduler is used. 65 std::unique_ptr<std::thread> mCallbackThread; 66 67 // Used to quit the callback thread when this instance is being destroyed. 68 bool mFinished GUARDED_BY(mMutex); 69 70 // Priority queue with reverse comparator, so tasks that expire first will be on top. 71 std::priority_queue<DelayedCallback, std::vector<DelayedCallback>, 72 std::greater<DelayedCallback>> 73 mQueue GUARDED_BY(mMutex); 74 75 void loop(); 76 }; 77 78 }; // namespace vibrator 79 80 }; // namespace android 81 82 #endif // ANDROID_VIBRATOR_CALLBACK_SCHEDULER_H 83