• 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 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