blob: ee891def1128bb9d0ef20a3d4ee18275d32a373b [file] [log] [blame]
Lais Andrade9e9fcc92020-04-07 20:13:08 +01001/*
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 "VibratorHalWrapper"
18
19#include <android/hardware/vibrator/1.3/IVibrator.h>
20#include <android/hardware/vibrator/BnVibratorCallback.h>
21#include <android/hardware/vibrator/IVibrator.h>
22#include <hardware/vibrator.h>
23
24#include <utils/Log.h>
25
Lais Andrade10d9dc72020-05-20 12:00:49 +000026#include <vibratorservice/VibratorCallbackScheduler.h>
Lais Andrade9e9fcc92020-04-07 20:13:08 +010027#include <vibratorservice/VibratorHalWrapper.h>
28
29using android::hardware::vibrator::CompositeEffect;
30using android::hardware::vibrator::Effect;
31using android::hardware::vibrator::EffectStrength;
32
33using std::chrono::milliseconds;
34
35namespace V1_0 = android::hardware::vibrator::V1_0;
36namespace V1_1 = android::hardware::vibrator::V1_1;
37namespace V1_2 = android::hardware::vibrator::V1_2;
38namespace V1_3 = android::hardware::vibrator::V1_3;
39namespace Aidl = android::hardware::vibrator;
40
41namespace android {
42
43namespace vibrator {
44
45// -------------------------------------------------------------------------------------------------
46
47template <class T>
Lais Andraded39ff7d2020-05-19 10:42:51 +000048HalResult<T> loadCached(const std::function<HalResult<T>()>& loadFn, std::optional<T>& cache) {
49 if (cache.has_value()) {
Lais Andrade10d9dc72020-05-20 12:00:49 +000050 // Return copy of cached value.
51 return HalResult<T>::ok(*cache);
Lais Andraded39ff7d2020-05-19 10:42:51 +000052 }
53 HalResult<T> ret = loadFn();
54 if (ret.isOk()) {
Lais Andrade10d9dc72020-05-20 12:00:49 +000055 // Cache copy of returned value.
Lais Andraded39ff7d2020-05-19 10:42:51 +000056 cache.emplace(ret.value());
57 }
58 return ret;
59}
60
61template <class T>
Lais Andrade9e9fcc92020-04-07 20:13:08 +010062bool isStaticCastValid(Effect effect) {
63 T castEffect = static_cast<T>(effect);
64 auto iter = hardware::hidl_enum_range<T>();
65 return castEffect >= *iter.begin() && castEffect <= *std::prev(iter.end());
66}
67
Lais Andrade9e9fcc92020-04-07 20:13:08 +010068// -------------------------------------------------------------------------------------------------
69
Lais Andrade08666612020-08-07 16:16:31 +000070const constexpr char* STATUS_T_ERROR_MESSAGE_PREFIX = "status_t = ";
71const constexpr char* STATUS_V_1_0_ERROR_MESSAGE_PREFIX =
72 "android::hardware::vibrator::V1_0::Status = ";
73
Lais Andrade9e9fcc92020-04-07 20:13:08 +010074template <typename T>
Lais Andrade9e9fcc92020-04-07 20:13:08 +010075HalResult<T> HalResult<T>::fromStatus(binder::Status status, T data) {
76 if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
77 return HalResult<T>::unsupported();
78 }
79 if (status.isOk()) {
80 return HalResult<T>::ok(data);
81 }
Lais Andrade08666612020-08-07 16:16:31 +000082 return HalResult<T>::failed(std::string(status.toString8().c_str()));
Lais Andrade9e9fcc92020-04-07 20:13:08 +010083}
84
85template <typename T>
86HalResult<T> HalResult<T>::fromStatus(V1_0::Status status, T data) {
87 switch (status) {
88 case V1_0::Status::OK:
89 return HalResult<T>::ok(data);
90 case V1_0::Status::UNSUPPORTED_OPERATION:
91 return HalResult<T>::unsupported();
92 default:
Lais Andrade08666612020-08-07 16:16:31 +000093 return HalResult<T>::failed(STATUS_V_1_0_ERROR_MESSAGE_PREFIX + toString(status));
Lais Andrade9e9fcc92020-04-07 20:13:08 +010094 }
95}
96
97template <typename T>
98template <typename R>
99HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, T data) {
Lais Andrade08666612020-08-07 16:16:31 +0000100 return ret.isOk() ? HalResult<T>::ok(data) : HalResult<T>::failed(ret.description());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100101}
102
103template <typename T>
104template <typename R>
105HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, V1_0::Status status, T data) {
Lais Andrade08666612020-08-07 16:16:31 +0000106 return ret.isOk() ? HalResult<T>::fromStatus(status, data)
107 : HalResult<T>::failed(ret.description());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100108}
109
110// -------------------------------------------------------------------------------------------------
111
Lais Andrade08666612020-08-07 16:16:31 +0000112HalResult<void> HalResult<void>::fromStatus(status_t status) {
113 if (status == android::OK) {
114 return HalResult<void>::ok();
115 }
116 return HalResult<void>::failed(STATUS_T_ERROR_MESSAGE_PREFIX + statusToString(status));
117}
118
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100119HalResult<void> HalResult<void>::fromStatus(binder::Status status) {
120 if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
121 return HalResult<void>::unsupported();
122 }
123 if (status.isOk()) {
124 return HalResult<void>::ok();
125 }
Lais Andrade08666612020-08-07 16:16:31 +0000126 return HalResult<void>::failed(std::string(status.toString8().c_str()));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100127}
128
129HalResult<void> HalResult<void>::fromStatus(V1_0::Status status) {
130 switch (status) {
131 case V1_0::Status::OK:
132 return HalResult<void>::ok();
133 case V1_0::Status::UNSUPPORTED_OPERATION:
134 return HalResult<void>::unsupported();
135 default:
Lais Andrade08666612020-08-07 16:16:31 +0000136 return HalResult<void>::failed(STATUS_V_1_0_ERROR_MESSAGE_PREFIX + toString(status));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100137 }
138}
139
140template <typename R>
141HalResult<void> HalResult<void>::fromReturn(hardware::Return<R>& ret) {
Lais Andrade08666612020-08-07 16:16:31 +0000142 return ret.isOk() ? HalResult<void>::ok() : HalResult<void>::failed(ret.description());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100143}
144
145// -------------------------------------------------------------------------------------------------
146
147class HalCallbackWrapper : public Aidl::BnVibratorCallback {
148public:
Lais Andrade10d9dc72020-05-20 12:00:49 +0000149 HalCallbackWrapper(std::function<void()> completionCallback)
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100150 : mCompletionCallback(completionCallback) {}
151
152 binder::Status onComplete() override {
153 mCompletionCallback();
154 return binder::Status::ok();
155 }
156
157private:
158 const std::function<void()> mCompletionCallback;
159};
160
161// -------------------------------------------------------------------------------------------------
162
163HalResult<void> AidlHalWrapper::ping() {
Lais Andrade08666612020-08-07 16:16:31 +0000164 return HalResult<void>::fromStatus(IInterface::asBinder(getHal())->pingBinder());
Lais Andradecfd81152020-07-01 09:00:26 +0000165}
166
167void AidlHalWrapper::tryReconnect() {
168 sp<Aidl::IVibrator> newHandle = checkVintfService<Aidl::IVibrator>();
169 if (newHandle) {
170 std::lock_guard<std::mutex> lock(mHandleMutex);
171 mHandle = std::move(newHandle);
172 }
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100173}
174
175HalResult<void> AidlHalWrapper::on(milliseconds timeout,
176 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000177 HalResult<Capabilities> capabilities = getCapabilities();
178 bool supportsCallback = capabilities.isOk() &&
179 static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
180 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
181
Lais Andradecfd81152020-07-01 09:00:26 +0000182 auto ret = HalResult<void>::fromStatus(getHal()->on(timeout.count(), cb));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000183 if (!supportsCallback && ret.isOk()) {
184 mCallbackScheduler->schedule(completionCallback, timeout);
185 }
186
187 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100188}
189
190HalResult<void> AidlHalWrapper::off() {
Lais Andradecfd81152020-07-01 09:00:26 +0000191 return HalResult<void>::fromStatus(getHal()->off());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100192}
193
194HalResult<void> AidlHalWrapper::setAmplitude(int32_t amplitude) {
195 float convertedAmplitude = static_cast<float>(amplitude) / std::numeric_limits<uint8_t>::max();
Lais Andradecfd81152020-07-01 09:00:26 +0000196 return HalResult<void>::fromStatus(getHal()->setAmplitude(convertedAmplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100197}
198
199HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000200 return HalResult<void>::fromStatus(getHal()->setExternalControl(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100201}
202
203HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
Lais Andradecfd81152020-07-01 09:00:26 +0000204 return HalResult<void>::fromStatus(getHal()->alwaysOnEnable(id, effect, strength));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100205}
206
207HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
Lais Andradecfd81152020-07-01 09:00:26 +0000208 return HalResult<void>::fromStatus(getHal()->alwaysOnDisable(id));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100209}
210
211HalResult<Capabilities> AidlHalWrapper::getCapabilities() {
Lais Andraded39ff7d2020-05-19 10:42:51 +0000212 std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000213 return loadCached<Capabilities>(std::bind(&AidlHalWrapper::getCapabilitiesInternal, this),
214 mCapabilities);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100215}
216
217HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffects() {
Lais Andraded39ff7d2020-05-19 10:42:51 +0000218 std::lock_guard<std::mutex> lock(mSupportedEffectsMutex);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000219 return loadCached<std::vector<Effect>>(std::bind(&AidlHalWrapper::getSupportedEffectsInternal,
220 this),
221 mSupportedEffects);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100222}
223
224HalResult<milliseconds> AidlHalWrapper::performEffect(
225 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000226 HalResult<Capabilities> capabilities = getCapabilities();
227 bool supportsCallback = capabilities.isOk() &&
228 static_cast<int32_t>(capabilities.value() & Capabilities::PERFORM_CALLBACK);
229 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
230
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100231 int32_t lengthMs;
Lais Andradecfd81152020-07-01 09:00:26 +0000232 auto result = getHal()->perform(effect, strength, cb, &lengthMs);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000233 milliseconds length = milliseconds(lengthMs);
234
235 auto ret = HalResult<milliseconds>::fromStatus(result, length);
236 if (!supportsCallback && ret.isOk()) {
237 mCallbackScheduler->schedule(completionCallback, length);
238 }
239
240 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100241}
242
243HalResult<void> AidlHalWrapper::performComposedEffect(
244 const std::vector<CompositeEffect>& primitiveEffects,
245 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000246 // This method should always support callbacks, so no need to double check.
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100247 auto cb = new HalCallbackWrapper(completionCallback);
Lais Andradecfd81152020-07-01 09:00:26 +0000248 return HalResult<void>::fromStatus(getHal()->compose(primitiveEffects, cb));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100249}
250
Lais Andrade10d9dc72020-05-20 12:00:49 +0000251HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
252 int32_t capabilities = 0;
Lais Andradecfd81152020-07-01 09:00:26 +0000253 auto result = getHal()->getCapabilities(&capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000254 return HalResult<Capabilities>::fromStatus(result, static_cast<Capabilities>(capabilities));
255}
256
257HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
258 std::vector<Effect> supportedEffects;
Lais Andradecfd81152020-07-01 09:00:26 +0000259 auto result = getHal()->getSupportedEffects(&supportedEffects);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000260 return HalResult<std::vector<Effect>>::fromStatus(result, supportedEffects);
261}
262
Lais Andradecfd81152020-07-01 09:00:26 +0000263sp<Aidl::IVibrator> AidlHalWrapper::getHal() {
264 std::lock_guard<std::mutex> lock(mHandleMutex);
265 return mHandle;
266}
267
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100268// -------------------------------------------------------------------------------------------------
269
Lais Andradecfd81152020-07-01 09:00:26 +0000270template <typename I>
271HalResult<void> HidlHalWrapper<I>::ping() {
272 auto result = getHal()->ping();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100273 return HalResult<void>::fromReturn(result);
274}
275
Lais Andradecfd81152020-07-01 09:00:26 +0000276template <typename I>
277void HidlHalWrapper<I>::tryReconnect() {
278 sp<I> newHandle = I::tryGetService();
279 if (newHandle) {
280 std::lock_guard<std::mutex> lock(mHandleMutex);
281 mHandle = std::move(newHandle);
282 }
283}
284
285template <typename I>
286HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
287 const std::function<void()>& completionCallback) {
288 auto result = getHal()->on(timeout.count());
Lais Andrade10d9dc72020-05-20 12:00:49 +0000289 auto ret = HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
290 if (ret.isOk()) {
291 mCallbackScheduler->schedule(completionCallback, timeout);
292 }
293 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100294}
295
Lais Andradecfd81152020-07-01 09:00:26 +0000296template <typename I>
297HalResult<void> HidlHalWrapper<I>::off() {
298 auto result = getHal()->off();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100299 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
300}
301
Lais Andradecfd81152020-07-01 09:00:26 +0000302template <typename I>
303HalResult<void> HidlHalWrapper<I>::setAmplitude(int32_t amplitude) {
304 auto result = getHal()->setAmplitude(static_cast<uint8_t>(amplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100305 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
306}
307
Lais Andradecfd81152020-07-01 09:00:26 +0000308template <typename I>
309HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100310 ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
311 return HalResult<void>::unsupported();
312}
313
Lais Andradecfd81152020-07-01 09:00:26 +0000314template <typename I>
315HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100316 ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
317 return HalResult<void>::unsupported();
318}
319
Lais Andradecfd81152020-07-01 09:00:26 +0000320template <typename I>
321HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100322 ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
323 return HalResult<void>::unsupported();
324}
325
Lais Andradecfd81152020-07-01 09:00:26 +0000326template <typename I>
327HalResult<Capabilities> HidlHalWrapper<I>::getCapabilities() {
Lais Andraded39ff7d2020-05-19 10:42:51 +0000328 std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
Lais Andradecfd81152020-07-01 09:00:26 +0000329 return loadCached<Capabilities>(std::bind(&HidlHalWrapper<I>::getCapabilitiesInternal, this),
Lais Andraded39ff7d2020-05-19 10:42:51 +0000330 mCapabilities);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100331}
332
Lais Andradecfd81152020-07-01 09:00:26 +0000333template <typename I>
334HalResult<std::vector<Effect>> HidlHalWrapper<I>::getSupportedEffects() {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100335 ALOGV("Skipped getSupportedEffects because Vibrator HAL AIDL is not available");
336 return HalResult<std::vector<Effect>>::unsupported();
337}
338
Lais Andradecfd81152020-07-01 09:00:26 +0000339template <typename I>
340HalResult<void> HidlHalWrapper<I>::performComposedEffect(const std::vector<CompositeEffect>&,
341 const std::function<void()>&) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100342 ALOGV("Skipped composed effect because Vibrator HAL AIDL is not available");
343 return HalResult<void>::unsupported();
344}
345
Lais Andradecfd81152020-07-01 09:00:26 +0000346template <typename I>
347HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
348 hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
Lais Andraded39ff7d2020-05-19 10:42:51 +0000349 Capabilities capabilities =
350 result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
351 return HalResult<Capabilities>::fromReturn(result, capabilities);
352}
353
Lais Andradecfd81152020-07-01 09:00:26 +0000354template <typename I>
355template <typename T>
356HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
357 perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
Lais Andrade10d9dc72020-05-20 12:00:49 +0000358 const std::function<void()>& completionCallback) {
359 V1_0::Status status;
360 int32_t lengthMs;
361 auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
362 status = retStatus;
363 lengthMs = retLengthMs;
364 };
365
366 V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
367 auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
368 milliseconds length = milliseconds(lengthMs);
369
370 auto ret = HalResult<milliseconds>::fromReturn(result, status, length);
371 if (ret.isOk()) {
372 mCallbackScheduler->schedule(completionCallback, length);
373 }
374
375 return ret;
376}
377
Lais Andradecfd81152020-07-01 09:00:26 +0000378template <typename I>
379sp<I> HidlHalWrapper<I>::getHal() {
380 std::lock_guard<std::mutex> lock(mHandleMutex);
381 return mHandle;
382}
383
384// -------------------------------------------------------------------------------------------------
385
386HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
Lais Andrade10d9dc72020-05-20 12:00:49 +0000387 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andradecfd81152020-07-01 09:00:26 +0000388 if (isStaticCastValid<V1_0::Effect>(effect)) {
389 return performInternal(&V1_0::IVibrator::perform, getHal(),
390 static_cast<V1_0::Effect>(effect), strength, completionCallback);
391 }
392
393 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
394 Aidl::toString(effect).c_str());
395 return HalResult<milliseconds>::unsupported();
Lais Andrade10d9dc72020-05-20 12:00:49 +0000396}
397
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100398// -------------------------------------------------------------------------------------------------
399
Lais Andrade10d9dc72020-05-20 12:00:49 +0000400HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
401 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100402 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000403 return performInternal(&V1_1::IVibrator::perform, getHal(),
404 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100405 }
406 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000407 return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
408 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100409 }
410
411 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
412 Aidl::toString(effect).c_str());
413 return HalResult<milliseconds>::unsupported();
414}
415
416// -------------------------------------------------------------------------------------------------
417
Lais Andrade10d9dc72020-05-20 12:00:49 +0000418HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
419 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100420 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000421 return performInternal(&V1_2::IVibrator::perform, getHal(),
422 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100423 }
424 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000425 return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
426 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100427 }
428 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000429 return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
430 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100431 }
432
433 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
434 Aidl::toString(effect).c_str());
435 return HalResult<milliseconds>::unsupported();
436}
437
438// -------------------------------------------------------------------------------------------------
439
440HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000441 auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100442 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
443}
444
Lais Andrade10d9dc72020-05-20 12:00:49 +0000445HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
446 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100447 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000448 return performInternal(&V1_3::IVibrator::perform, getHal(),
449 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100450 }
451 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000452 return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
453 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100454 }
455 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000456 return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
457 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100458 }
459 if (isStaticCastValid<V1_3::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000460 return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
461 static_cast<V1_3::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100462 }
463
464 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
465 Aidl::toString(effect).c_str());
466 return HalResult<milliseconds>::unsupported();
467}
468
Lais Andraded39ff7d2020-05-19 10:42:51 +0000469HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
Lais Andrade08666612020-08-07 16:16:31 +0000470 Capabilities capabilities = Capabilities::NONE;
471
Lais Andradecfd81152020-07-01 09:00:26 +0000472 sp<V1_3::IVibrator> hal = getHal();
473 auto amplitudeResult = hal->supportsAmplitudeControl();
474 if (!amplitudeResult.isOk()) {
Lais Andrade08666612020-08-07 16:16:31 +0000475 return HalResult<Capabilities>::fromReturn(amplitudeResult, capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000476 }
477
Lais Andradecfd81152020-07-01 09:00:26 +0000478 auto externalControlResult = hal->supportsExternalControl();
Lais Andradecfd81152020-07-01 09:00:26 +0000479 if (amplitudeResult.withDefault(false)) {
480 capabilities |= Capabilities::AMPLITUDE_CONTROL;
481 }
482 if (externalControlResult.withDefault(false)) {
483 capabilities |= Capabilities::EXTERNAL_CONTROL;
484 }
485
486 return HalResult<Capabilities>::fromReturn(externalControlResult, capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000487}
488
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100489// -------------------------------------------------------------------------------------------------
490
491}; // namespace vibrator
492
493}; // namespace android