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_OS_VIBRATOR_MANAGER_HAL_WRAPPER_H
18 #define ANDROID_OS_VIBRATOR_MANAGER_HAL_WRAPPER_H
19 
20 #include <aidl/android/hardware/vibrator/IVibratorManager.h>
21 #include <vibratorservice/VibratorHalController.h>
22 #include <unordered_map>
23 
24 namespace android {
25 
26 namespace vibrator {
27 
28 // VibratorManager HAL capabilities.
29 enum class ManagerCapabilities : int32_t {
30     NONE = 0,
31     SYNC = aidl::android::hardware::vibrator::IVibratorManager::CAP_SYNC,
32     PREPARE_ON = aidl::android::hardware::vibrator::IVibratorManager::CAP_PREPARE_ON,
33     PREPARE_PERFORM = aidl::android::hardware::vibrator::IVibratorManager::CAP_PREPARE_PERFORM,
34     PREPARE_COMPOSE = aidl::android::hardware::vibrator::IVibratorManager::CAP_PREPARE_COMPOSE,
35     MIXED_TRIGGER_ON = aidl::android::hardware::vibrator::IVibratorManager::IVibratorManager::
36             CAP_MIXED_TRIGGER_ON,
37     MIXED_TRIGGER_PERFORM =
38             aidl::android::hardware::vibrator::IVibratorManager::CAP_MIXED_TRIGGER_PERFORM,
39     MIXED_TRIGGER_COMPOSE =
40             aidl::android::hardware::vibrator::IVibratorManager::CAP_MIXED_TRIGGER_COMPOSE,
41     TRIGGER_CALLBACK = aidl::android::hardware::vibrator::IVibratorManager::CAP_TRIGGER_CALLBACK,
42     START_SESSIONS = aidl::android::hardware::vibrator::IVibratorManager::CAP_START_SESSIONS
43 };
44 
45 inline ManagerCapabilities operator|(ManagerCapabilities lhs, ManagerCapabilities rhs) {
46     using underlying = typename std::underlying_type<ManagerCapabilities>::type;
47     return static_cast<ManagerCapabilities>(static_cast<underlying>(lhs) |
48                                             static_cast<underlying>(rhs));
49 }
50 
51 inline ManagerCapabilities& operator|=(ManagerCapabilities& lhs, ManagerCapabilities rhs) {
52     return lhs = lhs | rhs;
53 }
54 
55 inline ManagerCapabilities operator&(ManagerCapabilities lhs, ManagerCapabilities rhs) {
56     using underlying = typename std::underlying_type<ManagerCapabilities>::type;
57     return static_cast<ManagerCapabilities>(static_cast<underlying>(lhs) &
58                                             static_cast<underlying>(rhs));
59 }
60 
61 inline ManagerCapabilities& operator&=(ManagerCapabilities& lhs, ManagerCapabilities rhs) {
62     return lhs = lhs & rhs;
63 }
64 
65 // Wrapper for VibratorManager HAL handlers.
66 class ManagerHalWrapper {
67 public:
68     using IVibrationSession = aidl::android::hardware::vibrator::IVibrationSession;
69     using VibrationSessionConfig = aidl::android::hardware::vibrator::VibrationSessionConfig;
70 
71     ManagerHalWrapper() = default;
72     virtual ~ManagerHalWrapper() = default;
73 
74     virtual HalResult<void> ping() = 0;
75 
76     /* reloads wrapped HAL service instance without waiting. This can be used to reconnect when the
77      * service restarts, to rapidly retry after a failure.
78      */
79     virtual void tryReconnect() = 0;
80 
81     virtual HalResult<ManagerCapabilities> getCapabilities() = 0;
82     virtual HalResult<std::vector<int32_t>> getVibratorIds() = 0;
83     virtual HalResult<std::shared_ptr<HalController>> getVibrator(int32_t id) = 0;
84 
85     virtual HalResult<void> prepareSynced(const std::vector<int32_t>& ids);
86     virtual HalResult<void> triggerSynced(const std::function<void()>& completionCallback);
87     virtual HalResult<void> cancelSynced();
88     virtual HalResult<std::shared_ptr<IVibrationSession>> startSession(
89             const std::vector<int32_t>& ids, const VibrationSessionConfig& config,
90             const std::function<void()>& completionCallback);
91     virtual HalResult<void> clearSessions();
92 };
93 
94 // Wrapper for the VibratorManager over single Vibrator HAL.
95 class LegacyManagerHalWrapper : public ManagerHalWrapper {
96 public:
LegacyManagerHalWrapper()97     LegacyManagerHalWrapper() : LegacyManagerHalWrapper(std::make_shared<HalController>()) {}
LegacyManagerHalWrapper(std::shared_ptr<HalController> controller)98     explicit LegacyManagerHalWrapper(std::shared_ptr<HalController> controller)
99           : mController(std::move(controller)) {}
100     virtual ~LegacyManagerHalWrapper() = default;
101 
102     HalResult<void> ping() override final;
103     void tryReconnect() override final;
104 
105     HalResult<ManagerCapabilities> getCapabilities() override final;
106     HalResult<std::vector<int32_t>> getVibratorIds() override final;
107     HalResult<std::shared_ptr<HalController>> getVibrator(int32_t id) override final;
108 
109 private:
110     const std::shared_ptr<HalController> mController;
111 };
112 
113 // Wrapper for the AIDL VibratorManager HAL.
114 class AidlManagerHalWrapper : public ManagerHalWrapper {
115 public:
116     using VibratorManager = aidl::android::hardware::vibrator::IVibratorManager;
117 
AidlManagerHalWrapper(std::shared_ptr<CallbackScheduler> callbackScheduler,std::shared_ptr<VibratorManager> handle)118     explicit AidlManagerHalWrapper(std::shared_ptr<CallbackScheduler> callbackScheduler,
119                                    std::shared_ptr<VibratorManager> handle)
120           : mHandle(std::move(handle)), mCallbackScheduler(callbackScheduler) {}
121     virtual ~AidlManagerHalWrapper() = default;
122 
123     HalResult<void> ping() override final;
124     void tryReconnect() override final;
125 
126     HalResult<ManagerCapabilities> getCapabilities() override final;
127     HalResult<std::vector<int32_t>> getVibratorIds() override final;
128     HalResult<std::shared_ptr<HalController>> getVibrator(int32_t id) override final;
129 
130     HalResult<void> prepareSynced(const std::vector<int32_t>& ids) override final;
131     HalResult<void> triggerSynced(const std::function<void()>& completionCallback) override final;
132     HalResult<void> cancelSynced() override final;
133     HalResult<std::shared_ptr<IVibrationSession>> startSession(
134             const std::vector<int32_t>& ids, const VibrationSessionConfig& config,
135             const std::function<void()>& completionCallback) override final;
136     HalResult<void> clearSessions() override final;
137 
138 private:
139     std::mutex mHandleMutex;
140     std::mutex mCapabilitiesMutex;
141     std::mutex mVibratorsMutex;
142     std::shared_ptr<VibratorManager> mHandle GUARDED_BY(mHandleMutex);
143     std::optional<ManagerCapabilities> mCapabilities GUARDED_BY(mCapabilitiesMutex);
144     std::optional<std::vector<int32_t>> mVibratorIds GUARDED_BY(mVibratorsMutex);
145     std::unordered_map<int32_t, std::shared_ptr<HalController>> mVibrators
146             GUARDED_BY(mVibratorsMutex);
147     std::shared_ptr<CallbackScheduler> mCallbackScheduler;
148 
149     std::shared_ptr<VibratorManager> getHal();
150     std::shared_ptr<HalWrapper> connectToVibrator(int32_t vibratorId,
151                                                   std::shared_ptr<CallbackScheduler> scheduler);
152 };
153 
154 }; // namespace vibrator
155 
156 }; // namespace android
157 
158 #endif // ANDROID_OS_VIBRATOR_MANAGER_HAL_WRAPPER_H
159