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 "VibratorManagerHalWrapper"
18
19 #include <utils/Log.h>
20
21 #include <vibratorservice/VibratorManagerHalWrapper.h>
22
23 namespace Aidl = android::hardware::vibrator;
24
25 namespace android {
26
27 namespace vibrator {
28
29 constexpr int32_t SINGLE_VIBRATOR_ID = 0;
30 const constexpr char* MISSING_VIBRATOR_MESSAGE_PREFIX = "No vibrator with id=";
31
ping()32 HalResult<void> LegacyManagerHalWrapper::ping() {
33 auto pingFn = [](HalWrapper* hal) { return hal->ping(); };
34 return mController->doWithRetry<void>(pingFn, "ping");
35 }
36
tryReconnect()37 void LegacyManagerHalWrapper::tryReconnect() {
38 mController->tryReconnect();
39 }
40
getCapabilities()41 HalResult<ManagerCapabilities> LegacyManagerHalWrapper::getCapabilities() {
42 return HalResult<ManagerCapabilities>::ok(ManagerCapabilities::NONE);
43 }
44
getVibratorIds()45 HalResult<std::vector<int32_t>> LegacyManagerHalWrapper::getVibratorIds() {
46 if (mController->init()) {
47 return HalResult<std::vector<int32_t>>::ok(std::vector<int32_t>(1, SINGLE_VIBRATOR_ID));
48 }
49 // Controller.init did not connect to any vibrator HAL service, so the device has no vibrator.
50 return HalResult<std::vector<int32_t>>::ok(std::vector<int32_t>());
51 }
52
getVibrator(int32_t id)53 HalResult<std::shared_ptr<HalController>> LegacyManagerHalWrapper::getVibrator(int32_t id) {
54 if (id == SINGLE_VIBRATOR_ID && mController->init()) {
55 return HalResult<std::shared_ptr<HalController>>::ok(mController);
56 }
57 // Controller.init did not connect to any vibrator HAL service, so the device has no vibrator.
58 return HalResult<std::shared_ptr<HalController>>::failed(MISSING_VIBRATOR_MESSAGE_PREFIX +
59 std::to_string(id));
60 }
61
prepareSynced(const std::vector<int32_t> &)62 HalResult<void> LegacyManagerHalWrapper::prepareSynced(const std::vector<int32_t>&) {
63 return HalResult<void>::unsupported();
64 }
65
triggerSynced(const std::function<void ()> &)66 HalResult<void> LegacyManagerHalWrapper::triggerSynced(const std::function<void()>&) {
67 return HalResult<void>::unsupported();
68 }
69
cancelSynced()70 HalResult<void> LegacyManagerHalWrapper::cancelSynced() {
71 return HalResult<void>::unsupported();
72 }
73
74 // -------------------------------------------------------------------------------------------------
75
connectToVibrator(int32_t vibratorId,std::shared_ptr<CallbackScheduler> callbackScheduler)76 std::shared_ptr<HalWrapper> AidlManagerHalWrapper::connectToVibrator(
77 int32_t vibratorId, std::shared_ptr<CallbackScheduler> callbackScheduler) {
78 std::function<HalResult<sp<Aidl::IVibrator>>()> reconnectFn = [=]() {
79 sp<Aidl::IVibrator> vibrator;
80 auto result = this->getHal()->getVibrator(vibratorId, &vibrator);
81 return HalResult<sp<Aidl::IVibrator>>::fromStatus(result, vibrator);
82 };
83 auto result = reconnectFn();
84 if (!result.isOk()) {
85 return nullptr;
86 }
87 auto vibrator = result.value();
88 if (!vibrator) {
89 return nullptr;
90 }
91 return std::move(std::make_unique<AidlHalWrapper>(std::move(callbackScheduler),
92 std::move(vibrator), reconnectFn));
93 }
94
ping()95 HalResult<void> AidlManagerHalWrapper::ping() {
96 return HalResult<void>::fromStatus(IInterface::asBinder(getHal())->pingBinder());
97 }
98
tryReconnect()99 void AidlManagerHalWrapper::tryReconnect() {
100 sp<Aidl::IVibratorManager> newHandle = checkVintfService<Aidl::IVibratorManager>();
101 if (newHandle) {
102 std::lock_guard<std::mutex> lock(mHandleMutex);
103 mHandle = std::move(newHandle);
104 }
105 }
106
getCapabilities()107 HalResult<ManagerCapabilities> AidlManagerHalWrapper::getCapabilities() {
108 std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
109 if (mCapabilities.has_value()) {
110 // Return copy of cached value.
111 return HalResult<ManagerCapabilities>::ok(*mCapabilities);
112 }
113 int32_t cap = 0;
114 auto result = getHal()->getCapabilities(&cap);
115 auto ret = HalResult<ManagerCapabilities>::fromStatus(result,
116 static_cast<ManagerCapabilities>(cap));
117 if (ret.isOk()) {
118 // Cache copy of returned value.
119 mCapabilities.emplace(ret.value());
120 }
121 return ret;
122 }
123
getVibratorIds()124 HalResult<std::vector<int32_t>> AidlManagerHalWrapper::getVibratorIds() {
125 std::lock_guard<std::mutex> lock(mVibratorsMutex);
126 if (mVibratorIds.has_value()) {
127 // Return copy of cached values.
128 return HalResult<std::vector<int32_t>>::ok(*mVibratorIds);
129 }
130 std::vector<int32_t> ids;
131 auto result = getHal()->getVibratorIds(&ids);
132 auto ret = HalResult<std::vector<int32_t>>::fromStatus(result, ids);
133 if (ret.isOk()) {
134 // Cache copy of returned value and the individual controllers.
135 mVibratorIds.emplace(ret.value());
136 for (auto& id : ids) {
137 HalController::Connector connector = [&, id](auto scheduler) {
138 return this->connectToVibrator(id, scheduler);
139 };
140 auto controller = std::make_unique<HalController>(mCallbackScheduler, connector);
141 mVibrators[id] = std::move(controller);
142 }
143 }
144 return ret;
145 }
146
getVibrator(int32_t id)147 HalResult<std::shared_ptr<HalController>> AidlManagerHalWrapper::getVibrator(int32_t id) {
148 // Make sure we cache vibrator ids and initialize the individual controllers.
149 getVibratorIds();
150 std::lock_guard<std::mutex> lock(mVibratorsMutex);
151 auto it = mVibrators.find(id);
152 if (it != mVibrators.end()) {
153 return HalResult<std::shared_ptr<HalController>>::ok(it->second);
154 }
155 return HalResult<std::shared_ptr<HalController>>::failed(MISSING_VIBRATOR_MESSAGE_PREFIX +
156 std::to_string(id));
157 }
158
prepareSynced(const std::vector<int32_t> & ids)159 HalResult<void> AidlManagerHalWrapper::prepareSynced(const std::vector<int32_t>& ids) {
160 auto ret = HalResult<void>::fromStatus(getHal()->prepareSynced(ids));
161 if (ret.isOk()) {
162 // Force reload of all vibrator controllers that were prepared for a sync operation here.
163 // This will trigger calls to getVibrator(id) on each controller, so they can use the
164 // latest service provided by this manager.
165 std::lock_guard<std::mutex> lock(mVibratorsMutex);
166 for (auto& id : ids) {
167 auto it = mVibrators.find(id);
168 if (it != mVibrators.end()) {
169 it->second->tryReconnect();
170 }
171 }
172 }
173 return ret;
174 }
175
triggerSynced(const std::function<void ()> & completionCallback)176 HalResult<void> AidlManagerHalWrapper::triggerSynced(
177 const std::function<void()>& completionCallback) {
178 HalResult<ManagerCapabilities> capabilities = getCapabilities();
179 bool supportsCallback = capabilities.isOk() &&
180 static_cast<int32_t>(capabilities.value() & ManagerCapabilities::TRIGGER_CALLBACK);
181 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
182 return HalResult<void>::fromStatus(getHal()->triggerSynced(cb));
183 }
184
cancelSynced()185 HalResult<void> AidlManagerHalWrapper::cancelSynced() {
186 auto ret = HalResult<void>::fromStatus(getHal()->cancelSynced());
187 if (ret.isOk()) {
188 // Force reload of all vibrator controllers that were prepared for a sync operation before.
189 // This will trigger calls to getVibrator(id) on each controller, so they can use the
190 // latest service provided by this manager.
191 std::lock_guard<std::mutex> lock(mVibratorsMutex);
192 for (auto& entry : mVibrators) {
193 entry.second->tryReconnect();
194 }
195 }
196 return ret;
197 }
198
getHal()199 sp<Aidl::IVibratorManager> AidlManagerHalWrapper::getHal() {
200 std::lock_guard<std::mutex> lock(mHandleMutex);
201 return mHandle;
202 }
203
204 }; // namespace vibrator
205
206 }; // namespace android
207