blob: 3db8ff8699dd1315675a59eb96f5931b7e34b449 [file] [log] [blame]
Lais Andrade24b5b8f2020-08-27 15:55:54 +00001/*
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
Lais Andrade818a2252024-06-24 14:48:14 +010023namespace Aidl = aidl::android::hardware::vibrator;
Lais Andrade98c97032020-11-17 19:23:01 +000024
Lais Andrade24b5b8f2020-08-27 15:55:54 +000025namespace android {
26
27namespace vibrator {
28
29constexpr int32_t SINGLE_VIBRATOR_ID = 0;
Lais Andrade98c97032020-11-17 19:23:01 +000030const constexpr char* MISSING_VIBRATOR_MESSAGE_PREFIX = "No vibrator with id=";
Lais Andrade24b5b8f2020-08-27 15:55:54 +000031
Lais Andradee2b376d2024-10-28 18:23:15 +000032HalResult<void> ManagerHalWrapper::prepareSynced(const std::vector<int32_t>&) {
33 return HalResult<void>::unsupported();
34}
35
36HalResult<void> ManagerHalWrapper::triggerSynced(const std::function<void()>&) {
37 return HalResult<void>::unsupported();
38}
39
40HalResult<void> ManagerHalWrapper::cancelSynced() {
41 return HalResult<void>::unsupported();
42}
43
44HalResult<std::shared_ptr<Aidl::IVibrationSession>> ManagerHalWrapper::startSession(
45 const std::vector<int32_t>&, const Aidl::VibrationSessionConfig&,
46 const std::function<void()>&) {
47 return HalResult<std::shared_ptr<Aidl::IVibrationSession>>::unsupported();
48}
49
50HalResult<void> ManagerHalWrapper::clearSessions() {
51 return HalResult<void>::unsupported();
52}
53
54// -------------------------------------------------------------------------------------------------
55
Lais Andrade24b5b8f2020-08-27 15:55:54 +000056HalResult<void> LegacyManagerHalWrapper::ping() {
Lais Andrade81bf87f2021-03-29 14:08:02 +000057 auto pingFn = [](HalWrapper* hal) { return hal->ping(); };
Lais Andrade965284b2021-03-19 20:58:15 +000058 return mController->doWithRetry<void>(pingFn, "ping");
Lais Andrade24b5b8f2020-08-27 15:55:54 +000059}
60
61void LegacyManagerHalWrapper::tryReconnect() {
62 mController->tryReconnect();
63}
64
Lais Andrade98c97032020-11-17 19:23:01 +000065HalResult<ManagerCapabilities> LegacyManagerHalWrapper::getCapabilities() {
66 return HalResult<ManagerCapabilities>::ok(ManagerCapabilities::NONE);
67}
68
Lais Andrade24b5b8f2020-08-27 15:55:54 +000069HalResult<std::vector<int32_t>> LegacyManagerHalWrapper::getVibratorIds() {
70 if (mController->init()) {
71 return HalResult<std::vector<int32_t>>::ok(std::vector<int32_t>(1, SINGLE_VIBRATOR_ID));
72 }
73 // Controller.init did not connect to any vibrator HAL service, so the device has no vibrator.
74 return HalResult<std::vector<int32_t>>::ok(std::vector<int32_t>());
75}
76
77HalResult<std::shared_ptr<HalController>> LegacyManagerHalWrapper::getVibrator(int32_t id) {
78 if (id == SINGLE_VIBRATOR_ID && mController->init()) {
79 return HalResult<std::shared_ptr<HalController>>::ok(mController);
80 }
81 // Controller.init did not connect to any vibrator HAL service, so the device has no vibrator.
Lais Andrade641248e2024-02-16 17:49:36 +000082 return HalResult<std::shared_ptr<HalController>>::failed(
83 (MISSING_VIBRATOR_MESSAGE_PREFIX + std::to_string(id)).c_str());
Lais Andrade24b5b8f2020-08-27 15:55:54 +000084}
85
Lais Andrade98c97032020-11-17 19:23:01 +000086// -------------------------------------------------------------------------------------------------
87
Lais Andradef20b1442020-11-19 15:14:10 +000088std::shared_ptr<HalWrapper> AidlManagerHalWrapper::connectToVibrator(
89 int32_t vibratorId, std::shared_ptr<CallbackScheduler> callbackScheduler) {
Lais Andrade818a2252024-06-24 14:48:14 +010090 std::function<HalResult<std::shared_ptr<Aidl::IVibrator>>()> reconnectFn = [=, this]() {
91 std::shared_ptr<Aidl::IVibrator> vibrator;
92 auto status = this->getHal()->getVibrator(vibratorId, &vibrator);
93 return HalResultFactory::fromStatus<std::shared_ptr<Aidl::IVibrator>>(std::move(status),
94 vibrator);
Lais Andrade98c97032020-11-17 19:23:01 +000095 };
96 auto result = reconnectFn();
97 if (!result.isOk()) {
98 return nullptr;
99 }
100 auto vibrator = result.value();
101 if (!vibrator) {
102 return nullptr;
103 }
Lais Andrade641248e2024-02-16 17:49:36 +0000104 return std::make_unique<AidlHalWrapper>(std::move(callbackScheduler), std::move(vibrator),
105 reconnectFn);
Lais Andrade98c97032020-11-17 19:23:01 +0000106}
107
108HalResult<void> AidlManagerHalWrapper::ping() {
Lais Andrade818a2252024-06-24 14:48:14 +0100109 return HalResultFactory::fromStatus(AIBinder_ping(getHal()->asBinder().get()));
Lais Andrade98c97032020-11-17 19:23:01 +0000110}
111
112void AidlManagerHalWrapper::tryReconnect() {
Lais Andrade818a2252024-06-24 14:48:14 +0100113 auto aidlServiceName = std::string(Aidl::IVibratorManager::descriptor) + "/default";
114 std::shared_ptr<Aidl::IVibratorManager> newHandle = Aidl::IVibratorManager::fromBinder(
115 ndk::SpAIBinder(AServiceManager_checkService(aidlServiceName.c_str())));
Lais Andrade98c97032020-11-17 19:23:01 +0000116 if (newHandle) {
117 std::lock_guard<std::mutex> lock(mHandleMutex);
118 mHandle = std::move(newHandle);
119 }
120}
121
122HalResult<ManagerCapabilities> AidlManagerHalWrapper::getCapabilities() {
123 std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
124 if (mCapabilities.has_value()) {
125 // Return copy of cached value.
126 return HalResult<ManagerCapabilities>::ok(*mCapabilities);
127 }
128 int32_t cap = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100129 auto status = getHal()->getCapabilities(&cap);
Lais Andrade641248e2024-02-16 17:49:36 +0000130 auto capabilities = static_cast<ManagerCapabilities>(cap);
Lais Andrade818a2252024-06-24 14:48:14 +0100131 auto ret = HalResultFactory::fromStatus<ManagerCapabilities>(std::move(status), capabilities);
Lais Andrade98c97032020-11-17 19:23:01 +0000132 if (ret.isOk()) {
133 // Cache copy of returned value.
134 mCapabilities.emplace(ret.value());
135 }
136 return ret;
137}
138
139HalResult<std::vector<int32_t>> AidlManagerHalWrapper::getVibratorIds() {
140 std::lock_guard<std::mutex> lock(mVibratorsMutex);
141 if (mVibratorIds.has_value()) {
142 // Return copy of cached values.
143 return HalResult<std::vector<int32_t>>::ok(*mVibratorIds);
144 }
145 std::vector<int32_t> ids;
Lais Andrade818a2252024-06-24 14:48:14 +0100146 auto status = getHal()->getVibratorIds(&ids);
147 auto ret = HalResultFactory::fromStatus<std::vector<int32_t>>(std::move(status), ids);
Lais Andrade98c97032020-11-17 19:23:01 +0000148 if (ret.isOk()) {
149 // Cache copy of returned value and the individual controllers.
150 mVibratorIds.emplace(ret.value());
151 for (auto& id : ids) {
Lais Andradef20b1442020-11-19 15:14:10 +0000152 HalController::Connector connector = [&, id](auto scheduler) {
153 return this->connectToVibrator(id, scheduler);
154 };
155 auto controller = std::make_unique<HalController>(mCallbackScheduler, connector);
Lais Andrade98c97032020-11-17 19:23:01 +0000156 mVibrators[id] = std::move(controller);
157 }
158 }
159 return ret;
160}
161
162HalResult<std::shared_ptr<HalController>> AidlManagerHalWrapper::getVibrator(int32_t id) {
163 // Make sure we cache vibrator ids and initialize the individual controllers.
164 getVibratorIds();
165 std::lock_guard<std::mutex> lock(mVibratorsMutex);
166 auto it = mVibrators.find(id);
167 if (it != mVibrators.end()) {
168 return HalResult<std::shared_ptr<HalController>>::ok(it->second);
169 }
Lais Andrade641248e2024-02-16 17:49:36 +0000170 return HalResult<std::shared_ptr<HalController>>::failed(
171 (MISSING_VIBRATOR_MESSAGE_PREFIX + std::to_string(id)).c_str());
Lais Andrade98c97032020-11-17 19:23:01 +0000172}
173
174HalResult<void> AidlManagerHalWrapper::prepareSynced(const std::vector<int32_t>& ids) {
Lais Andrade641248e2024-02-16 17:49:36 +0000175 auto ret = HalResultFactory::fromStatus(getHal()->prepareSynced(ids));
Lais Andrade98c97032020-11-17 19:23:01 +0000176 if (ret.isOk()) {
177 // Force reload of all vibrator controllers that were prepared for a sync operation here.
178 // This will trigger calls to getVibrator(id) on each controller, so they can use the
179 // latest service provided by this manager.
180 std::lock_guard<std::mutex> lock(mVibratorsMutex);
181 for (auto& id : ids) {
182 auto it = mVibrators.find(id);
183 if (it != mVibrators.end()) {
184 it->second->tryReconnect();
185 }
186 }
187 }
188 return ret;
189}
190
191HalResult<void> AidlManagerHalWrapper::triggerSynced(
192 const std::function<void()>& completionCallback) {
193 HalResult<ManagerCapabilities> capabilities = getCapabilities();
194 bool supportsCallback = capabilities.isOk() &&
195 static_cast<int32_t>(capabilities.value() & ManagerCapabilities::TRIGGER_CALLBACK);
Lais Andrade818a2252024-06-24 14:48:14 +0100196 auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
197 : nullptr;
Lais Andrade641248e2024-02-16 17:49:36 +0000198 return HalResultFactory::fromStatus(getHal()->triggerSynced(cb));
Lais Andrade98c97032020-11-17 19:23:01 +0000199}
200
Lais Andradee2b376d2024-10-28 18:23:15 +0000201HalResult<std::shared_ptr<Aidl::IVibrationSession>> AidlManagerHalWrapper::startSession(
202 const std::vector<int32_t>& ids, const Aidl::VibrationSessionConfig& config,
203 const std::function<void()>& completionCallback) {
204 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
205 std::shared_ptr<Aidl::IVibrationSession> session;
206 auto status = getHal()->startSession(ids, config, cb, &session);
207 return HalResultFactory::fromStatus<std::shared_ptr<Aidl::IVibrationSession>>(std::move(status),
208 std::move(
209 session));
210}
211
Lais Andrade98c97032020-11-17 19:23:01 +0000212HalResult<void> AidlManagerHalWrapper::cancelSynced() {
Lais Andrade641248e2024-02-16 17:49:36 +0000213 auto ret = HalResultFactory::fromStatus(getHal()->cancelSynced());
Lais Andrade98c97032020-11-17 19:23:01 +0000214 if (ret.isOk()) {
215 // Force reload of all vibrator controllers that were prepared for a sync operation before.
216 // This will trigger calls to getVibrator(id) on each controller, so they can use the
217 // latest service provided by this manager.
218 std::lock_guard<std::mutex> lock(mVibratorsMutex);
219 for (auto& entry : mVibrators) {
220 entry.second->tryReconnect();
221 }
222 }
223 return ret;
224}
225
Lais Andradee2b376d2024-10-28 18:23:15 +0000226HalResult<void> AidlManagerHalWrapper::clearSessions() {
227 return HalResultFactory::fromStatus(getHal()->clearSessions());
228}
229
Lais Andrade818a2252024-06-24 14:48:14 +0100230std::shared_ptr<Aidl::IVibratorManager> AidlManagerHalWrapper::getHal() {
Lais Andrade98c97032020-11-17 19:23:01 +0000231 std::lock_guard<std::mutex> lock(mHandleMutex);
232 return mHandle;
233}
234
Lais Andrade24b5b8f2020-08-27 15:55:54 +0000235}; // namespace vibrator
236
237}; // namespace android