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