blob: 93ec781b214fb7a0d9bc64382975769aa1a8ba79 [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
32HalResult<void> LegacyManagerHalWrapper::ping() {
Lais Andrade81bf87f2021-03-29 14:08:02 +000033 auto pingFn = [](HalWrapper* hal) { return hal->ping(); };
Lais Andrade965284b2021-03-19 20:58:15 +000034 return mController->doWithRetry<void>(pingFn, "ping");
Lais Andrade24b5b8f2020-08-27 15:55:54 +000035}
36
37void LegacyManagerHalWrapper::tryReconnect() {
38 mController->tryReconnect();
39}
40
Lais Andrade98c97032020-11-17 19:23:01 +000041HalResult<ManagerCapabilities> LegacyManagerHalWrapper::getCapabilities() {
42 return HalResult<ManagerCapabilities>::ok(ManagerCapabilities::NONE);
43}
44
Lais Andrade24b5b8f2020-08-27 15:55:54 +000045HalResult<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
53HalResult<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.
Lais Andrade641248e2024-02-16 17:49:36 +000058 return HalResult<std::shared_ptr<HalController>>::failed(
59 (MISSING_VIBRATOR_MESSAGE_PREFIX + std::to_string(id)).c_str());
Lais Andrade24b5b8f2020-08-27 15:55:54 +000060}
61
62HalResult<void> LegacyManagerHalWrapper::prepareSynced(const std::vector<int32_t>&) {
63 return HalResult<void>::unsupported();
64}
65
66HalResult<void> LegacyManagerHalWrapper::triggerSynced(const std::function<void()>&) {
67 return HalResult<void>::unsupported();
68}
69
70HalResult<void> LegacyManagerHalWrapper::cancelSynced() {
71 return HalResult<void>::unsupported();
72}
73
Lais Andrade98c97032020-11-17 19:23:01 +000074// -------------------------------------------------------------------------------------------------
75
Lais Andradef20b1442020-11-19 15:14:10 +000076std::shared_ptr<HalWrapper> AidlManagerHalWrapper::connectToVibrator(
77 int32_t vibratorId, std::shared_ptr<CallbackScheduler> callbackScheduler) {
Lais Andrade818a2252024-06-24 14:48:14 +010078 std::function<HalResult<std::shared_ptr<Aidl::IVibrator>>()> reconnectFn = [=, this]() {
79 std::shared_ptr<Aidl::IVibrator> vibrator;
80 auto status = this->getHal()->getVibrator(vibratorId, &vibrator);
81 return HalResultFactory::fromStatus<std::shared_ptr<Aidl::IVibrator>>(std::move(status),
82 vibrator);
Lais Andrade98c97032020-11-17 19:23:01 +000083 };
84 auto result = reconnectFn();
85 if (!result.isOk()) {
86 return nullptr;
87 }
88 auto vibrator = result.value();
89 if (!vibrator) {
90 return nullptr;
91 }
Lais Andrade641248e2024-02-16 17:49:36 +000092 return std::make_unique<AidlHalWrapper>(std::move(callbackScheduler), std::move(vibrator),
93 reconnectFn);
Lais Andrade98c97032020-11-17 19:23:01 +000094}
95
96HalResult<void> AidlManagerHalWrapper::ping() {
Lais Andrade818a2252024-06-24 14:48:14 +010097 return HalResultFactory::fromStatus(AIBinder_ping(getHal()->asBinder().get()));
Lais Andrade98c97032020-11-17 19:23:01 +000098}
99
100void AidlManagerHalWrapper::tryReconnect() {
Lais Andrade818a2252024-06-24 14:48:14 +0100101 auto aidlServiceName = std::string(Aidl::IVibratorManager::descriptor) + "/default";
102 std::shared_ptr<Aidl::IVibratorManager> newHandle = Aidl::IVibratorManager::fromBinder(
103 ndk::SpAIBinder(AServiceManager_checkService(aidlServiceName.c_str())));
Lais Andrade98c97032020-11-17 19:23:01 +0000104 if (newHandle) {
105 std::lock_guard<std::mutex> lock(mHandleMutex);
106 mHandle = std::move(newHandle);
107 }
108}
109
110HalResult<ManagerCapabilities> AidlManagerHalWrapper::getCapabilities() {
111 std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
112 if (mCapabilities.has_value()) {
113 // Return copy of cached value.
114 return HalResult<ManagerCapabilities>::ok(*mCapabilities);
115 }
116 int32_t cap = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100117 auto status = getHal()->getCapabilities(&cap);
Lais Andrade641248e2024-02-16 17:49:36 +0000118 auto capabilities = static_cast<ManagerCapabilities>(cap);
Lais Andrade818a2252024-06-24 14:48:14 +0100119 auto ret = HalResultFactory::fromStatus<ManagerCapabilities>(std::move(status), capabilities);
Lais Andrade98c97032020-11-17 19:23:01 +0000120 if (ret.isOk()) {
121 // Cache copy of returned value.
122 mCapabilities.emplace(ret.value());
123 }
124 return ret;
125}
126
127HalResult<std::vector<int32_t>> AidlManagerHalWrapper::getVibratorIds() {
128 std::lock_guard<std::mutex> lock(mVibratorsMutex);
129 if (mVibratorIds.has_value()) {
130 // Return copy of cached values.
131 return HalResult<std::vector<int32_t>>::ok(*mVibratorIds);
132 }
133 std::vector<int32_t> ids;
Lais Andrade818a2252024-06-24 14:48:14 +0100134 auto status = getHal()->getVibratorIds(&ids);
135 auto ret = HalResultFactory::fromStatus<std::vector<int32_t>>(std::move(status), ids);
Lais Andrade98c97032020-11-17 19:23:01 +0000136 if (ret.isOk()) {
137 // Cache copy of returned value and the individual controllers.
138 mVibratorIds.emplace(ret.value());
139 for (auto& id : ids) {
Lais Andradef20b1442020-11-19 15:14:10 +0000140 HalController::Connector connector = [&, id](auto scheduler) {
141 return this->connectToVibrator(id, scheduler);
142 };
143 auto controller = std::make_unique<HalController>(mCallbackScheduler, connector);
Lais Andrade98c97032020-11-17 19:23:01 +0000144 mVibrators[id] = std::move(controller);
145 }
146 }
147 return ret;
148}
149
150HalResult<std::shared_ptr<HalController>> AidlManagerHalWrapper::getVibrator(int32_t id) {
151 // Make sure we cache vibrator ids and initialize the individual controllers.
152 getVibratorIds();
153 std::lock_guard<std::mutex> lock(mVibratorsMutex);
154 auto it = mVibrators.find(id);
155 if (it != mVibrators.end()) {
156 return HalResult<std::shared_ptr<HalController>>::ok(it->second);
157 }
Lais Andrade641248e2024-02-16 17:49:36 +0000158 return HalResult<std::shared_ptr<HalController>>::failed(
159 (MISSING_VIBRATOR_MESSAGE_PREFIX + std::to_string(id)).c_str());
Lais Andrade98c97032020-11-17 19:23:01 +0000160}
161
162HalResult<void> AidlManagerHalWrapper::prepareSynced(const std::vector<int32_t>& ids) {
Lais Andrade641248e2024-02-16 17:49:36 +0000163 auto ret = HalResultFactory::fromStatus(getHal()->prepareSynced(ids));
Lais Andrade98c97032020-11-17 19:23:01 +0000164 if (ret.isOk()) {
165 // Force reload of all vibrator controllers that were prepared for a sync operation here.
166 // This will trigger calls to getVibrator(id) on each controller, so they can use the
167 // latest service provided by this manager.
168 std::lock_guard<std::mutex> lock(mVibratorsMutex);
169 for (auto& id : ids) {
170 auto it = mVibrators.find(id);
171 if (it != mVibrators.end()) {
172 it->second->tryReconnect();
173 }
174 }
175 }
176 return ret;
177}
178
179HalResult<void> AidlManagerHalWrapper::triggerSynced(
180 const std::function<void()>& completionCallback) {
181 HalResult<ManagerCapabilities> capabilities = getCapabilities();
182 bool supportsCallback = capabilities.isOk() &&
183 static_cast<int32_t>(capabilities.value() & ManagerCapabilities::TRIGGER_CALLBACK);
Lais Andrade818a2252024-06-24 14:48:14 +0100184 auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
185 : nullptr;
Lais Andrade641248e2024-02-16 17:49:36 +0000186 return HalResultFactory::fromStatus(getHal()->triggerSynced(cb));
Lais Andrade98c97032020-11-17 19:23:01 +0000187}
188
189HalResult<void> AidlManagerHalWrapper::cancelSynced() {
Lais Andrade641248e2024-02-16 17:49:36 +0000190 auto ret = HalResultFactory::fromStatus(getHal()->cancelSynced());
Lais Andrade98c97032020-11-17 19:23:01 +0000191 if (ret.isOk()) {
192 // Force reload of all vibrator controllers that were prepared for a sync operation before.
193 // This will trigger calls to getVibrator(id) on each controller, so they can use the
194 // latest service provided by this manager.
195 std::lock_guard<std::mutex> lock(mVibratorsMutex);
196 for (auto& entry : mVibrators) {
197 entry.second->tryReconnect();
198 }
199 }
200 return ret;
201}
202
Lais Andrade818a2252024-06-24 14:48:14 +0100203std::shared_ptr<Aidl::IVibratorManager> AidlManagerHalWrapper::getHal() {
Lais Andrade98c97032020-11-17 19:23:01 +0000204 std::lock_guard<std::mutex> lock(mHandleMutex);
205 return mHandle;
206}
207
Lais Andrade24b5b8f2020-08-27 15:55:54 +0000208}; // namespace vibrator
209
210}; // namespace android