xref: /aosp_15_r20/frameworks/native/services/vibratorservice/VibratorManagerHalWrapper.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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 #define LOG_TAG "VibratorManagerHalWrapper"
18 
19 #include <utils/Log.h>
20 
21 #include <vibratorservice/VibratorManagerHalWrapper.h>
22 
23 namespace Aidl = aidl::android::hardware::vibrator;
24 
25 namespace android {
26 
27 namespace vibrator {
28 
29 constexpr int32_t SINGLE_VIBRATOR_ID = 0;
30 const constexpr char* MISSING_VIBRATOR_MESSAGE_PREFIX = "No vibrator with id=";
31 
prepareSynced(const std::vector<int32_t> &)32 HalResult<void> ManagerHalWrapper::prepareSynced(const std::vector<int32_t>&) {
33     return HalResult<void>::unsupported();
34 }
35 
triggerSynced(const std::function<void ()> &)36 HalResult<void> ManagerHalWrapper::triggerSynced(const std::function<void()>&) {
37     return HalResult<void>::unsupported();
38 }
39 
cancelSynced()40 HalResult<void> ManagerHalWrapper::cancelSynced() {
41     return HalResult<void>::unsupported();
42 }
43 
startSession(const std::vector<int32_t> &,const Aidl::VibrationSessionConfig &,const std::function<void ()> &)44 HalResult<std::shared_ptr<Aidl::IVibrationSession>> ManagerHalWrapper::startSession(
45         const std::vector<int32_t>&, const Aidl::VibrationSessionConfig&,
46         const std::function<void()>&) {
47     return HalResult<std::shared_ptr<Aidl::IVibrationSession>>::unsupported();
48 }
49 
clearSessions()50 HalResult<void> ManagerHalWrapper::clearSessions() {
51     return HalResult<void>::unsupported();
52 }
53 
54 // -------------------------------------------------------------------------------------------------
55 
ping()56 HalResult<void> LegacyManagerHalWrapper::ping() {
57     auto pingFn = [](HalWrapper* hal) { return hal->ping(); };
58     return mController->doWithRetry<void>(pingFn, "ping");
59 }
60 
tryReconnect()61 void LegacyManagerHalWrapper::tryReconnect() {
62     mController->tryReconnect();
63 }
64 
getCapabilities()65 HalResult<ManagerCapabilities> LegacyManagerHalWrapper::getCapabilities() {
66     return HalResult<ManagerCapabilities>::ok(ManagerCapabilities::NONE);
67 }
68 
getVibratorIds()69 HalResult<std::vector<int32_t>> LegacyManagerHalWrapper::getVibratorIds() {
70     if (mController->init()) {
71         return HalResult<std::vector<int32_t>>::ok(std::vector<int32_t>(1, SINGLE_VIBRATOR_ID));
72     }
73     // Controller.init did not connect to any vibrator HAL service, so the device has no vibrator.
74     return HalResult<std::vector<int32_t>>::ok(std::vector<int32_t>());
75 }
76 
getVibrator(int32_t id)77 HalResult<std::shared_ptr<HalController>> LegacyManagerHalWrapper::getVibrator(int32_t id) {
78     if (id == SINGLE_VIBRATOR_ID && mController->init()) {
79         return HalResult<std::shared_ptr<HalController>>::ok(mController);
80     }
81     // Controller.init did not connect to any vibrator HAL service, so the device has no vibrator.
82     return HalResult<std::shared_ptr<HalController>>::failed(
83             (MISSING_VIBRATOR_MESSAGE_PREFIX + std::to_string(id)).c_str());
84 }
85 
86 // -------------------------------------------------------------------------------------------------
87 
connectToVibrator(int32_t vibratorId,std::shared_ptr<CallbackScheduler> callbackScheduler)88 std::shared_ptr<HalWrapper> AidlManagerHalWrapper::connectToVibrator(
89         int32_t vibratorId, std::shared_ptr<CallbackScheduler> callbackScheduler) {
90     std::function<HalResult<std::shared_ptr<Aidl::IVibrator>>()> reconnectFn = [=, this]() {
91         std::shared_ptr<Aidl::IVibrator> vibrator;
92         auto status = this->getHal()->getVibrator(vibratorId, &vibrator);
93         return HalResultFactory::fromStatus<std::shared_ptr<Aidl::IVibrator>>(std::move(status),
94                                                                               vibrator);
95     };
96     auto result = reconnectFn();
97     if (!result.isOk()) {
98         return nullptr;
99     }
100     auto vibrator = result.value();
101     if (!vibrator) {
102         return nullptr;
103     }
104     return std::make_unique<AidlHalWrapper>(std::move(callbackScheduler), std::move(vibrator),
105                                             reconnectFn);
106 }
107 
ping()108 HalResult<void> AidlManagerHalWrapper::ping() {
109     return HalResultFactory::fromStatus(AIBinder_ping(getHal()->asBinder().get()));
110 }
111 
tryReconnect()112 void AidlManagerHalWrapper::tryReconnect() {
113     auto aidlServiceName = std::string(Aidl::IVibratorManager::descriptor) + "/default";
114     std::shared_ptr<Aidl::IVibratorManager> newHandle = Aidl::IVibratorManager::fromBinder(
115             ndk::SpAIBinder(AServiceManager_checkService(aidlServiceName.c_str())));
116     if (newHandle) {
117         std::lock_guard<std::mutex> lock(mHandleMutex);
118         mHandle = std::move(newHandle);
119     }
120 }
121 
getCapabilities()122 HalResult<ManagerCapabilities> AidlManagerHalWrapper::getCapabilities() {
123     std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
124     if (mCapabilities.has_value()) {
125         // Return copy of cached value.
126         return HalResult<ManagerCapabilities>::ok(*mCapabilities);
127     }
128     int32_t cap = 0;
129     auto status = getHal()->getCapabilities(&cap);
130     auto capabilities = static_cast<ManagerCapabilities>(cap);
131     auto ret = HalResultFactory::fromStatus<ManagerCapabilities>(std::move(status), capabilities);
132     if (ret.isOk()) {
133         // Cache copy of returned value.
134         mCapabilities.emplace(ret.value());
135     }
136     return ret;
137 }
138 
getVibratorIds()139 HalResult<std::vector<int32_t>> AidlManagerHalWrapper::getVibratorIds() {
140     std::lock_guard<std::mutex> lock(mVibratorsMutex);
141     if (mVibratorIds.has_value()) {
142         // Return copy of cached values.
143         return HalResult<std::vector<int32_t>>::ok(*mVibratorIds);
144     }
145     std::vector<int32_t> ids;
146     auto status = getHal()->getVibratorIds(&ids);
147     auto ret = HalResultFactory::fromStatus<std::vector<int32_t>>(std::move(status), ids);
148     if (ret.isOk()) {
149         // Cache copy of returned value and the individual controllers.
150         mVibratorIds.emplace(ret.value());
151         for (auto& id : ids) {
152             HalController::Connector connector = [&, id](auto scheduler) {
153                 return this->connectToVibrator(id, scheduler);
154             };
155             auto controller = std::make_unique<HalController>(mCallbackScheduler, connector);
156             mVibrators[id] = std::move(controller);
157         }
158     }
159     return ret;
160 }
161 
getVibrator(int32_t id)162 HalResult<std::shared_ptr<HalController>> AidlManagerHalWrapper::getVibrator(int32_t id) {
163     // Make sure we cache vibrator ids and initialize the individual controllers.
164     getVibratorIds();
165     std::lock_guard<std::mutex> lock(mVibratorsMutex);
166     auto it = mVibrators.find(id);
167     if (it != mVibrators.end()) {
168         return HalResult<std::shared_ptr<HalController>>::ok(it->second);
169     }
170     return HalResult<std::shared_ptr<HalController>>::failed(
171             (MISSING_VIBRATOR_MESSAGE_PREFIX + std::to_string(id)).c_str());
172 }
173 
prepareSynced(const std::vector<int32_t> & ids)174 HalResult<void> AidlManagerHalWrapper::prepareSynced(const std::vector<int32_t>& ids) {
175     auto ret = HalResultFactory::fromStatus(getHal()->prepareSynced(ids));
176     if (ret.isOk()) {
177         // Force reload of all vibrator controllers that were prepared for a sync operation here.
178         // This will trigger calls to getVibrator(id) on each controller, so they can use the
179         // latest service provided by this manager.
180         std::lock_guard<std::mutex> lock(mVibratorsMutex);
181         for (auto& id : ids) {
182             auto it = mVibrators.find(id);
183             if (it != mVibrators.end()) {
184                 it->second->tryReconnect();
185             }
186         }
187     }
188     return ret;
189 }
190 
triggerSynced(const std::function<void ()> & completionCallback)191 HalResult<void> AidlManagerHalWrapper::triggerSynced(
192         const std::function<void()>& completionCallback) {
193     HalResult<ManagerCapabilities> capabilities = getCapabilities();
194     bool supportsCallback = capabilities.isOk() &&
195             static_cast<int32_t>(capabilities.value() & ManagerCapabilities::TRIGGER_CALLBACK);
196     auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
197                                : nullptr;
198     return HalResultFactory::fromStatus(getHal()->triggerSynced(cb));
199 }
200 
startSession(const std::vector<int32_t> & ids,const Aidl::VibrationSessionConfig & config,const std::function<void ()> & completionCallback)201 HalResult<std::shared_ptr<Aidl::IVibrationSession>> AidlManagerHalWrapper::startSession(
202         const std::vector<int32_t>& ids, const Aidl::VibrationSessionConfig& config,
203         const std::function<void()>& completionCallback) {
204     auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
205     std::shared_ptr<Aidl::IVibrationSession> session;
206     auto status = getHal()->startSession(ids, config, cb, &session);
207     return HalResultFactory::fromStatus<std::shared_ptr<Aidl::IVibrationSession>>(std::move(status),
208                                                                                   std::move(
209                                                                                           session));
210 }
211 
cancelSynced()212 HalResult<void> AidlManagerHalWrapper::cancelSynced() {
213     auto ret = HalResultFactory::fromStatus(getHal()->cancelSynced());
214     if (ret.isOk()) {
215         // Force reload of all vibrator controllers that were prepared for a sync operation before.
216         // This will trigger calls to getVibrator(id) on each controller, so they can use the
217         // latest service provided by this manager.
218         std::lock_guard<std::mutex> lock(mVibratorsMutex);
219         for (auto& entry : mVibrators) {
220             entry.second->tryReconnect();
221         }
222     }
223     return ret;
224 }
225 
clearSessions()226 HalResult<void> AidlManagerHalWrapper::clearSessions() {
227     return HalResultFactory::fromStatus(getHal()->clearSessions());
228 }
229 
getHal()230 std::shared_ptr<Aidl::IVibratorManager> AidlManagerHalWrapper::getHal() {
231     std::lock_guard<std::mutex> lock(mHandleMutex);
232     return mHandle;
233 }
234 
235 }; // namespace vibrator
236 
237 }; // namespace android
238