• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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             ALOGE("Supported primitive %zu is outside range [0,%zu), skipping load duration",
406                   primitiveIdx, durations.size());
407             continue;
408         }
409         int32_t duration = 0;
410         auto result = getHal()->getPrimitiveDuration(primitive, &duration);
411         auto halResult = HalResult<int32_t>::fromStatus(result, duration);
412         if (halResult.isUnsupported()) {
413             // Should not happen, supported primitives should always support requesting duration.
414             ALOGE("Supported primitive %zu returned unsupported for getPrimitiveDuration",
415                   primitiveIdx);
416         }
417         if (halResult.isFailed()) {
418             // Fail entire request if one request has failed.
419             return HalResult<std::vector<milliseconds>>::failed(result.toString8().c_str());
420         }
421         durations[primitiveIdx] = milliseconds(duration);
422     }
423 
424     return HalResult<std::vector<milliseconds>>::ok(durations);
425 }
426 
getPrimitiveDelayMaxInternal()427 HalResult<milliseconds> AidlHalWrapper::getPrimitiveDelayMaxInternal() {
428     int32_t delay = 0;
429     auto result = getHal()->getCompositionDelayMax(&delay);
430     return HalResult<milliseconds>::fromStatus(result, milliseconds(delay));
431 }
432 
getPrimitiveDurationMaxInternal()433 HalResult<milliseconds> AidlHalWrapper::getPrimitiveDurationMaxInternal() {
434     int32_t delay = 0;
435     auto result = getHal()->getPwlePrimitiveDurationMax(&delay);
436     return HalResult<milliseconds>::fromStatus(result, milliseconds(delay));
437 }
438 
getCompositionSizeMaxInternal()439 HalResult<int32_t> AidlHalWrapper::getCompositionSizeMaxInternal() {
440     int32_t size = 0;
441     auto result = getHal()->getCompositionSizeMax(&size);
442     return HalResult<int32_t>::fromStatus(result, size);
443 }
444 
getPwleSizeMaxInternal()445 HalResult<int32_t> AidlHalWrapper::getPwleSizeMaxInternal() {
446     int32_t size = 0;
447     auto result = getHal()->getPwleCompositionSizeMax(&size);
448     return HalResult<int32_t>::fromStatus(result, size);
449 }
450 
getMinFrequencyInternal()451 HalResult<float> AidlHalWrapper::getMinFrequencyInternal() {
452     float minFrequency = 0;
453     auto result = getHal()->getFrequencyMinimum(&minFrequency);
454     return HalResult<float>::fromStatus(result, minFrequency);
455 }
456 
getResonantFrequencyInternal()457 HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() {
458     float f0 = 0;
459     auto result = getHal()->getResonantFrequency(&f0);
460     return HalResult<float>::fromStatus(result, f0);
461 }
462 
getFrequencyResolutionInternal()463 HalResult<float> AidlHalWrapper::getFrequencyResolutionInternal() {
464     float frequencyResolution = 0;
465     auto result = getHal()->getFrequencyResolution(&frequencyResolution);
466     return HalResult<float>::fromStatus(result, frequencyResolution);
467 }
468 
getQFactorInternal()469 HalResult<float> AidlHalWrapper::getQFactorInternal() {
470     float qFactor = 0;
471     auto result = getHal()->getQFactor(&qFactor);
472     return HalResult<float>::fromStatus(result, qFactor);
473 }
474 
getMaxAmplitudesInternal()475 HalResult<std::vector<float>> AidlHalWrapper::getMaxAmplitudesInternal() {
476     std::vector<float> amplitudes;
477     auto result = getHal()->getBandwidthAmplitudeMap(&amplitudes);
478     return HalResult<std::vector<float>>::fromStatus(result, amplitudes);
479 }
480 
getHal()481 sp<Aidl::IVibrator> AidlHalWrapper::getHal() {
482     std::lock_guard<std::mutex> lock(mHandleMutex);
483     return mHandle;
484 }
485 
486 // -------------------------------------------------------------------------------------------------
487 
488 template <typename I>
ping()489 HalResult<void> HidlHalWrapper<I>::ping() {
490     auto result = getHal()->ping();
491     return HalResult<void>::fromReturn(result);
492 }
493 
494 template <typename I>
tryReconnect()495 void HidlHalWrapper<I>::tryReconnect() {
496     sp<I> newHandle = I::tryGetService();
497     if (newHandle) {
498         std::lock_guard<std::mutex> lock(mHandleMutex);
499         mHandle = std::move(newHandle);
500     }
501 }
502 
503 template <typename I>
on(milliseconds timeout,const std::function<void ()> & completionCallback)504 HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
505                                       const std::function<void()>& completionCallback) {
506     auto result = getHal()->on(timeout.count());
507     auto ret = HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
508     if (ret.isOk()) {
509         mCallbackScheduler->schedule(completionCallback, timeout);
510     }
511     return ret;
512 }
513 
514 template <typename I>
off()515 HalResult<void> HidlHalWrapper<I>::off() {
516     auto result = getHal()->off();
517     return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
518 }
519 
520 template <typename I>
setAmplitude(float amplitude)521 HalResult<void> HidlHalWrapper<I>::setAmplitude(float amplitude) {
522     uint8_t amp = static_cast<uint8_t>(amplitude * std::numeric_limits<uint8_t>::max());
523     auto result = getHal()->setAmplitude(amp);
524     return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
525 }
526 
527 template <typename I>
setExternalControl(bool)528 HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
529     ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
530     return HalResult<void>::unsupported();
531 }
532 
533 template <typename I>
alwaysOnEnable(int32_t,Effect,EffectStrength)534 HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
535     ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
536     return HalResult<void>::unsupported();
537 }
538 
539 template <typename I>
alwaysOnDisable(int32_t)540 HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
541     ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
542     return HalResult<void>::unsupported();
543 }
544 
545 template <typename I>
getCapabilitiesInternal()546 HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
547     hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
548     Capabilities capabilities =
549             result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
550     return HalResult<Capabilities>::fromReturn(result, capabilities);
551 }
552 
553 template <typename I>
554 template <typename T>
performInternal(perform_fn<T> performFn,sp<I> handle,T effect,EffectStrength strength,const std::function<void ()> & completionCallback)555 HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
556         perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
557         const std::function<void()>& completionCallback) {
558     V1_0::Status status;
559     int32_t lengthMs;
560     auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
561         status = retStatus;
562         lengthMs = retLengthMs;
563     };
564 
565     V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
566     auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
567     milliseconds length = milliseconds(lengthMs);
568 
569     auto ret = HalResult<milliseconds>::fromReturn(result, status, length);
570     if (ret.isOk()) {
571         mCallbackScheduler->schedule(completionCallback, length);
572     }
573 
574     return ret;
575 }
576 
577 template <typename I>
getHal()578 sp<I> HidlHalWrapper<I>::getHal() {
579     std::lock_guard<std::mutex> lock(mHandleMutex);
580     return mHandle;
581 }
582 
583 // -------------------------------------------------------------------------------------------------
584 
performEffect(Effect effect,EffectStrength strength,const std::function<void ()> & completionCallback)585 HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
586         Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
587     if (isStaticCastValid<V1_0::Effect>(effect)) {
588         return performInternal(&V1_0::IVibrator::perform, getHal(),
589                                static_cast<V1_0::Effect>(effect), strength, completionCallback);
590     }
591 
592     ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
593           Aidl::toString(effect).c_str());
594     return HalResult<milliseconds>::unsupported();
595 }
596 
597 // -------------------------------------------------------------------------------------------------
598 
performEffect(Effect effect,EffectStrength strength,const std::function<void ()> & completionCallback)599 HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
600         Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
601     if (isStaticCastValid<V1_0::Effect>(effect)) {
602         return performInternal(&V1_1::IVibrator::perform, getHal(),
603                                static_cast<V1_0::Effect>(effect), strength, completionCallback);
604     }
605     if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
606         return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
607                                static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
608     }
609 
610     ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
611           Aidl::toString(effect).c_str());
612     return HalResult<milliseconds>::unsupported();
613 }
614 
615 // -------------------------------------------------------------------------------------------------
616 
performEffect(Effect effect,EffectStrength strength,const std::function<void ()> & completionCallback)617 HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
618         Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
619     if (isStaticCastValid<V1_0::Effect>(effect)) {
620         return performInternal(&V1_2::IVibrator::perform, getHal(),
621                                static_cast<V1_0::Effect>(effect), strength, completionCallback);
622     }
623     if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
624         return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
625                                static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
626     }
627     if (isStaticCastValid<V1_2::Effect>(effect)) {
628         return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
629                                static_cast<V1_2::Effect>(effect), strength, completionCallback);
630     }
631 
632     ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
633           Aidl::toString(effect).c_str());
634     return HalResult<milliseconds>::unsupported();
635 }
636 
637 // -------------------------------------------------------------------------------------------------
638 
setExternalControl(bool enabled)639 HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
640     auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
641     return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
642 }
643 
performEffect(Effect effect,EffectStrength strength,const std::function<void ()> & completionCallback)644 HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
645         Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
646     if (isStaticCastValid<V1_0::Effect>(effect)) {
647         return performInternal(&V1_3::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_3::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_3::IVibrator::perform_1_2, getHal(),
656                                static_cast<V1_2::Effect>(effect), strength, completionCallback);
657     }
658     if (isStaticCastValid<V1_3::Effect>(effect)) {
659         return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
660                                static_cast<V1_3::Effect>(effect), strength, completionCallback);
661     }
662 
663     ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
664           Aidl::toString(effect).c_str());
665     return HalResult<milliseconds>::unsupported();
666 }
667 
getCapabilitiesInternal()668 HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
669     Capabilities capabilities = Capabilities::NONE;
670 
671     sp<V1_3::IVibrator> hal = getHal();
672     auto amplitudeResult = hal->supportsAmplitudeControl();
673     if (!amplitudeResult.isOk()) {
674         return HalResult<Capabilities>::fromReturn(amplitudeResult, capabilities);
675     }
676 
677     auto externalControlResult = hal->supportsExternalControl();
678     if (amplitudeResult.withDefault(false)) {
679         capabilities |= Capabilities::AMPLITUDE_CONTROL;
680     }
681     if (externalControlResult.withDefault(false)) {
682         capabilities |= Capabilities::EXTERNAL_CONTROL;
683 
684         if (amplitudeResult.withDefault(false)) {
685             capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL;
686         }
687     }
688 
689     return HalResult<Capabilities>::fromReturn(externalControlResult, capabilities);
690 }
691 
692 // -------------------------------------------------------------------------------------------------
693 
694 }; // namespace vibrator
695 
696 }; // namespace android
697