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 "VibratorHalWrapper"
18
19 #include <android/hardware/vibrator/1.3/IVibrator.h>
20 #include <android/hardware/vibrator/IVibrator.h>
21 #include <hardware/vibrator.h>
22 #include <cmath>
23
24 #include <utils/Log.h>
25
26 #include <vibratorservice/VibratorCallbackScheduler.h>
27 #include <vibratorservice/VibratorHalWrapper.h>
28
29 using android::hardware::vibrator::Braking;
30 using android::hardware::vibrator::CompositeEffect;
31 using android::hardware::vibrator::CompositePrimitive;
32 using android::hardware::vibrator::Effect;
33 using android::hardware::vibrator::EffectStrength;
34 using android::hardware::vibrator::PrimitivePwle;
35
36 using std::chrono::milliseconds;
37
38 namespace V1_0 = android::hardware::vibrator::V1_0;
39 namespace V1_1 = android::hardware::vibrator::V1_1;
40 namespace V1_2 = android::hardware::vibrator::V1_2;
41 namespace V1_3 = android::hardware::vibrator::V1_3;
42 namespace Aidl = android::hardware::vibrator;
43
44 namespace android {
45
46 namespace vibrator {
47
48 // -------------------------------------------------------------------------------------------------
49
50 template <class T>
isStaticCastValid(Effect effect)51 bool isStaticCastValid(Effect effect) {
52 T castEffect = static_cast<T>(effect);
53 auto iter = hardware::hidl_enum_range<T>();
54 return castEffect >= *iter.begin() && castEffect <= *std::prev(iter.end());
55 }
56
57 // -------------------------------------------------------------------------------------------------
58
59 const constexpr char* STATUS_T_ERROR_MESSAGE_PREFIX = "status_t = ";
60 const constexpr char* STATUS_V_1_0_ERROR_MESSAGE_PREFIX =
61 "android::hardware::vibrator::V1_0::Status = ";
62
63 template <typename T>
fromStatus(V1_0::Status status,T data)64 HalResult<T> HalResult<T>::fromStatus(V1_0::Status status, T data) {
65 switch (status) {
66 case V1_0::Status::OK:
67 return HalResult<T>::ok(data);
68 case V1_0::Status::UNSUPPORTED_OPERATION:
69 return HalResult<T>::unsupported();
70 default:
71 return HalResult<T>::failed(STATUS_V_1_0_ERROR_MESSAGE_PREFIX + toString(status));
72 }
73 }
74
75 template <typename T>
76 template <typename R>
fromReturn(hardware::Return<R> & ret,T data)77 HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, T data) {
78 return ret.isOk() ? HalResult<T>::ok(data) : HalResult<T>::failed(ret.description());
79 }
80
81 template <typename T>
82 template <typename R>
fromReturn(hardware::Return<R> & ret,V1_0::Status status,T data)83 HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, V1_0::Status status, T data) {
84 return ret.isOk() ? HalResult<T>::fromStatus(status, data)
85 : HalResult<T>::failed(ret.description());
86 }
87
88 // -------------------------------------------------------------------------------------------------
89
fromStatus(status_t status)90 HalResult<void> HalResult<void>::fromStatus(status_t status) {
91 if (status == android::OK) {
92 return HalResult<void>::ok();
93 }
94 return HalResult<void>::failed(STATUS_T_ERROR_MESSAGE_PREFIX + statusToString(status));
95 }
96
fromStatus(binder::Status status)97 HalResult<void> HalResult<void>::fromStatus(binder::Status status) {
98 if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION ||
99 status.transactionError() == android::UNKNOWN_TRANSACTION) {
100 // UNKNOWN_TRANSACTION means the HAL implementation is an older version, so this is
101 // the same as the operation being unsupported by this HAL. Should not retry.
102 return HalResult<void>::unsupported();
103 }
104 if (status.isOk()) {
105 return HalResult<void>::ok();
106 }
107 return HalResult<void>::failed(std::string(status.toString8().c_str()));
108 }
109
fromStatus(V1_0::Status status)110 HalResult<void> HalResult<void>::fromStatus(V1_0::Status status) {
111 switch (status) {
112 case V1_0::Status::OK:
113 return HalResult<void>::ok();
114 case V1_0::Status::UNSUPPORTED_OPERATION:
115 return HalResult<void>::unsupported();
116 default:
117 return HalResult<void>::failed(STATUS_V_1_0_ERROR_MESSAGE_PREFIX + toString(status));
118 }
119 }
120
121 template <typename R>
fromReturn(hardware::Return<R> & ret)122 HalResult<void> HalResult<void>::fromReturn(hardware::Return<R>& ret) {
123 return ret.isOk() ? HalResult<void>::ok() : HalResult<void>::failed(ret.description());
124 }
125
126 // -------------------------------------------------------------------------------------------------
127
getInfo()128 Info HalWrapper::getInfo() {
129 getCapabilities();
130 getPrimitiveDurations();
131 std::lock_guard<std::mutex> lock(mInfoMutex);
132 if (mInfoCache.mSupportedEffects.isFailed()) {
133 mInfoCache.mSupportedEffects = getSupportedEffectsInternal();
134 }
135 if (mInfoCache.mSupportedBraking.isFailed()) {
136 mInfoCache.mSupportedBraking = getSupportedBrakingInternal();
137 }
138 if (mInfoCache.mPrimitiveDelayMax.isFailed()) {
139 mInfoCache.mPrimitiveDelayMax = getPrimitiveDelayMaxInternal();
140 }
141 if (mInfoCache.mPwlePrimitiveDurationMax.isFailed()) {
142 mInfoCache.mPwlePrimitiveDurationMax = getPrimitiveDurationMaxInternal();
143 }
144 if (mInfoCache.mCompositionSizeMax.isFailed()) {
145 mInfoCache.mCompositionSizeMax = getCompositionSizeMaxInternal();
146 }
147 if (mInfoCache.mPwleSizeMax.isFailed()) {
148 mInfoCache.mPwleSizeMax = getPwleSizeMaxInternal();
149 }
150 if (mInfoCache.mMinFrequency.isFailed()) {
151 mInfoCache.mMinFrequency = getMinFrequencyInternal();
152 }
153 if (mInfoCache.mResonantFrequency.isFailed()) {
154 mInfoCache.mResonantFrequency = getResonantFrequencyInternal();
155 }
156 if (mInfoCache.mFrequencyResolution.isFailed()) {
157 mInfoCache.mFrequencyResolution = getFrequencyResolutionInternal();
158 }
159 if (mInfoCache.mQFactor.isFailed()) {
160 mInfoCache.mQFactor = getQFactorInternal();
161 }
162 if (mInfoCache.mMaxAmplitudes.isFailed()) {
163 mInfoCache.mMaxAmplitudes = getMaxAmplitudesInternal();
164 }
165 return mInfoCache.get();
166 }
167
performComposedEffect(const std::vector<CompositeEffect> &,const std::function<void ()> &)168 HalResult<milliseconds> HalWrapper::performComposedEffect(const std::vector<CompositeEffect>&,
169 const std::function<void()>&) {
170 ALOGV("Skipped performComposedEffect because it's not available in Vibrator HAL");
171 return HalResult<milliseconds>::unsupported();
172 }
173
performPwleEffect(const std::vector<PrimitivePwle> &,const std::function<void ()> &)174 HalResult<void> HalWrapper::performPwleEffect(const std::vector<PrimitivePwle>&,
175 const std::function<void()>&) {
176 ALOGV("Skipped performPwleEffect because it's not available in Vibrator HAL");
177 return HalResult<void>::unsupported();
178 }
179
getCapabilities()180 HalResult<Capabilities> HalWrapper::getCapabilities() {
181 std::lock_guard<std::mutex> lock(mInfoMutex);
182 if (mInfoCache.mCapabilities.isFailed()) {
183 mInfoCache.mCapabilities = getCapabilitiesInternal();
184 }
185 return mInfoCache.mCapabilities;
186 }
187
getPrimitiveDurations()188 HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurations() {
189 std::lock_guard<std::mutex> lock(mInfoMutex);
190 if (mInfoCache.mSupportedPrimitives.isFailed()) {
191 mInfoCache.mSupportedPrimitives = getSupportedPrimitivesInternal();
192 if (mInfoCache.mSupportedPrimitives.isUnsupported()) {
193 mInfoCache.mPrimitiveDurations = HalResult<std::vector<milliseconds>>::unsupported();
194 }
195 }
196 if (mInfoCache.mPrimitiveDurations.isFailed() && mInfoCache.mSupportedPrimitives.isOk()) {
197 mInfoCache.mPrimitiveDurations =
198 getPrimitiveDurationsInternal(mInfoCache.mSupportedPrimitives.value());
199 }
200 return mInfoCache.mPrimitiveDurations;
201 }
202
getSupportedEffectsInternal()203 HalResult<std::vector<Effect>> HalWrapper::getSupportedEffectsInternal() {
204 ALOGV("Skipped getSupportedEffects because it's not available in Vibrator HAL");
205 return HalResult<std::vector<Effect>>::unsupported();
206 }
207
getSupportedBrakingInternal()208 HalResult<std::vector<Braking>> HalWrapper::getSupportedBrakingInternal() {
209 ALOGV("Skipped getSupportedBraking because it's not available in Vibrator HAL");
210 return HalResult<std::vector<Braking>>::unsupported();
211 }
212
getSupportedPrimitivesInternal()213 HalResult<std::vector<CompositePrimitive>> HalWrapper::getSupportedPrimitivesInternal() {
214 ALOGV("Skipped getSupportedPrimitives because it's not available in Vibrator HAL");
215 return HalResult<std::vector<CompositePrimitive>>::unsupported();
216 }
217
getPrimitiveDurationsInternal(const std::vector<CompositePrimitive> &)218 HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurationsInternal(
219 const std::vector<CompositePrimitive>&) {
220 ALOGV("Skipped getPrimitiveDurations because it's not available in Vibrator HAL");
221 return HalResult<std::vector<milliseconds>>::unsupported();
222 }
223
getPrimitiveDelayMaxInternal()224 HalResult<milliseconds> HalWrapper::getPrimitiveDelayMaxInternal() {
225 ALOGV("Skipped getPrimitiveDelayMaxInternal because it's not available in Vibrator HAL");
226 return HalResult<milliseconds>::unsupported();
227 }
228
getPrimitiveDurationMaxInternal()229 HalResult<milliseconds> HalWrapper::getPrimitiveDurationMaxInternal() {
230 ALOGV("Skipped getPrimitiveDurationMaxInternal because it's not available in Vibrator HAL");
231 return HalResult<milliseconds>::unsupported();
232 }
233
getCompositionSizeMaxInternal()234 HalResult<int32_t> HalWrapper::getCompositionSizeMaxInternal() {
235 ALOGV("Skipped getCompositionSizeMaxInternal because it's not available in Vibrator HAL");
236 return HalResult<int32_t>::unsupported();
237 }
238
getPwleSizeMaxInternal()239 HalResult<int32_t> HalWrapper::getPwleSizeMaxInternal() {
240 ALOGV("Skipped getPwleSizeMaxInternal because it's not available in Vibrator HAL");
241 return HalResult<int32_t>::unsupported();
242 }
243
getMinFrequencyInternal()244 HalResult<float> HalWrapper::getMinFrequencyInternal() {
245 ALOGV("Skipped getMinFrequency because it's not available in Vibrator HAL");
246 return HalResult<float>::unsupported();
247 }
248
getResonantFrequencyInternal()249 HalResult<float> HalWrapper::getResonantFrequencyInternal() {
250 ALOGV("Skipped getResonantFrequency because it's not available in Vibrator HAL");
251 return HalResult<float>::unsupported();
252 }
253
getFrequencyResolutionInternal()254 HalResult<float> HalWrapper::getFrequencyResolutionInternal() {
255 ALOGV("Skipped getFrequencyResolution because it's not available in Vibrator HAL");
256 return HalResult<float>::unsupported();
257 }
258
getQFactorInternal()259 HalResult<float> HalWrapper::getQFactorInternal() {
260 ALOGV("Skipped getQFactor because it's not available in Vibrator HAL");
261 return HalResult<float>::unsupported();
262 }
263
getMaxAmplitudesInternal()264 HalResult<std::vector<float>> HalWrapper::getMaxAmplitudesInternal() {
265 ALOGV("Skipped getMaxAmplitudes because it's not available in Vibrator HAL");
266 return HalResult<std::vector<float>>::unsupported();
267 }
268
269 // -------------------------------------------------------------------------------------------------
270
ping()271 HalResult<void> AidlHalWrapper::ping() {
272 return HalResult<void>::fromStatus(IInterface::asBinder(getHal())->pingBinder());
273 }
274
tryReconnect()275 void AidlHalWrapper::tryReconnect() {
276 auto result = mReconnectFn();
277 if (!result.isOk()) {
278 return;
279 }
280 sp<Aidl::IVibrator> newHandle = result.value();
281 if (newHandle) {
282 std::lock_guard<std::mutex> lock(mHandleMutex);
283 mHandle = std::move(newHandle);
284 }
285 }
286
on(milliseconds timeout,const std::function<void ()> & completionCallback)287 HalResult<void> AidlHalWrapper::on(milliseconds timeout,
288 const std::function<void()>& completionCallback) {
289 HalResult<Capabilities> capabilities = getCapabilities();
290 bool supportsCallback = capabilities.isOk() &&
291 static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
292 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
293
294 auto ret = HalResult<void>::fromStatus(getHal()->on(timeout.count(), cb));
295 if (!supportsCallback && ret.isOk()) {
296 mCallbackScheduler->schedule(completionCallback, timeout);
297 }
298
299 return ret;
300 }
301
off()302 HalResult<void> AidlHalWrapper::off() {
303 return HalResult<void>::fromStatus(getHal()->off());
304 }
305
setAmplitude(float amplitude)306 HalResult<void> AidlHalWrapper::setAmplitude(float amplitude) {
307 return HalResult<void>::fromStatus(getHal()->setAmplitude(amplitude));
308 }
309
setExternalControl(bool enabled)310 HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
311 return HalResult<void>::fromStatus(getHal()->setExternalControl(enabled));
312 }
313
alwaysOnEnable(int32_t id,Effect effect,EffectStrength strength)314 HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
315 return HalResult<void>::fromStatus(getHal()->alwaysOnEnable(id, effect, strength));
316 }
317
alwaysOnDisable(int32_t id)318 HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
319 return HalResult<void>::fromStatus(getHal()->alwaysOnDisable(id));
320 }
321
performEffect(Effect effect,EffectStrength strength,const std::function<void ()> & completionCallback)322 HalResult<milliseconds> AidlHalWrapper::performEffect(
323 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
324 HalResult<Capabilities> capabilities = getCapabilities();
325 bool supportsCallback = capabilities.isOk() &&
326 static_cast<int32_t>(capabilities.value() & Capabilities::PERFORM_CALLBACK);
327 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
328
329 int32_t lengthMs;
330 auto result = getHal()->perform(effect, strength, cb, &lengthMs);
331 milliseconds length = milliseconds(lengthMs);
332
333 auto ret = HalResult<milliseconds>::fromStatus(result, length);
334 if (!supportsCallback && ret.isOk()) {
335 mCallbackScheduler->schedule(completionCallback, length);
336 }
337
338 return ret;
339 }
340
performComposedEffect(const std::vector<CompositeEffect> & primitives,const std::function<void ()> & completionCallback)341 HalResult<milliseconds> AidlHalWrapper::performComposedEffect(
342 const std::vector<CompositeEffect>& primitives,
343 const std::function<void()>& completionCallback) {
344 // This method should always support callbacks, so no need to double check.
345 auto cb = new HalCallbackWrapper(completionCallback);
346
347 auto durations = getPrimitiveDurations().valueOr({});
348 milliseconds duration(0);
349 for (const auto& effect : primitives) {
350 auto primitiveIdx = static_cast<size_t>(effect.primitive);
351 if (primitiveIdx < durations.size()) {
352 duration += durations[primitiveIdx];
353 } else {
354 // Make sure the returned duration is positive to indicate successful vibration.
355 duration += milliseconds(1);
356 }
357 duration += milliseconds(effect.delayMs);
358 }
359
360 return HalResult<milliseconds>::fromStatus(getHal()->compose(primitives, cb), duration);
361 }
362
performPwleEffect(const std::vector<PrimitivePwle> & primitives,const std::function<void ()> & completionCallback)363 HalResult<void> AidlHalWrapper::performPwleEffect(const std::vector<PrimitivePwle>& primitives,
364 const std::function<void()>& completionCallback) {
365 // This method should always support callbacks, so no need to double check.
366 auto cb = new HalCallbackWrapper(completionCallback);
367 return HalResult<void>::fromStatus(getHal()->composePwle(primitives, cb));
368 }
369
getCapabilitiesInternal()370 HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
371 int32_t capabilities = 0;
372 auto result = getHal()->getCapabilities(&capabilities);
373 return HalResult<Capabilities>::fromStatus(result, static_cast<Capabilities>(capabilities));
374 }
375
getSupportedEffectsInternal()376 HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
377 std::vector<Effect> supportedEffects;
378 auto result = getHal()->getSupportedEffects(&supportedEffects);
379 return HalResult<std::vector<Effect>>::fromStatus(result, supportedEffects);
380 }
381
getSupportedBrakingInternal()382 HalResult<std::vector<Braking>> AidlHalWrapper::getSupportedBrakingInternal() {
383 std::vector<Braking> supportedBraking;
384 auto result = getHal()->getSupportedBraking(&supportedBraking);
385 return HalResult<std::vector<Braking>>::fromStatus(result, supportedBraking);
386 }
387
getSupportedPrimitivesInternal()388 HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() {
389 std::vector<CompositePrimitive> supportedPrimitives;
390 auto result = getHal()->getSupportedPrimitives(&supportedPrimitives);
391 return HalResult<std::vector<CompositePrimitive>>::fromStatus(result, supportedPrimitives);
392 }
393
getPrimitiveDurationsInternal(const std::vector<CompositePrimitive> & supportedPrimitives)394 HalResult<std::vector<milliseconds>> AidlHalWrapper::getPrimitiveDurationsInternal(
395 const std::vector<CompositePrimitive>& supportedPrimitives) {
396 std::vector<milliseconds> durations;
397 constexpr auto primitiveRange = enum_range<CompositePrimitive>();
398 constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
399 durations.resize(primitiveCount);
400
401 for (auto primitive : supportedPrimitives) {
402 auto primitiveIdx = static_cast<size_t>(primitive);
403 if (primitiveIdx >= durations.size()) {
404 // Safety check, should not happen if enum_range is correct.
405 continue;
406 }
407 int32_t duration = 0;
408 auto status = getHal()->getPrimitiveDuration(primitive, &duration);
409 if (!status.isOk()) {
410 return HalResult<std::vector<milliseconds>>::failed(status.toString8().c_str());
411 }
412 durations[primitiveIdx] = milliseconds(duration);
413 }
414
415 return HalResult<std::vector<milliseconds>>::ok(durations);
416 }
417
getPrimitiveDelayMaxInternal()418 HalResult<milliseconds> AidlHalWrapper::getPrimitiveDelayMaxInternal() {
419 int32_t delay = 0;
420 auto result = getHal()->getCompositionDelayMax(&delay);
421 return HalResult<milliseconds>::fromStatus(result, milliseconds(delay));
422 }
423
getPrimitiveDurationMaxInternal()424 HalResult<milliseconds> AidlHalWrapper::getPrimitiveDurationMaxInternal() {
425 int32_t delay = 0;
426 auto result = getHal()->getPwlePrimitiveDurationMax(&delay);
427 return HalResult<milliseconds>::fromStatus(result, milliseconds(delay));
428 }
429
getCompositionSizeMaxInternal()430 HalResult<int32_t> AidlHalWrapper::getCompositionSizeMaxInternal() {
431 int32_t size = 0;
432 auto result = getHal()->getCompositionSizeMax(&size);
433 return HalResult<int32_t>::fromStatus(result, size);
434 }
435
getPwleSizeMaxInternal()436 HalResult<int32_t> AidlHalWrapper::getPwleSizeMaxInternal() {
437 int32_t size = 0;
438 auto result = getHal()->getPwleCompositionSizeMax(&size);
439 return HalResult<int32_t>::fromStatus(result, size);
440 }
441
getMinFrequencyInternal()442 HalResult<float> AidlHalWrapper::getMinFrequencyInternal() {
443 float minFrequency = 0;
444 auto result = getHal()->getFrequencyMinimum(&minFrequency);
445 return HalResult<float>::fromStatus(result, minFrequency);
446 }
447
getResonantFrequencyInternal()448 HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() {
449 float f0 = 0;
450 auto result = getHal()->getResonantFrequency(&f0);
451 return HalResult<float>::fromStatus(result, f0);
452 }
453
getFrequencyResolutionInternal()454 HalResult<float> AidlHalWrapper::getFrequencyResolutionInternal() {
455 float frequencyResolution = 0;
456 auto result = getHal()->getFrequencyResolution(&frequencyResolution);
457 return HalResult<float>::fromStatus(result, frequencyResolution);
458 }
459
getQFactorInternal()460 HalResult<float> AidlHalWrapper::getQFactorInternal() {
461 float qFactor = 0;
462 auto result = getHal()->getQFactor(&qFactor);
463 return HalResult<float>::fromStatus(result, qFactor);
464 }
465
getMaxAmplitudesInternal()466 HalResult<std::vector<float>> AidlHalWrapper::getMaxAmplitudesInternal() {
467 std::vector<float> amplitudes;
468 auto result = getHal()->getBandwidthAmplitudeMap(&litudes);
469 return HalResult<std::vector<float>>::fromStatus(result, amplitudes);
470 }
471
getHal()472 sp<Aidl::IVibrator> AidlHalWrapper::getHal() {
473 std::lock_guard<std::mutex> lock(mHandleMutex);
474 return mHandle;
475 }
476
477 // -------------------------------------------------------------------------------------------------
478
479 template <typename I>
ping()480 HalResult<void> HidlHalWrapper<I>::ping() {
481 auto result = getHal()->ping();
482 return HalResult<void>::fromReturn(result);
483 }
484
485 template <typename I>
tryReconnect()486 void HidlHalWrapper<I>::tryReconnect() {
487 sp<I> newHandle = I::tryGetService();
488 if (newHandle) {
489 std::lock_guard<std::mutex> lock(mHandleMutex);
490 mHandle = std::move(newHandle);
491 }
492 }
493
494 template <typename I>
on(milliseconds timeout,const std::function<void ()> & completionCallback)495 HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
496 const std::function<void()>& completionCallback) {
497 auto result = getHal()->on(timeout.count());
498 auto ret = HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
499 if (ret.isOk()) {
500 mCallbackScheduler->schedule(completionCallback, timeout);
501 }
502 return ret;
503 }
504
505 template <typename I>
off()506 HalResult<void> HidlHalWrapper<I>::off() {
507 auto result = getHal()->off();
508 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
509 }
510
511 template <typename I>
setAmplitude(float amplitude)512 HalResult<void> HidlHalWrapper<I>::setAmplitude(float amplitude) {
513 uint8_t amp = static_cast<uint8_t>(amplitude * std::numeric_limits<uint8_t>::max());
514 auto result = getHal()->setAmplitude(amp);
515 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
516 }
517
518 template <typename I>
setExternalControl(bool)519 HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
520 ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
521 return HalResult<void>::unsupported();
522 }
523
524 template <typename I>
alwaysOnEnable(int32_t,Effect,EffectStrength)525 HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
526 ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
527 return HalResult<void>::unsupported();
528 }
529
530 template <typename I>
alwaysOnDisable(int32_t)531 HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
532 ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
533 return HalResult<void>::unsupported();
534 }
535
536 template <typename I>
getCapabilitiesInternal()537 HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
538 hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
539 Capabilities capabilities =
540 result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
541 return HalResult<Capabilities>::fromReturn(result, capabilities);
542 }
543
544 template <typename I>
545 template <typename T>
performInternal(perform_fn<T> performFn,sp<I> handle,T effect,EffectStrength strength,const std::function<void ()> & completionCallback)546 HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
547 perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
548 const std::function<void()>& completionCallback) {
549 V1_0::Status status;
550 int32_t lengthMs;
551 auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
552 status = retStatus;
553 lengthMs = retLengthMs;
554 };
555
556 V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
557 auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
558 milliseconds length = milliseconds(lengthMs);
559
560 auto ret = HalResult<milliseconds>::fromReturn(result, status, length);
561 if (ret.isOk()) {
562 mCallbackScheduler->schedule(completionCallback, length);
563 }
564
565 return ret;
566 }
567
568 template <typename I>
getHal()569 sp<I> HidlHalWrapper<I>::getHal() {
570 std::lock_guard<std::mutex> lock(mHandleMutex);
571 return mHandle;
572 }
573
574 // -------------------------------------------------------------------------------------------------
575
performEffect(Effect effect,EffectStrength strength,const std::function<void ()> & completionCallback)576 HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
577 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
578 if (isStaticCastValid<V1_0::Effect>(effect)) {
579 return performInternal(&V1_0::IVibrator::perform, getHal(),
580 static_cast<V1_0::Effect>(effect), strength, completionCallback);
581 }
582
583 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
584 Aidl::toString(effect).c_str());
585 return HalResult<milliseconds>::unsupported();
586 }
587
588 // -------------------------------------------------------------------------------------------------
589
performEffect(Effect effect,EffectStrength strength,const std::function<void ()> & completionCallback)590 HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
591 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
592 if (isStaticCastValid<V1_0::Effect>(effect)) {
593 return performInternal(&V1_1::IVibrator::perform, getHal(),
594 static_cast<V1_0::Effect>(effect), strength, completionCallback);
595 }
596 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
597 return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
598 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
599 }
600
601 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
602 Aidl::toString(effect).c_str());
603 return HalResult<milliseconds>::unsupported();
604 }
605
606 // -------------------------------------------------------------------------------------------------
607
performEffect(Effect effect,EffectStrength strength,const std::function<void ()> & completionCallback)608 HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
609 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
610 if (isStaticCastValid<V1_0::Effect>(effect)) {
611 return performInternal(&V1_2::IVibrator::perform, getHal(),
612 static_cast<V1_0::Effect>(effect), strength, completionCallback);
613 }
614 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
615 return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
616 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
617 }
618 if (isStaticCastValid<V1_2::Effect>(effect)) {
619 return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
620 static_cast<V1_2::Effect>(effect), strength, completionCallback);
621 }
622
623 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
624 Aidl::toString(effect).c_str());
625 return HalResult<milliseconds>::unsupported();
626 }
627
628 // -------------------------------------------------------------------------------------------------
629
setExternalControl(bool enabled)630 HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
631 auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
632 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
633 }
634
performEffect(Effect effect,EffectStrength strength,const std::function<void ()> & completionCallback)635 HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
636 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
637 if (isStaticCastValid<V1_0::Effect>(effect)) {
638 return performInternal(&V1_3::IVibrator::perform, getHal(),
639 static_cast<V1_0::Effect>(effect), strength, completionCallback);
640 }
641 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
642 return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
643 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
644 }
645 if (isStaticCastValid<V1_2::Effect>(effect)) {
646 return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
647 static_cast<V1_2::Effect>(effect), strength, completionCallback);
648 }
649 if (isStaticCastValid<V1_3::Effect>(effect)) {
650 return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
651 static_cast<V1_3::Effect>(effect), strength, completionCallback);
652 }
653
654 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
655 Aidl::toString(effect).c_str());
656 return HalResult<milliseconds>::unsupported();
657 }
658
getCapabilitiesInternal()659 HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
660 Capabilities capabilities = Capabilities::NONE;
661
662 sp<V1_3::IVibrator> hal = getHal();
663 auto amplitudeResult = hal->supportsAmplitudeControl();
664 if (!amplitudeResult.isOk()) {
665 return HalResult<Capabilities>::fromReturn(amplitudeResult, capabilities);
666 }
667
668 auto externalControlResult = hal->supportsExternalControl();
669 if (amplitudeResult.withDefault(false)) {
670 capabilities |= Capabilities::AMPLITUDE_CONTROL;
671 }
672 if (externalControlResult.withDefault(false)) {
673 capabilities |= Capabilities::EXTERNAL_CONTROL;
674
675 if (amplitudeResult.withDefault(false)) {
676 capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL;
677 }
678 }
679
680 return HalResult<Capabilities>::fromReturn(externalControlResult, capabilities);
681 }
682
683 // -------------------------------------------------------------------------------------------------
684
685 }; // namespace vibrator
686
687 }; // namespace android
688