blob: 9d219ff49e35f16d97451cf0456aad4f435c4d44 [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
70template <typename T>
Lais Andrade9e9fcc92020-04-07 20:13:08 +010071HalResult<T> HalResult<T>::fromStatus(binder::Status status, T data) {
72 if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
73 return HalResult<T>::unsupported();
74 }
75 if (status.isOk()) {
76 return HalResult<T>::ok(data);
77 }
78 return HalResult<T>::failed();
79}
80
81template <typename T>
82HalResult<T> HalResult<T>::fromStatus(V1_0::Status status, T data) {
83 switch (status) {
84 case V1_0::Status::OK:
85 return HalResult<T>::ok(data);
86 case V1_0::Status::UNSUPPORTED_OPERATION:
87 return HalResult<T>::unsupported();
88 default:
89 return HalResult<T>::failed();
90 }
91}
92
93template <typename T>
94template <typename R>
95HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, T data) {
96 return ret.isOk() ? HalResult<T>::ok(data) : HalResult<T>::failed();
97}
98
99template <typename T>
100template <typename R>
101HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, V1_0::Status status, T data) {
102 return ret.isOk() ? HalResult<T>::fromStatus(status, data) : HalResult<T>::failed();
103}
104
105// -------------------------------------------------------------------------------------------------
106
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100107HalResult<void> HalResult<void>::fromStatus(binder::Status status) {
108 if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
109 return HalResult<void>::unsupported();
110 }
111 if (status.isOk()) {
112 return HalResult<void>::ok();
113 }
114 return HalResult<void>::failed();
115}
116
117HalResult<void> HalResult<void>::fromStatus(V1_0::Status status) {
118 switch (status) {
119 case V1_0::Status::OK:
120 return HalResult<void>::ok();
121 case V1_0::Status::UNSUPPORTED_OPERATION:
122 return HalResult<void>::unsupported();
123 default:
124 return HalResult<void>::failed();
125 }
126}
127
128template <typename R>
129HalResult<void> HalResult<void>::fromReturn(hardware::Return<R>& ret) {
130 return ret.isOk() ? HalResult<void>::ok() : HalResult<void>::failed();
131}
132
133// -------------------------------------------------------------------------------------------------
134
135class HalCallbackWrapper : public Aidl::BnVibratorCallback {
136public:
Lais Andrade10d9dc72020-05-20 12:00:49 +0000137 HalCallbackWrapper(std::function<void()> completionCallback)
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100138 : mCompletionCallback(completionCallback) {}
139
140 binder::Status onComplete() override {
141 mCompletionCallback();
142 return binder::Status::ok();
143 }
144
145private:
146 const std::function<void()> mCompletionCallback;
147};
148
149// -------------------------------------------------------------------------------------------------
150
151HalResult<void> AidlHalWrapper::ping() {
Lais Andradecfd81152020-07-01 09:00:26 +0000152 return IInterface::asBinder(getHal())->pingBinder() ? HalResult<void>::ok()
153 : HalResult<void>::failed();
154}
155
156void AidlHalWrapper::tryReconnect() {
157 sp<Aidl::IVibrator> newHandle = checkVintfService<Aidl::IVibrator>();
158 if (newHandle) {
159 std::lock_guard<std::mutex> lock(mHandleMutex);
160 mHandle = std::move(newHandle);
161 }
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100162}
163
164HalResult<void> AidlHalWrapper::on(milliseconds timeout,
165 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000166 HalResult<Capabilities> capabilities = getCapabilities();
167 bool supportsCallback = capabilities.isOk() &&
168 static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
169 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
170
Lais Andradecfd81152020-07-01 09:00:26 +0000171 auto ret = HalResult<void>::fromStatus(getHal()->on(timeout.count(), cb));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000172 if (!supportsCallback && ret.isOk()) {
173 mCallbackScheduler->schedule(completionCallback, timeout);
174 }
175
176 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100177}
178
179HalResult<void> AidlHalWrapper::off() {
Lais Andradecfd81152020-07-01 09:00:26 +0000180 return HalResult<void>::fromStatus(getHal()->off());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100181}
182
183HalResult<void> AidlHalWrapper::setAmplitude(int32_t amplitude) {
184 float convertedAmplitude = static_cast<float>(amplitude) / std::numeric_limits<uint8_t>::max();
Lais Andradecfd81152020-07-01 09:00:26 +0000185 return HalResult<void>::fromStatus(getHal()->setAmplitude(convertedAmplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100186}
187
188HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000189 return HalResult<void>::fromStatus(getHal()->setExternalControl(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100190}
191
192HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
Lais Andradecfd81152020-07-01 09:00:26 +0000193 return HalResult<void>::fromStatus(getHal()->alwaysOnEnable(id, effect, strength));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100194}
195
196HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
Lais Andradecfd81152020-07-01 09:00:26 +0000197 return HalResult<void>::fromStatus(getHal()->alwaysOnDisable(id));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100198}
199
200HalResult<Capabilities> AidlHalWrapper::getCapabilities() {
Lais Andraded39ff7d2020-05-19 10:42:51 +0000201 std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000202 return loadCached<Capabilities>(std::bind(&AidlHalWrapper::getCapabilitiesInternal, this),
203 mCapabilities);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100204}
205
206HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffects() {
Lais Andraded39ff7d2020-05-19 10:42:51 +0000207 std::lock_guard<std::mutex> lock(mSupportedEffectsMutex);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000208 return loadCached<std::vector<Effect>>(std::bind(&AidlHalWrapper::getSupportedEffectsInternal,
209 this),
210 mSupportedEffects);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100211}
212
213HalResult<milliseconds> AidlHalWrapper::performEffect(
214 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000215 HalResult<Capabilities> capabilities = getCapabilities();
216 bool supportsCallback = capabilities.isOk() &&
217 static_cast<int32_t>(capabilities.value() & Capabilities::PERFORM_CALLBACK);
218 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
219
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100220 int32_t lengthMs;
Lais Andradecfd81152020-07-01 09:00:26 +0000221 auto result = getHal()->perform(effect, strength, cb, &lengthMs);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000222 milliseconds length = milliseconds(lengthMs);
223
224 auto ret = HalResult<milliseconds>::fromStatus(result, length);
225 if (!supportsCallback && ret.isOk()) {
226 mCallbackScheduler->schedule(completionCallback, length);
227 }
228
229 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100230}
231
232HalResult<void> AidlHalWrapper::performComposedEffect(
233 const std::vector<CompositeEffect>& primitiveEffects,
234 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000235 // This method should always support callbacks, so no need to double check.
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100236 auto cb = new HalCallbackWrapper(completionCallback);
Lais Andradecfd81152020-07-01 09:00:26 +0000237 return HalResult<void>::fromStatus(getHal()->compose(primitiveEffects, cb));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100238}
239
Lais Andrade10d9dc72020-05-20 12:00:49 +0000240HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
241 int32_t capabilities = 0;
Lais Andradecfd81152020-07-01 09:00:26 +0000242 auto result = getHal()->getCapabilities(&capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000243 return HalResult<Capabilities>::fromStatus(result, static_cast<Capabilities>(capabilities));
244}
245
246HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
247 std::vector<Effect> supportedEffects;
Lais Andradecfd81152020-07-01 09:00:26 +0000248 auto result = getHal()->getSupportedEffects(&supportedEffects);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000249 return HalResult<std::vector<Effect>>::fromStatus(result, supportedEffects);
250}
251
Lais Andradecfd81152020-07-01 09:00:26 +0000252sp<Aidl::IVibrator> AidlHalWrapper::getHal() {
253 std::lock_guard<std::mutex> lock(mHandleMutex);
254 return mHandle;
255}
256
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100257// -------------------------------------------------------------------------------------------------
258
Lais Andradecfd81152020-07-01 09:00:26 +0000259template <typename I>
260HalResult<void> HidlHalWrapper<I>::ping() {
261 auto result = getHal()->ping();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100262 return HalResult<void>::fromReturn(result);
263}
264
Lais Andradecfd81152020-07-01 09:00:26 +0000265template <typename I>
266void HidlHalWrapper<I>::tryReconnect() {
267 sp<I> newHandle = I::tryGetService();
268 if (newHandle) {
269 std::lock_guard<std::mutex> lock(mHandleMutex);
270 mHandle = std::move(newHandle);
271 }
272}
273
274template <typename I>
275HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
276 const std::function<void()>& completionCallback) {
277 auto result = getHal()->on(timeout.count());
Lais Andrade10d9dc72020-05-20 12:00:49 +0000278 auto ret = HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
279 if (ret.isOk()) {
280 mCallbackScheduler->schedule(completionCallback, timeout);
281 }
282 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100283}
284
Lais Andradecfd81152020-07-01 09:00:26 +0000285template <typename I>
286HalResult<void> HidlHalWrapper<I>::off() {
287 auto result = getHal()->off();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100288 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
289}
290
Lais Andradecfd81152020-07-01 09:00:26 +0000291template <typename I>
292HalResult<void> HidlHalWrapper<I>::setAmplitude(int32_t amplitude) {
293 auto result = getHal()->setAmplitude(static_cast<uint8_t>(amplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100294 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
295}
296
Lais Andradecfd81152020-07-01 09:00:26 +0000297template <typename I>
298HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100299 ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
300 return HalResult<void>::unsupported();
301}
302
Lais Andradecfd81152020-07-01 09:00:26 +0000303template <typename I>
304HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100305 ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
306 return HalResult<void>::unsupported();
307}
308
Lais Andradecfd81152020-07-01 09:00:26 +0000309template <typename I>
310HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100311 ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
312 return HalResult<void>::unsupported();
313}
314
Lais Andradecfd81152020-07-01 09:00:26 +0000315template <typename I>
316HalResult<Capabilities> HidlHalWrapper<I>::getCapabilities() {
Lais Andraded39ff7d2020-05-19 10:42:51 +0000317 std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
Lais Andradecfd81152020-07-01 09:00:26 +0000318 return loadCached<Capabilities>(std::bind(&HidlHalWrapper<I>::getCapabilitiesInternal, this),
Lais Andraded39ff7d2020-05-19 10:42:51 +0000319 mCapabilities);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100320}
321
Lais Andradecfd81152020-07-01 09:00:26 +0000322template <typename I>
323HalResult<std::vector<Effect>> HidlHalWrapper<I>::getSupportedEffects() {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100324 ALOGV("Skipped getSupportedEffects because Vibrator HAL AIDL is not available");
325 return HalResult<std::vector<Effect>>::unsupported();
326}
327
Lais Andradecfd81152020-07-01 09:00:26 +0000328template <typename I>
329HalResult<void> HidlHalWrapper<I>::performComposedEffect(const std::vector<CompositeEffect>&,
330 const std::function<void()>&) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100331 ALOGV("Skipped composed effect because Vibrator HAL AIDL is not available");
332 return HalResult<void>::unsupported();
333}
334
Lais Andradecfd81152020-07-01 09:00:26 +0000335template <typename I>
336HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
337 hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
Lais Andraded39ff7d2020-05-19 10:42:51 +0000338 Capabilities capabilities =
339 result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
340 return HalResult<Capabilities>::fromReturn(result, capabilities);
341}
342
Lais Andradecfd81152020-07-01 09:00:26 +0000343template <typename I>
344template <typename T>
345HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
346 perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
Lais Andrade10d9dc72020-05-20 12:00:49 +0000347 const std::function<void()>& completionCallback) {
348 V1_0::Status status;
349 int32_t lengthMs;
350 auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
351 status = retStatus;
352 lengthMs = retLengthMs;
353 };
354
355 V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
356 auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
357 milliseconds length = milliseconds(lengthMs);
358
359 auto ret = HalResult<milliseconds>::fromReturn(result, status, length);
360 if (ret.isOk()) {
361 mCallbackScheduler->schedule(completionCallback, length);
362 }
363
364 return ret;
365}
366
Lais Andradecfd81152020-07-01 09:00:26 +0000367template <typename I>
368sp<I> HidlHalWrapper<I>::getHal() {
369 std::lock_guard<std::mutex> lock(mHandleMutex);
370 return mHandle;
371}
372
373// -------------------------------------------------------------------------------------------------
374
375HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
Lais Andrade10d9dc72020-05-20 12:00:49 +0000376 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andradecfd81152020-07-01 09:00:26 +0000377 if (isStaticCastValid<V1_0::Effect>(effect)) {
378 return performInternal(&V1_0::IVibrator::perform, getHal(),
379 static_cast<V1_0::Effect>(effect), strength, completionCallback);
380 }
381
382 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
383 Aidl::toString(effect).c_str());
384 return HalResult<milliseconds>::unsupported();
Lais Andrade10d9dc72020-05-20 12:00:49 +0000385}
386
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100387// -------------------------------------------------------------------------------------------------
388
Lais Andrade10d9dc72020-05-20 12:00:49 +0000389HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
390 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100391 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000392 return performInternal(&V1_1::IVibrator::perform, getHal(),
393 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100394 }
395 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000396 return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
397 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100398 }
399
400 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
401 Aidl::toString(effect).c_str());
402 return HalResult<milliseconds>::unsupported();
403}
404
405// -------------------------------------------------------------------------------------------------
406
Lais Andrade10d9dc72020-05-20 12:00:49 +0000407HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
408 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100409 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000410 return performInternal(&V1_2::IVibrator::perform, getHal(),
411 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100412 }
413 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000414 return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
415 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100416 }
417 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000418 return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
419 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100420 }
421
422 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
423 Aidl::toString(effect).c_str());
424 return HalResult<milliseconds>::unsupported();
425}
426
427// -------------------------------------------------------------------------------------------------
428
429HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000430 auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100431 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
432}
433
Lais Andrade10d9dc72020-05-20 12:00:49 +0000434HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
435 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100436 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000437 return performInternal(&V1_3::IVibrator::perform, getHal(),
438 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100439 }
440 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000441 return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
442 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100443 }
444 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000445 return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
446 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100447 }
448 if (isStaticCastValid<V1_3::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000449 return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
450 static_cast<V1_3::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100451 }
452
453 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
454 Aidl::toString(effect).c_str());
455 return HalResult<milliseconds>::unsupported();
456}
457
Lais Andraded39ff7d2020-05-19 10:42:51 +0000458HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
Lais Andradecfd81152020-07-01 09:00:26 +0000459 sp<V1_3::IVibrator> hal = getHal();
460 auto amplitudeResult = hal->supportsAmplitudeControl();
461 if (!amplitudeResult.isOk()) {
462 return HalResult<Capabilities>::failed();
Lais Andraded39ff7d2020-05-19 10:42:51 +0000463 }
464
Lais Andradecfd81152020-07-01 09:00:26 +0000465 auto externalControlResult = hal->supportsExternalControl();
466 Capabilities capabilities = Capabilities::NONE;
Lais Andraded39ff7d2020-05-19 10:42:51 +0000467
Lais Andradecfd81152020-07-01 09:00:26 +0000468 if (amplitudeResult.withDefault(false)) {
469 capabilities |= Capabilities::AMPLITUDE_CONTROL;
470 }
471 if (externalControlResult.withDefault(false)) {
472 capabilities |= Capabilities::EXTERNAL_CONTROL;
473 }
474
475 return HalResult<Capabilities>::fromReturn(externalControlResult, capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000476}
477
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100478// -------------------------------------------------------------------------------------------------
479
480}; // namespace vibrator
481
482}; // namespace android