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