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(&litudes);
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