• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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