blob: 13412667e039c91a89e401a63fed7524e995b8e7 [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 Andrade98c97032020-11-17 19:23:01 +000023namespace Aidl = android::hardware::vibrator;
24
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 Andrade641248e2024-02-16 17:49:36 +000078 std::function<HalResult<sp<Aidl::IVibrator>>()> reconnectFn = [=, this]() {
Lais Andrade98c97032020-11-17 19:23:01 +000079 sp<Aidl::IVibrator> vibrator;
Lais Andradef20b1442020-11-19 15:14:10 +000080 auto result = this->getHal()->getVibrator(vibratorId, &vibrator);
Lais Andrade641248e2024-02-16 17:49:36 +000081 return HalResultFactory::fromStatus<sp<Aidl::IVibrator>>(result, vibrator);
Lais Andrade98c97032020-11-17 19:23:01 +000082 };
83 auto result = reconnectFn();
84 if (!result.isOk()) {
85 return nullptr;
86 }
87 auto vibrator = result.value();
88 if (!vibrator) {
89 return nullptr;
90 }
Lais Andrade641248e2024-02-16 17:49:36 +000091 return std::make_unique<AidlHalWrapper>(std::move(callbackScheduler), std::move(vibrator),
92 reconnectFn);
Lais Andrade98c97032020-11-17 19:23:01 +000093}
94
95HalResult<void> AidlManagerHalWrapper::ping() {
Lais Andrade641248e2024-02-16 17:49:36 +000096 return HalResultFactory::fromStatus(IInterface::asBinder(getHal())->pingBinder());
Lais Andrade98c97032020-11-17 19:23:01 +000097}
98
99void 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
107HalResult<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);
Lais Andrade641248e2024-02-16 17:49:36 +0000115 auto capabilities = static_cast<ManagerCapabilities>(cap);
116 auto ret = HalResultFactory::fromStatus<ManagerCapabilities>(result, capabilities);
Lais Andrade98c97032020-11-17 19:23:01 +0000117 if (ret.isOk()) {
118 // Cache copy of returned value.
119 mCapabilities.emplace(ret.value());
120 }
121 return ret;
122}
123
124HalResult<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);
Lais Andrade641248e2024-02-16 17:49:36 +0000132 auto ret = HalResultFactory::fromStatus<std::vector<int32_t>>(result, ids);
Lais Andrade98c97032020-11-17 19:23:01 +0000133 if (ret.isOk()) {
134 // Cache copy of returned value and the individual controllers.
135 mVibratorIds.emplace(ret.value());
136 for (auto& id : ids) {
Lais Andradef20b1442020-11-19 15:14:10 +0000137 HalController::Connector connector = [&, id](auto scheduler) {
138 return this->connectToVibrator(id, scheduler);
139 };
140 auto controller = std::make_unique<HalController>(mCallbackScheduler, connector);
Lais Andrade98c97032020-11-17 19:23:01 +0000141 mVibrators[id] = std::move(controller);
142 }
143 }
144 return ret;
145}
146
147HalResult<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 }
Lais Andrade641248e2024-02-16 17:49:36 +0000155 return HalResult<std::shared_ptr<HalController>>::failed(
156 (MISSING_VIBRATOR_MESSAGE_PREFIX + std::to_string(id)).c_str());
Lais Andrade98c97032020-11-17 19:23:01 +0000157}
158
159HalResult<void> AidlManagerHalWrapper::prepareSynced(const std::vector<int32_t>& ids) {
Lais Andrade641248e2024-02-16 17:49:36 +0000160 auto ret = HalResultFactory::fromStatus(getHal()->prepareSynced(ids));
Lais Andrade98c97032020-11-17 19:23:01 +0000161 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
176HalResult<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;
Lais Andrade641248e2024-02-16 17:49:36 +0000182 return HalResultFactory::fromStatus(getHal()->triggerSynced(cb));
Lais Andrade98c97032020-11-17 19:23:01 +0000183}
184
185HalResult<void> AidlManagerHalWrapper::cancelSynced() {
Lais Andrade641248e2024-02-16 17:49:36 +0000186 auto ret = HalResultFactory::fromStatus(getHal()->cancelSynced());
Lais Andrade98c97032020-11-17 19:23:01 +0000187 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
199sp<Aidl::IVibratorManager> AidlManagerHalWrapper::getHal() {
200 std::lock_guard<std::mutex> lock(mHandleMutex);
201 return mHandle;
202}
203
Lais Andrade24b5b8f2020-08-27 15:55:54 +0000204}; // namespace vibrator
205
206}; // namespace android