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