blob: 1010aa51951ec22ae16dee6667ede16f8b5c3074 [file] [log] [blame]
Lais Andrade9e9fcc92020-04-07 20:13:08 +01001/*
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>
Lais Andrade9e9fcc92020-04-07 20:13:08 +010020#include <android/hardware/vibrator/IVibrator.h>
21#include <hardware/vibrator.h>
Lais Andrade965284b2021-03-19 20:58:15 +000022#include <cmath>
Lais Andrade9e9fcc92020-04-07 20:13:08 +010023
24#include <utils/Log.h>
25
Lais Andrade10d9dc72020-05-20 12:00:49 +000026#include <vibratorservice/VibratorCallbackScheduler.h>
Lais Andrade9e9fcc92020-04-07 20:13:08 +010027#include <vibratorservice/VibratorHalWrapper.h>
28
Lais Andrade92f2af52021-03-22 16:12:50 +000029using android::hardware::vibrator::Braking;
Lais Andrade9e9fcc92020-04-07 20:13:08 +010030using android::hardware::vibrator::CompositeEffect;
Lais Andrade07f9c0e2020-08-11 16:22:12 +000031using android::hardware::vibrator::CompositePrimitive;
Lais Andrade9e9fcc92020-04-07 20:13:08 +010032using android::hardware::vibrator::Effect;
33using android::hardware::vibrator::EffectStrength;
Lais Andrade92f2af52021-03-22 16:12:50 +000034using android::hardware::vibrator::PrimitivePwle;
Lais Andrade9e9fcc92020-04-07 20:13:08 +010035
36using std::chrono::milliseconds;
37
38namespace V1_0 = android::hardware::vibrator::V1_0;
39namespace V1_1 = android::hardware::vibrator::V1_1;
40namespace V1_2 = android::hardware::vibrator::V1_2;
41namespace V1_3 = android::hardware::vibrator::V1_3;
42namespace Aidl = android::hardware::vibrator;
43
44namespace android {
45
46namespace vibrator {
47
48// -------------------------------------------------------------------------------------------------
49
50template <class T>
51bool 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
Lais Andrade9e9fcc92020-04-07 20:13:08 +010057// -------------------------------------------------------------------------------------------------
58
Lais Andrade08666612020-08-07 16:16:31 +000059const constexpr char* STATUS_T_ERROR_MESSAGE_PREFIX = "status_t = ";
60const constexpr char* STATUS_V_1_0_ERROR_MESSAGE_PREFIX =
61 "android::hardware::vibrator::V1_0::Status = ";
62
Lais Andrade9e9fcc92020-04-07 20:13:08 +010063template <typename T>
Lais Andrade9e9fcc92020-04-07 20:13:08 +010064HalResult<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:
Lais Andrade08666612020-08-07 16:16:31 +000071 return HalResult<T>::failed(STATUS_V_1_0_ERROR_MESSAGE_PREFIX + toString(status));
Lais Andrade9e9fcc92020-04-07 20:13:08 +010072 }
73}
74
75template <typename T>
76template <typename R>
77HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, T data) {
Lais Andrade08666612020-08-07 16:16:31 +000078 return ret.isOk() ? HalResult<T>::ok(data) : HalResult<T>::failed(ret.description());
Lais Andrade9e9fcc92020-04-07 20:13:08 +010079}
80
81template <typename T>
82template <typename R>
83HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, V1_0::Status status, T data) {
Lais Andrade08666612020-08-07 16:16:31 +000084 return ret.isOk() ? HalResult<T>::fromStatus(status, data)
85 : HalResult<T>::failed(ret.description());
Lais Andrade9e9fcc92020-04-07 20:13:08 +010086}
87
88// -------------------------------------------------------------------------------------------------
89
Lais Andrade08666612020-08-07 16:16:31 +000090HalResult<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
Lais Andrade9e9fcc92020-04-07 20:13:08 +010097HalResult<void> HalResult<void>::fromStatus(binder::Status status) {
98 if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
99 return HalResult<void>::unsupported();
100 }
101 if (status.isOk()) {
102 return HalResult<void>::ok();
103 }
Lais Andrade08666612020-08-07 16:16:31 +0000104 return HalResult<void>::failed(std::string(status.toString8().c_str()));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100105}
106
107HalResult<void> HalResult<void>::fromStatus(V1_0::Status status) {
108 switch (status) {
109 case V1_0::Status::OK:
110 return HalResult<void>::ok();
111 case V1_0::Status::UNSUPPORTED_OPERATION:
112 return HalResult<void>::unsupported();
113 default:
Lais Andrade08666612020-08-07 16:16:31 +0000114 return HalResult<void>::failed(STATUS_V_1_0_ERROR_MESSAGE_PREFIX + toString(status));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100115 }
116}
117
118template <typename R>
119HalResult<void> HalResult<void>::fromReturn(hardware::Return<R>& ret) {
Lais Andrade08666612020-08-07 16:16:31 +0000120 return ret.isOk() ? HalResult<void>::ok() : HalResult<void>::failed(ret.description());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100121}
122
123// -------------------------------------------------------------------------------------------------
124
Lais Andrade965284b2021-03-19 20:58:15 +0000125Info HalWrapper::getInfo() {
126 getCapabilities();
127 getPrimitiveDurations();
128 std::lock_guard<std::mutex> lock(mInfoMutex);
129 if (mInfoCache.mSupportedEffects.isFailed()) {
130 mInfoCache.mSupportedEffects = getSupportedEffectsInternal();
131 }
Lais Andrade92f2af52021-03-22 16:12:50 +0000132 if (mInfoCache.mSupportedBraking.isFailed()) {
133 mInfoCache.mSupportedBraking = getSupportedBrakingInternal();
134 }
135 if (mInfoCache.mMinFrequency.isFailed()) {
136 mInfoCache.mMinFrequency = getMinFrequencyInternal();
137 }
Lais Andrade965284b2021-03-19 20:58:15 +0000138 if (mInfoCache.mResonantFrequency.isFailed()) {
139 mInfoCache.mResonantFrequency = getResonantFrequencyInternal();
140 }
Lais Andrade92f2af52021-03-22 16:12:50 +0000141 if (mInfoCache.mFrequencyResolution.isFailed()) {
142 mInfoCache.mFrequencyResolution = getFrequencyResolutionInternal();
143 }
Lais Andrade965284b2021-03-19 20:58:15 +0000144 if (mInfoCache.mQFactor.isFailed()) {
145 mInfoCache.mQFactor = getQFactorInternal();
146 }
Lais Andrade92f2af52021-03-22 16:12:50 +0000147 if (mInfoCache.mMaxAmplitudes.isFailed()) {
148 mInfoCache.mMaxAmplitudes = getMaxAmplitudesInternal();
149 }
Lais Andrade965284b2021-03-19 20:58:15 +0000150 return mInfoCache.get();
151}
152
Lais Andrade92f2af52021-03-22 16:12:50 +0000153HalResult<milliseconds> HalWrapper::performComposedEffect(const std::vector<CompositeEffect>&,
154 const std::function<void()>&) {
155 ALOGV("Skipped performComposedEffect because it's not available in Vibrator HAL");
156 return HalResult<milliseconds>::unsupported();
157}
158
159HalResult<void> HalWrapper::performPwleEffect(const std::vector<PrimitivePwle>&,
160 const std::function<void()>&) {
161 ALOGV("Skipped performPwleEffect because it's not available in Vibrator HAL");
162 return HalResult<void>::unsupported();
163}
164
Lais Andrade965284b2021-03-19 20:58:15 +0000165HalResult<Capabilities> HalWrapper::getCapabilities() {
166 std::lock_guard<std::mutex> lock(mInfoMutex);
167 if (mInfoCache.mCapabilities.isFailed()) {
168 mInfoCache.mCapabilities = getCapabilitiesInternal();
169 }
170 return mInfoCache.mCapabilities;
171}
172
173HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurations() {
174 std::lock_guard<std::mutex> lock(mInfoMutex);
175 if (mInfoCache.mSupportedPrimitives.isFailed()) {
176 mInfoCache.mSupportedPrimitives = getSupportedPrimitivesInternal();
177 if (mInfoCache.mSupportedPrimitives.isUnsupported()) {
178 mInfoCache.mPrimitiveDurations = HalResult<std::vector<milliseconds>>::unsupported();
179 }
180 }
181 if (mInfoCache.mPrimitiveDurations.isFailed() && mInfoCache.mSupportedPrimitives.isOk()) {
182 mInfoCache.mPrimitiveDurations =
183 getPrimitiveDurationsInternal(mInfoCache.mSupportedPrimitives.value());
184 }
185 return mInfoCache.mPrimitiveDurations;
186}
187
188HalResult<std::vector<Effect>> HalWrapper::getSupportedEffectsInternal() {
189 ALOGV("Skipped getSupportedEffects because it's not available in Vibrator HAL");
190 return HalResult<std::vector<Effect>>::unsupported();
191}
192
Lais Andrade92f2af52021-03-22 16:12:50 +0000193HalResult<std::vector<Braking>> HalWrapper::getSupportedBrakingInternal() {
194 ALOGV("Skipped getSupportedBraking because it's not available in Vibrator HAL");
195 return HalResult<std::vector<Braking>>::unsupported();
196}
197
Lais Andrade965284b2021-03-19 20:58:15 +0000198HalResult<std::vector<CompositePrimitive>> HalWrapper::getSupportedPrimitivesInternal() {
199 ALOGV("Skipped getSupportedPrimitives because it's not available in Vibrator HAL");
200 return HalResult<std::vector<CompositePrimitive>>::unsupported();
201}
202
203HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurationsInternal(
204 const std::vector<CompositePrimitive>&) {
205 ALOGV("Skipped getPrimitiveDurations because it's not available in Vibrator HAL");
206 return HalResult<std::vector<milliseconds>>::unsupported();
207}
208
Lais Andrade92f2af52021-03-22 16:12:50 +0000209HalResult<float> HalWrapper::getMinFrequencyInternal() {
210 ALOGV("Skipped getMinFrequency because it's not available in Vibrator HAL");
211 return HalResult<float>::unsupported();
212}
213
Lais Andrade965284b2021-03-19 20:58:15 +0000214HalResult<float> HalWrapper::getResonantFrequencyInternal() {
215 ALOGV("Skipped getResonantFrequency because it's not available in Vibrator HAL");
216 return HalResult<float>::unsupported();
217}
218
Lais Andrade92f2af52021-03-22 16:12:50 +0000219HalResult<float> HalWrapper::getFrequencyResolutionInternal() {
220 ALOGV("Skipped getFrequencyResolution because it's not available in Vibrator HAL");
221 return HalResult<float>::unsupported();
222}
223
Lais Andrade965284b2021-03-19 20:58:15 +0000224HalResult<float> HalWrapper::getQFactorInternal() {
225 ALOGV("Skipped getQFactor because it's not available in Vibrator HAL");
226 return HalResult<float>::unsupported();
227}
228
Lais Andrade92f2af52021-03-22 16:12:50 +0000229HalResult<std::vector<float>> HalWrapper::getMaxAmplitudesInternal() {
230 ALOGV("Skipped getMaxAmplitudes because it's not available in Vibrator HAL");
231 return HalResult<std::vector<float>>::unsupported();
232}
233
Lais Andrade965284b2021-03-19 20:58:15 +0000234// -------------------------------------------------------------------------------------------------
235
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100236HalResult<void> AidlHalWrapper::ping() {
Lais Andrade08666612020-08-07 16:16:31 +0000237 return HalResult<void>::fromStatus(IInterface::asBinder(getHal())->pingBinder());
Lais Andradecfd81152020-07-01 09:00:26 +0000238}
239
240void AidlHalWrapper::tryReconnect() {
Lais Andrade98c97032020-11-17 19:23:01 +0000241 auto result = mReconnectFn();
242 if (!result.isOk()) {
243 return;
244 }
245 sp<Aidl::IVibrator> newHandle = result.value();
Lais Andradecfd81152020-07-01 09:00:26 +0000246 if (newHandle) {
247 std::lock_guard<std::mutex> lock(mHandleMutex);
248 mHandle = std::move(newHandle);
249 }
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100250}
251
252HalResult<void> AidlHalWrapper::on(milliseconds timeout,
253 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000254 HalResult<Capabilities> capabilities = getCapabilities();
255 bool supportsCallback = capabilities.isOk() &&
256 static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
257 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
258
Lais Andradecfd81152020-07-01 09:00:26 +0000259 auto ret = HalResult<void>::fromStatus(getHal()->on(timeout.count(), cb));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000260 if (!supportsCallback && ret.isOk()) {
261 mCallbackScheduler->schedule(completionCallback, timeout);
262 }
263
264 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100265}
266
267HalResult<void> AidlHalWrapper::off() {
Lais Andradecfd81152020-07-01 09:00:26 +0000268 return HalResult<void>::fromStatus(getHal()->off());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100269}
270
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000271HalResult<void> AidlHalWrapper::setAmplitude(float amplitude) {
272 return HalResult<void>::fromStatus(getHal()->setAmplitude(amplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100273}
274
275HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000276 return HalResult<void>::fromStatus(getHal()->setExternalControl(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100277}
278
279HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
Lais Andradecfd81152020-07-01 09:00:26 +0000280 return HalResult<void>::fromStatus(getHal()->alwaysOnEnable(id, effect, strength));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100281}
282
283HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
Lais Andradecfd81152020-07-01 09:00:26 +0000284 return HalResult<void>::fromStatus(getHal()->alwaysOnDisable(id));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100285}
286
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100287HalResult<milliseconds> AidlHalWrapper::performEffect(
288 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000289 HalResult<Capabilities> capabilities = getCapabilities();
290 bool supportsCallback = capabilities.isOk() &&
291 static_cast<int32_t>(capabilities.value() & Capabilities::PERFORM_CALLBACK);
292 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
293
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100294 int32_t lengthMs;
Lais Andradecfd81152020-07-01 09:00:26 +0000295 auto result = getHal()->perform(effect, strength, cb, &lengthMs);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000296 milliseconds length = milliseconds(lengthMs);
297
298 auto ret = HalResult<milliseconds>::fromStatus(result, length);
299 if (!supportsCallback && ret.isOk()) {
300 mCallbackScheduler->schedule(completionCallback, length);
301 }
302
303 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100304}
305
Lais Andrade49b60b12021-02-23 13:27:41 +0000306HalResult<milliseconds> AidlHalWrapper::performComposedEffect(
Lais Andrade92f2af52021-03-22 16:12:50 +0000307 const std::vector<CompositeEffect>& primitives,
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100308 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000309 // This method should always support callbacks, so no need to double check.
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100310 auto cb = new HalCallbackWrapper(completionCallback);
Lais Andrade965284b2021-03-19 20:58:15 +0000311
312 auto durations = getPrimitiveDurations().valueOr({});
Lais Andrade49b60b12021-02-23 13:27:41 +0000313 milliseconds duration(0);
Lais Andrade92f2af52021-03-22 16:12:50 +0000314 for (const auto& effect : primitives) {
Lais Andrade965284b2021-03-19 20:58:15 +0000315 auto primitiveIdx = static_cast<size_t>(effect.primitive);
316 if (primitiveIdx < durations.size()) {
317 duration += durations[primitiveIdx];
318 } else {
319 // Make sure the returned duration is positive to indicate successful vibration.
320 duration += milliseconds(1);
Lais Andrade49b60b12021-02-23 13:27:41 +0000321 }
322 duration += milliseconds(effect.delayMs);
323 }
Lais Andrade49b60b12021-02-23 13:27:41 +0000324
Lais Andrade92f2af52021-03-22 16:12:50 +0000325 return HalResult<milliseconds>::fromStatus(getHal()->compose(primitives, cb), duration);
326}
327
328HalResult<void> AidlHalWrapper::performPwleEffect(const std::vector<PrimitivePwle>& primitives,
329 const std::function<void()>& completionCallback) {
330 // This method should always support callbacks, so no need to double check.
331 auto cb = new HalCallbackWrapper(completionCallback);
332 return HalResult<void>::fromStatus(getHal()->composePwle(primitives, cb));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100333}
334
Lais Andrade10d9dc72020-05-20 12:00:49 +0000335HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
336 int32_t capabilities = 0;
Lais Andradecfd81152020-07-01 09:00:26 +0000337 auto result = getHal()->getCapabilities(&capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000338 return HalResult<Capabilities>::fromStatus(result, static_cast<Capabilities>(capabilities));
339}
340
341HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
342 std::vector<Effect> supportedEffects;
Lais Andradecfd81152020-07-01 09:00:26 +0000343 auto result = getHal()->getSupportedEffects(&supportedEffects);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000344 return HalResult<std::vector<Effect>>::fromStatus(result, supportedEffects);
345}
346
Lais Andrade92f2af52021-03-22 16:12:50 +0000347HalResult<std::vector<Braking>> AidlHalWrapper::getSupportedBrakingInternal() {
348 std::vector<Braking> supportedBraking;
349 auto result = getHal()->getSupportedBraking(&supportedBraking);
350 return HalResult<std::vector<Braking>>::fromStatus(result, supportedBraking);
351}
352
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000353HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() {
354 std::vector<CompositePrimitive> supportedPrimitives;
355 auto result = getHal()->getSupportedPrimitives(&supportedPrimitives);
356 return HalResult<std::vector<CompositePrimitive>>::fromStatus(result, supportedPrimitives);
357}
358
Lais Andrade965284b2021-03-19 20:58:15 +0000359HalResult<std::vector<milliseconds>> AidlHalWrapper::getPrimitiveDurationsInternal(
360 const std::vector<CompositePrimitive>& supportedPrimitives) {
361 std::vector<milliseconds> durations;
362 constexpr auto primitiveRange = enum_range<CompositePrimitive>();
363 constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
364 durations.resize(primitiveCount);
365
366 for (auto primitive : supportedPrimitives) {
367 auto primitiveIdx = static_cast<size_t>(primitive);
368 if (primitiveIdx >= durations.size()) {
369 // Safety check, should not happen if enum_range is correct.
370 continue;
371 }
372 int32_t duration = 0;
373 auto status = getHal()->getPrimitiveDuration(primitive, &duration);
374 if (!status.isOk()) {
375 return HalResult<std::vector<milliseconds>>::failed(status.toString8().c_str());
376 }
377 durations[primitiveIdx] = milliseconds(duration);
378 }
379
380 return HalResult<std::vector<milliseconds>>::ok(durations);
381}
382
Lais Andrade92f2af52021-03-22 16:12:50 +0000383HalResult<float> AidlHalWrapper::getMinFrequencyInternal() {
384 float minFrequency = 0;
385 auto result = getHal()->getFrequencyMinimum(&minFrequency);
386 return HalResult<float>::fromStatus(result, minFrequency);
387}
388
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000389HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() {
390 float f0 = 0;
391 auto result = getHal()->getResonantFrequency(&f0);
392 return HalResult<float>::fromStatus(result, f0);
393}
394
Lais Andrade92f2af52021-03-22 16:12:50 +0000395HalResult<float> AidlHalWrapper::getFrequencyResolutionInternal() {
396 float frequencyResolution = 0;
397 auto result = getHal()->getFrequencyResolution(&frequencyResolution);
398 return HalResult<float>::fromStatus(result, frequencyResolution);
399}
400
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000401HalResult<float> AidlHalWrapper::getQFactorInternal() {
402 float qFactor = 0;
403 auto result = getHal()->getQFactor(&qFactor);
404 return HalResult<float>::fromStatus(result, qFactor);
405}
406
Lais Andrade92f2af52021-03-22 16:12:50 +0000407HalResult<std::vector<float>> AidlHalWrapper::getMaxAmplitudesInternal() {
408 std::vector<float> amplitudes;
409 auto result = getHal()->getBandwidthAmplitudeMap(&amplitudes);
410 return HalResult<std::vector<float>>::fromStatus(result, amplitudes);
411}
412
Lais Andradecfd81152020-07-01 09:00:26 +0000413sp<Aidl::IVibrator> AidlHalWrapper::getHal() {
414 std::lock_guard<std::mutex> lock(mHandleMutex);
415 return mHandle;
416}
417
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100418// -------------------------------------------------------------------------------------------------
419
Lais Andradecfd81152020-07-01 09:00:26 +0000420template <typename I>
421HalResult<void> HidlHalWrapper<I>::ping() {
422 auto result = getHal()->ping();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100423 return HalResult<void>::fromReturn(result);
424}
425
Lais Andradecfd81152020-07-01 09:00:26 +0000426template <typename I>
427void HidlHalWrapper<I>::tryReconnect() {
428 sp<I> newHandle = I::tryGetService();
429 if (newHandle) {
430 std::lock_guard<std::mutex> lock(mHandleMutex);
431 mHandle = std::move(newHandle);
432 }
433}
434
435template <typename I>
436HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
437 const std::function<void()>& completionCallback) {
438 auto result = getHal()->on(timeout.count());
Lais Andrade10d9dc72020-05-20 12:00:49 +0000439 auto ret = HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
440 if (ret.isOk()) {
441 mCallbackScheduler->schedule(completionCallback, timeout);
442 }
443 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100444}
445
Lais Andradecfd81152020-07-01 09:00:26 +0000446template <typename I>
447HalResult<void> HidlHalWrapper<I>::off() {
448 auto result = getHal()->off();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100449 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
450}
451
Lais Andradecfd81152020-07-01 09:00:26 +0000452template <typename I>
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000453HalResult<void> HidlHalWrapper<I>::setAmplitude(float amplitude) {
454 uint8_t amp = static_cast<uint8_t>(amplitude * std::numeric_limits<uint8_t>::max());
455 auto result = getHal()->setAmplitude(amp);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100456 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
457}
458
Lais Andradecfd81152020-07-01 09:00:26 +0000459template <typename I>
460HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100461 ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
462 return HalResult<void>::unsupported();
463}
464
Lais Andradecfd81152020-07-01 09:00:26 +0000465template <typename I>
466HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100467 ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
468 return HalResult<void>::unsupported();
469}
470
Lais Andradecfd81152020-07-01 09:00:26 +0000471template <typename I>
472HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100473 ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
474 return HalResult<void>::unsupported();
475}
476
Lais Andradecfd81152020-07-01 09:00:26 +0000477template <typename I>
Lais Andradecfd81152020-07-01 09:00:26 +0000478HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
479 hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
Lais Andraded39ff7d2020-05-19 10:42:51 +0000480 Capabilities capabilities =
481 result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
482 return HalResult<Capabilities>::fromReturn(result, capabilities);
483}
484
Lais Andradecfd81152020-07-01 09:00:26 +0000485template <typename I>
486template <typename T>
487HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
488 perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
Lais Andrade10d9dc72020-05-20 12:00:49 +0000489 const std::function<void()>& completionCallback) {
490 V1_0::Status status;
491 int32_t lengthMs;
492 auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
493 status = retStatus;
494 lengthMs = retLengthMs;
495 };
496
497 V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
498 auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
499 milliseconds length = milliseconds(lengthMs);
500
501 auto ret = HalResult<milliseconds>::fromReturn(result, status, length);
502 if (ret.isOk()) {
503 mCallbackScheduler->schedule(completionCallback, length);
504 }
505
506 return ret;
507}
508
Lais Andradecfd81152020-07-01 09:00:26 +0000509template <typename I>
510sp<I> HidlHalWrapper<I>::getHal() {
511 std::lock_guard<std::mutex> lock(mHandleMutex);
512 return mHandle;
513}
514
515// -------------------------------------------------------------------------------------------------
516
517HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
Lais Andrade10d9dc72020-05-20 12:00:49 +0000518 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andradecfd81152020-07-01 09:00:26 +0000519 if (isStaticCastValid<V1_0::Effect>(effect)) {
520 return performInternal(&V1_0::IVibrator::perform, getHal(),
521 static_cast<V1_0::Effect>(effect), strength, completionCallback);
522 }
523
524 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
525 Aidl::toString(effect).c_str());
526 return HalResult<milliseconds>::unsupported();
Lais Andrade10d9dc72020-05-20 12:00:49 +0000527}
528
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100529// -------------------------------------------------------------------------------------------------
530
Lais Andrade10d9dc72020-05-20 12:00:49 +0000531HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
532 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100533 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000534 return performInternal(&V1_1::IVibrator::perform, getHal(),
535 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100536 }
537 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000538 return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
539 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100540 }
541
542 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
543 Aidl::toString(effect).c_str());
544 return HalResult<milliseconds>::unsupported();
545}
546
547// -------------------------------------------------------------------------------------------------
548
Lais Andrade10d9dc72020-05-20 12:00:49 +0000549HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
550 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100551 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000552 return performInternal(&V1_2::IVibrator::perform, getHal(),
553 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100554 }
555 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000556 return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
557 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100558 }
559 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000560 return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
561 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100562 }
563
564 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
565 Aidl::toString(effect).c_str());
566 return HalResult<milliseconds>::unsupported();
567}
568
569// -------------------------------------------------------------------------------------------------
570
571HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000572 auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100573 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
574}
575
Lais Andrade10d9dc72020-05-20 12:00:49 +0000576HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
577 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100578 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000579 return performInternal(&V1_3::IVibrator::perform, getHal(),
580 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100581 }
582 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000583 return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
584 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100585 }
586 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000587 return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
588 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100589 }
590 if (isStaticCastValid<V1_3::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000591 return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
592 static_cast<V1_3::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100593 }
594
595 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
596 Aidl::toString(effect).c_str());
597 return HalResult<milliseconds>::unsupported();
598}
599
Lais Andraded39ff7d2020-05-19 10:42:51 +0000600HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
Lais Andrade08666612020-08-07 16:16:31 +0000601 Capabilities capabilities = Capabilities::NONE;
602
Lais Andradecfd81152020-07-01 09:00:26 +0000603 sp<V1_3::IVibrator> hal = getHal();
604 auto amplitudeResult = hal->supportsAmplitudeControl();
605 if (!amplitudeResult.isOk()) {
Lais Andrade08666612020-08-07 16:16:31 +0000606 return HalResult<Capabilities>::fromReturn(amplitudeResult, capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000607 }
608
Lais Andradecfd81152020-07-01 09:00:26 +0000609 auto externalControlResult = hal->supportsExternalControl();
Lais Andradecfd81152020-07-01 09:00:26 +0000610 if (amplitudeResult.withDefault(false)) {
611 capabilities |= Capabilities::AMPLITUDE_CONTROL;
612 }
613 if (externalControlResult.withDefault(false)) {
614 capabilities |= Capabilities::EXTERNAL_CONTROL;
Lais Andrade602ff962020-08-27 12:02:53 +0000615
616 if (amplitudeResult.withDefault(false)) {
617 capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL;
618 }
Lais Andradecfd81152020-07-01 09:00:26 +0000619 }
620
621 return HalResult<Capabilities>::fromReturn(externalControlResult, capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000622}
623
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100624// -------------------------------------------------------------------------------------------------
625
626}; // namespace vibrator
627
628}; // namespace android