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 = 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         sp<Aidl::IVibratorManager> hal = waitForVintfService<Aidl::IVibratorManager>();
33         if (hal) {
34             ALOGV("Successfully connected to VibratorManager HAL AIDL service.");
35             return std::make_shared<AidlManagerHalWrapper>(std::move(scheduler), hal);
36         }
37     }
38 
39     gHalExists = false;
40     return std::make_shared<LegacyManagerHalWrapper>();
41 }
42 
43 static constexpr int MAX_RETRIES = 1;
44 
45 template <typename T>
processHalResult(HalResult<T> result,const char * functionName)46 HalResult<T> ManagerHalController::processHalResult(HalResult<T> result, const char* functionName) {
47     if (result.isFailed()) {
48         ALOGE("VibratorManager HAL %s failed: %s", functionName, result.errorMessage());
49     }
50     return result;
51 }
52 
53 template <typename T>
apply(ManagerHalController::hal_fn<T> & halFn,const char * functionName)54 HalResult<T> ManagerHalController::apply(ManagerHalController::hal_fn<T>& halFn,
55                                          const char* functionName) {
56     std::shared_ptr<ManagerHalWrapper> hal = nullptr;
57     {
58         std::lock_guard<std::mutex> lock(mConnectedHalMutex);
59         if (mConnectedHal == nullptr) {
60             // Init was never called, so connect to HAL for the first time during this call.
61             mConnectedHal = mConnector(mCallbackScheduler);
62 
63             if (mConnectedHal == nullptr) {
64                 ALOGV("Skipped %s because VibratorManager HAL is not available", functionName);
65                 return HalResult<T>::unsupported();
66             }
67         }
68         hal = mConnectedHal;
69     }
70 
71     HalResult<T> result = processHalResult(halFn(hal), functionName);
72     for (int i = 0; i < MAX_RETRIES && result.shouldRetry(); i++) {
73         {
74             std::lock_guard<std::mutex> lock(mConnectedHalMutex);
75             mConnectedHal->tryReconnect();
76         }
77         result = processHalResult(halFn(hal), functionName);
78     }
79 
80     return result;
81 }
82 
83 // -------------------------------------------------------------------------------------------------
84 
init()85 void ManagerHalController::init() {
86     std::lock_guard<std::mutex> lock(mConnectedHalMutex);
87     if (mConnectedHal == nullptr) {
88         mConnectedHal = mConnector(mCallbackScheduler);
89     }
90 }
91 
ping()92 HalResult<void> ManagerHalController::ping() {
93     hal_fn<void> pingFn = [](std::shared_ptr<ManagerHalWrapper> hal) { return hal->ping(); };
94     return apply(pingFn, "ping");
95 }
96 
tryReconnect()97 void ManagerHalController::tryReconnect() {
98     std::lock_guard<std::mutex> lock(mConnectedHalMutex);
99     if (mConnectedHal == nullptr) {
100         mConnectedHal = mConnector(mCallbackScheduler);
101     } else {
102         mConnectedHal->tryReconnect();
103     }
104 }
105 
getCapabilities()106 HalResult<ManagerCapabilities> ManagerHalController::getCapabilities() {
107     hal_fn<ManagerCapabilities> getCapabilitiesFn = [](std::shared_ptr<ManagerHalWrapper> hal) {
108         return hal->getCapabilities();
109     };
110     return apply(getCapabilitiesFn, "getCapabilities");
111 }
112 
getVibratorIds()113 HalResult<std::vector<int32_t>> ManagerHalController::getVibratorIds() {
114     hal_fn<std::vector<int32_t>> getVibratorIdsFn = [](std::shared_ptr<ManagerHalWrapper> hal) {
115         return hal->getVibratorIds();
116     };
117     return apply(getVibratorIdsFn, "getVibratorIds");
118 }
119 
getVibrator(int32_t id)120 HalResult<std::shared_ptr<HalController>> ManagerHalController::getVibrator(int32_t id) {
121     hal_fn<std::shared_ptr<HalController>> getVibratorFn =
122             [&](std::shared_ptr<ManagerHalWrapper> hal) { return hal->getVibrator(id); };
123     return apply(getVibratorFn, "getVibrator");
124 }
125 
prepareSynced(const std::vector<int32_t> & ids)126 HalResult<void> ManagerHalController::prepareSynced(const std::vector<int32_t>& ids) {
127     hal_fn<void> prepareSyncedFn = [&](std::shared_ptr<ManagerHalWrapper> hal) {
128         return hal->prepareSynced(ids);
129     };
130     return apply(prepareSyncedFn, "prepareSynced");
131 }
132 
triggerSynced(const std::function<void ()> & completionCallback)133 HalResult<void> ManagerHalController::triggerSynced(
134         const std::function<void()>& completionCallback) {
135     hal_fn<void> triggerSyncedFn = [&](std::shared_ptr<ManagerHalWrapper> hal) {
136         return hal->triggerSynced(completionCallback);
137     };
138     return apply(triggerSyncedFn, "triggerSynced");
139 }
140 
cancelSynced()141 HalResult<void> ManagerHalController::cancelSynced() {
142     hal_fn<void> cancelSyncedFn = [](std::shared_ptr<ManagerHalWrapper> hal) {
143         return hal->cancelSynced();
144     };
145     return apply(cancelSyncedFn, "cancelSynced");
146 }
147 
148 }; // namespace vibrator
149 
150 }; // namespace android
151