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