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