xref: /aosp_15_r20/frameworks/native/services/vibratorservice/VibratorManagerHalController.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 "VibratorManagerHalController"
18 
19 #include <utils/Log.h>
20 
21 #include <vibratorservice/VibratorManagerHalController.h>
22 
23 namespace Aidl = aidl::android::hardware::vibrator;
24 
25 namespace android {
26 
27 namespace vibrator {
28 
connectManagerHal(std::shared_ptr<CallbackScheduler> scheduler)29 std::shared_ptr<ManagerHalWrapper> connectManagerHal(std::shared_ptr<CallbackScheduler> scheduler) {
30     static bool gHalExists = true;
31     if (gHalExists) {
32         auto serviceName = std::string(Aidl::IVibratorManager::descriptor) + "/default";
33         if (AServiceManager_isDeclared(serviceName.c_str())) {
34             std::shared_ptr<Aidl::IVibratorManager> hal = Aidl::IVibratorManager::fromBinder(
35                     ndk::SpAIBinder(AServiceManager_checkService(serviceName.c_str())));
36             if (hal) {
37                 ALOGV("Successfully connected to VibratorManager HAL AIDL service.");
38                 return std::make_shared<AidlManagerHalWrapper>(std::move(scheduler),
39                                                                std::move(hal));
40             }
41         }
42     }
43 
44     gHalExists = false;
45     return std::make_shared<LegacyManagerHalWrapper>();
46 }
47 
48 static constexpr int MAX_RETRIES = 1;
49 
50 template <typename T>
processHalResult(HalResult<T> result,const char * functionName)51 HalResult<T> ManagerHalController::processHalResult(HalResult<T> result, const char* functionName) {
52     if (result.isFailed()) {
53         ALOGE("VibratorManager HAL %s failed: %s", functionName, result.errorMessage());
54     }
55     return result;
56 }
57 
58 template <typename T>
apply(ManagerHalController::hal_fn<T> & halFn,const char * functionName)59 HalResult<T> ManagerHalController::apply(ManagerHalController::hal_fn<T>& halFn,
60                                          const char* functionName) {
61     std::shared_ptr<ManagerHalWrapper> hal = nullptr;
62     {
63         std::lock_guard<std::mutex> lock(mConnectedHalMutex);
64         if (mConnectedHal == nullptr) {
65             // Init was never called, so connect to HAL for the first time during this call.
66             mConnectedHal = mConnector(mCallbackScheduler);
67 
68             if (mConnectedHal == nullptr) {
69                 ALOGV("Skipped %s because VibratorManager HAL is not available", functionName);
70                 return HalResult<T>::unsupported();
71             }
72         }
73         hal = mConnectedHal;
74     }
75 
76     HalResult<T> result = processHalResult(halFn(hal), functionName);
77     for (int i = 0; i < MAX_RETRIES && result.shouldRetry(); i++) {
78         {
79             std::lock_guard<std::mutex> lock(mConnectedHalMutex);
80             mConnectedHal->tryReconnect();
81         }
82         result = processHalResult(halFn(hal), functionName);
83     }
84 
85     return result;
86 }
87 
88 // -------------------------------------------------------------------------------------------------
89 
init()90 void ManagerHalController::init() {
91     std::lock_guard<std::mutex> lock(mConnectedHalMutex);
92     if (mConnectedHal == nullptr) {
93         mConnectedHal = mConnector(mCallbackScheduler);
94     }
95 }
96 
ping()97 HalResult<void> ManagerHalController::ping() {
98     hal_fn<void> pingFn = [](std::shared_ptr<ManagerHalWrapper> hal) { return hal->ping(); };
99     return apply(pingFn, "ping");
100 }
101 
tryReconnect()102 void ManagerHalController::tryReconnect() {
103     std::lock_guard<std::mutex> lock(mConnectedHalMutex);
104     if (mConnectedHal == nullptr) {
105         mConnectedHal = mConnector(mCallbackScheduler);
106     } else {
107         mConnectedHal->tryReconnect();
108     }
109 }
110 
getCapabilities()111 HalResult<ManagerCapabilities> ManagerHalController::getCapabilities() {
112     hal_fn<ManagerCapabilities> getCapabilitiesFn = [](std::shared_ptr<ManagerHalWrapper> hal) {
113         return hal->getCapabilities();
114     };
115     return apply(getCapabilitiesFn, "getCapabilities");
116 }
117 
getVibratorIds()118 HalResult<std::vector<int32_t>> ManagerHalController::getVibratorIds() {
119     hal_fn<std::vector<int32_t>> getVibratorIdsFn = [](std::shared_ptr<ManagerHalWrapper> hal) {
120         return hal->getVibratorIds();
121     };
122     return apply(getVibratorIdsFn, "getVibratorIds");
123 }
124 
getVibrator(int32_t id)125 HalResult<std::shared_ptr<HalController>> ManagerHalController::getVibrator(int32_t id) {
126     hal_fn<std::shared_ptr<HalController>> getVibratorFn =
127             [&](std::shared_ptr<ManagerHalWrapper> hal) { return hal->getVibrator(id); };
128     return apply(getVibratorFn, "getVibrator");
129 }
130 
prepareSynced(const std::vector<int32_t> & ids)131 HalResult<void> ManagerHalController::prepareSynced(const std::vector<int32_t>& ids) {
132     hal_fn<void> prepareSyncedFn = [&](std::shared_ptr<ManagerHalWrapper> hal) {
133         return hal->prepareSynced(ids);
134     };
135     return apply(prepareSyncedFn, "prepareSynced");
136 }
137 
triggerSynced(const std::function<void ()> & completionCallback)138 HalResult<void> ManagerHalController::triggerSynced(
139         const std::function<void()>& completionCallback) {
140     hal_fn<void> triggerSyncedFn = [&](std::shared_ptr<ManagerHalWrapper> hal) {
141         return hal->triggerSynced(completionCallback);
142     };
143     return apply(triggerSyncedFn, "triggerSynced");
144 }
145 
cancelSynced()146 HalResult<void> ManagerHalController::cancelSynced() {
147     hal_fn<void> cancelSyncedFn = [](std::shared_ptr<ManagerHalWrapper> hal) {
148         return hal->cancelSynced();
149     };
150     return apply(cancelSyncedFn, "cancelSynced");
151 }
152 
startSession(const std::vector<int32_t> & ids,const Aidl::VibrationSessionConfig & config,const std::function<void ()> & completionCallback)153 HalResult<std::shared_ptr<Aidl::IVibrationSession>> ManagerHalController::startSession(
154         const std::vector<int32_t>& ids, const Aidl::VibrationSessionConfig& config,
155         const std::function<void()>& completionCallback) {
156     hal_fn<std::shared_ptr<Aidl::IVibrationSession>> startSessionFn =
157             [&](std::shared_ptr<ManagerHalWrapper> hal) {
158                 return hal->startSession(ids, config, completionCallback);
159             };
160     return apply(startSessionFn, "startSession");
161 }
162 
clearSessions()163 HalResult<void> ManagerHalController::clearSessions() {
164     hal_fn<void> clearSessionsFn = [](std::shared_ptr<ManagerHalWrapper> hal) {
165         return hal->clearSessions();
166     };
167     return apply(clearSessionsFn, "clearSessions");
168 }
169 
170 }; // namespace vibrator
171 
172 }; // namespace android
173