1 /* 2 * Copyright (C) 2021 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_hardware_automotive_vehicle_aidl_impl_vhal_include_RecurrentTimer_H_ 18 #define android_hardware_automotive_vehicle_aidl_impl_vhal_include_RecurrentTimer_H_ 19 20 #include <android-base/thread_annotations.h> 21 22 #include <utils/Looper.h> 23 #include <atomic> 24 #include <memory> 25 #include <mutex> 26 #include <queue> 27 #include <thread> 28 #include <unordered_map> 29 #include <vector> 30 31 namespace android { 32 namespace hardware { 33 namespace automotive { 34 namespace vehicle { 35 36 // Forward declaration 37 class RecurrentMessageHandler; 38 39 // A thread-safe recurrent timer. 40 class RecurrentTimer final { 41 public: 42 // The class for the function that would be called recurrently. 43 using Callback = std::function<void()>; 44 45 RecurrentTimer(); 46 47 ~RecurrentTimer(); 48 49 // Registers a recurrent callback for a given interval. 50 // Registering the same callback twice will override the interval provided before. 51 void registerTimerCallback(int64_t intervalInNanos, std::shared_ptr<Callback> callback); 52 53 // Unregisters a previously registered recurrent callback. 54 void unregisterTimerCallback(std::shared_ptr<Callback> callback); 55 56 private: 57 friend class RecurrentMessageHandler; 58 59 // For unit test 60 friend class RecurrentTimerTest; 61 62 struct CallbackInfo { 63 std::shared_ptr<Callback> callback; 64 int64_t intervalInNanos; 65 int64_t nextTimeInNanos; 66 }; 67 68 android::sp<Looper> mLooper; 69 android::sp<RecurrentMessageHandler> mHandler; 70 71 std::atomic<bool> mStopRequested = false; 72 std::atomic<int> mCallbackId = 0; 73 std::mutex mLock; 74 std::thread mThread; 75 std::unordered_map<std::shared_ptr<Callback>, int> mIdByCallback GUARDED_BY(mLock); 76 std::unordered_map<int, std::unique_ptr<CallbackInfo>> mCallbackInfoById GUARDED_BY(mLock); 77 78 void handleMessage(const android::Message& message) EXCLUDES(mLock); 79 int getCallbackIdLocked(std::shared_ptr<Callback> callback) REQUIRES(mLock); 80 }; 81 82 class RecurrentMessageHandler final : public android::MessageHandler { 83 public: RecurrentMessageHandler(RecurrentTimer * timer)84 RecurrentMessageHandler(RecurrentTimer* timer) { mTimer = timer; } 85 void handleMessage(const android::Message& message) override; 86 87 private: 88 RecurrentTimer* mTimer; 89 }; 90 91 } // namespace vehicle 92 } // namespace automotive 93 } // namespace hardware 94 } // namespace android 95 96 #endif // android_hardware_automotive_vehicle_aidl_impl_vhal_include_RecurrentTimer_H_ 97