blob: f15a963e4484e0258d8f67e615e23a2a4b6933e5 [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) {
Lais Andradef5f88f32021-06-10 16:48:26 +010098 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.
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100102 return HalResult<void>::unsupported();
103 }
104 if (status.isOk()) {
105 return HalResult<void>::ok();
106 }
Lais Andrade08666612020-08-07 16:16:31 +0000107 return HalResult<void>::failed(std::string(status.toString8().c_str()));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100108}
109
110HalResult<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:
Lais Andrade08666612020-08-07 16:16:31 +0000117 return HalResult<void>::failed(STATUS_V_1_0_ERROR_MESSAGE_PREFIX + toString(status));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100118 }
119}
120
121template <typename R>
122HalResult<void> HalResult<void>::fromReturn(hardware::Return<R>& ret) {
Lais Andrade08666612020-08-07 16:16:31 +0000123 return ret.isOk() ? HalResult<void>::ok() : HalResult<void>::failed(ret.description());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100124}
125
126// -------------------------------------------------------------------------------------------------
127
Lais Andrade965284b2021-03-19 20:58:15 +0000128Info HalWrapper::getInfo() {
129 getCapabilities();
130 getPrimitiveDurations();
131 std::lock_guard<std::mutex> lock(mInfoMutex);
132 if (mInfoCache.mSupportedEffects.isFailed()) {
133 mInfoCache.mSupportedEffects = getSupportedEffectsInternal();
134 }
Lais Andrade92f2af52021-03-22 16:12:50 +0000135 if (mInfoCache.mSupportedBraking.isFailed()) {
136 mInfoCache.mSupportedBraking = getSupportedBrakingInternal();
137 }
138 if (mInfoCache.mMinFrequency.isFailed()) {
139 mInfoCache.mMinFrequency = getMinFrequencyInternal();
140 }
Lais Andrade965284b2021-03-19 20:58:15 +0000141 if (mInfoCache.mResonantFrequency.isFailed()) {
142 mInfoCache.mResonantFrequency = getResonantFrequencyInternal();
143 }
Lais Andrade92f2af52021-03-22 16:12:50 +0000144 if (mInfoCache.mFrequencyResolution.isFailed()) {
145 mInfoCache.mFrequencyResolution = getFrequencyResolutionInternal();
146 }
Lais Andrade965284b2021-03-19 20:58:15 +0000147 if (mInfoCache.mQFactor.isFailed()) {
148 mInfoCache.mQFactor = getQFactorInternal();
149 }
Lais Andrade92f2af52021-03-22 16:12:50 +0000150 if (mInfoCache.mMaxAmplitudes.isFailed()) {
151 mInfoCache.mMaxAmplitudes = getMaxAmplitudesInternal();
152 }
Lais Andrade965284b2021-03-19 20:58:15 +0000153 return mInfoCache.get();
154}
155
Lais Andrade92f2af52021-03-22 16:12:50 +0000156HalResult<milliseconds> HalWrapper::performComposedEffect(const std::vector<CompositeEffect>&,
157 const std::function<void()>&) {
158 ALOGV("Skipped performComposedEffect because it's not available in Vibrator HAL");
159 return HalResult<milliseconds>::unsupported();
160}
161
162HalResult<void> HalWrapper::performPwleEffect(const std::vector<PrimitivePwle>&,
163 const std::function<void()>&) {
164 ALOGV("Skipped performPwleEffect because it's not available in Vibrator HAL");
165 return HalResult<void>::unsupported();
166}
167
Lais Andrade965284b2021-03-19 20:58:15 +0000168HalResult<Capabilities> HalWrapper::getCapabilities() {
169 std::lock_guard<std::mutex> lock(mInfoMutex);
170 if (mInfoCache.mCapabilities.isFailed()) {
171 mInfoCache.mCapabilities = getCapabilitiesInternal();
172 }
173 return mInfoCache.mCapabilities;
174}
175
176HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurations() {
177 std::lock_guard<std::mutex> lock(mInfoMutex);
178 if (mInfoCache.mSupportedPrimitives.isFailed()) {
179 mInfoCache.mSupportedPrimitives = getSupportedPrimitivesInternal();
180 if (mInfoCache.mSupportedPrimitives.isUnsupported()) {
181 mInfoCache.mPrimitiveDurations = HalResult<std::vector<milliseconds>>::unsupported();
182 }
183 }
184 if (mInfoCache.mPrimitiveDurations.isFailed() && mInfoCache.mSupportedPrimitives.isOk()) {
185 mInfoCache.mPrimitiveDurations =
186 getPrimitiveDurationsInternal(mInfoCache.mSupportedPrimitives.value());
187 }
188 return mInfoCache.mPrimitiveDurations;
189}
190
191HalResult<std::vector<Effect>> HalWrapper::getSupportedEffectsInternal() {
192 ALOGV("Skipped getSupportedEffects because it's not available in Vibrator HAL");
193 return HalResult<std::vector<Effect>>::unsupported();
194}
195
Lais Andrade92f2af52021-03-22 16:12:50 +0000196HalResult<std::vector<Braking>> HalWrapper::getSupportedBrakingInternal() {
197 ALOGV("Skipped getSupportedBraking because it's not available in Vibrator HAL");
198 return HalResult<std::vector<Braking>>::unsupported();
199}
200
Lais Andrade965284b2021-03-19 20:58:15 +0000201HalResult<std::vector<CompositePrimitive>> HalWrapper::getSupportedPrimitivesInternal() {
202 ALOGV("Skipped getSupportedPrimitives because it's not available in Vibrator HAL");
203 return HalResult<std::vector<CompositePrimitive>>::unsupported();
204}
205
206HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurationsInternal(
207 const std::vector<CompositePrimitive>&) {
208 ALOGV("Skipped getPrimitiveDurations because it's not available in Vibrator HAL");
209 return HalResult<std::vector<milliseconds>>::unsupported();
210}
211
Lais Andrade92f2af52021-03-22 16:12:50 +0000212HalResult<float> HalWrapper::getMinFrequencyInternal() {
213 ALOGV("Skipped getMinFrequency because it's not available in Vibrator HAL");
214 return HalResult<float>::unsupported();
215}
216
Lais Andrade965284b2021-03-19 20:58:15 +0000217HalResult<float> HalWrapper::getResonantFrequencyInternal() {
218 ALOGV("Skipped getResonantFrequency because it's not available in Vibrator HAL");
219 return HalResult<float>::unsupported();
220}
221
Lais Andrade92f2af52021-03-22 16:12:50 +0000222HalResult<float> HalWrapper::getFrequencyResolutionInternal() {
223 ALOGV("Skipped getFrequencyResolution because it's not available in Vibrator HAL");
224 return HalResult<float>::unsupported();
225}
226
Lais Andrade965284b2021-03-19 20:58:15 +0000227HalResult<float> HalWrapper::getQFactorInternal() {
228 ALOGV("Skipped getQFactor because it's not available in Vibrator HAL");
229 return HalResult<float>::unsupported();
230}
231
Lais Andrade92f2af52021-03-22 16:12:50 +0000232HalResult<std::vector<float>> HalWrapper::getMaxAmplitudesInternal() {
233 ALOGV("Skipped getMaxAmplitudes because it's not available in Vibrator HAL");
234 return HalResult<std::vector<float>>::unsupported();
235}
236
Lais Andrade965284b2021-03-19 20:58:15 +0000237// -------------------------------------------------------------------------------------------------
238
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100239HalResult<void> AidlHalWrapper::ping() {
Lais Andrade08666612020-08-07 16:16:31 +0000240 return HalResult<void>::fromStatus(IInterface::asBinder(getHal())->pingBinder());
Lais Andradecfd81152020-07-01 09:00:26 +0000241}
242
243void AidlHalWrapper::tryReconnect() {
Lais Andrade98c97032020-11-17 19:23:01 +0000244 auto result = mReconnectFn();
245 if (!result.isOk()) {
246 return;
247 }
248 sp<Aidl::IVibrator> newHandle = result.value();
Lais Andradecfd81152020-07-01 09:00:26 +0000249 if (newHandle) {
250 std::lock_guard<std::mutex> lock(mHandleMutex);
251 mHandle = std::move(newHandle);
252 }
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100253}
254
255HalResult<void> AidlHalWrapper::on(milliseconds timeout,
256 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000257 HalResult<Capabilities> capabilities = getCapabilities();
258 bool supportsCallback = capabilities.isOk() &&
259 static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
260 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
261
Lais Andradecfd81152020-07-01 09:00:26 +0000262 auto ret = HalResult<void>::fromStatus(getHal()->on(timeout.count(), cb));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000263 if (!supportsCallback && ret.isOk()) {
264 mCallbackScheduler->schedule(completionCallback, timeout);
265 }
266
267 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100268}
269
270HalResult<void> AidlHalWrapper::off() {
Lais Andradecfd81152020-07-01 09:00:26 +0000271 return HalResult<void>::fromStatus(getHal()->off());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100272}
273
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000274HalResult<void> AidlHalWrapper::setAmplitude(float amplitude) {
275 return HalResult<void>::fromStatus(getHal()->setAmplitude(amplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100276}
277
278HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000279 return HalResult<void>::fromStatus(getHal()->setExternalControl(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100280}
281
282HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
Lais Andradecfd81152020-07-01 09:00:26 +0000283 return HalResult<void>::fromStatus(getHal()->alwaysOnEnable(id, effect, strength));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100284}
285
286HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
Lais Andradecfd81152020-07-01 09:00:26 +0000287 return HalResult<void>::fromStatus(getHal()->alwaysOnDisable(id));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100288}
289
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100290HalResult<milliseconds> AidlHalWrapper::performEffect(
291 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000292 HalResult<Capabilities> capabilities = getCapabilities();
293 bool supportsCallback = capabilities.isOk() &&
294 static_cast<int32_t>(capabilities.value() & Capabilities::PERFORM_CALLBACK);
295 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
296
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100297 int32_t lengthMs;
Lais Andradecfd81152020-07-01 09:00:26 +0000298 auto result = getHal()->perform(effect, strength, cb, &lengthMs);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000299 milliseconds length = milliseconds(lengthMs);
300
301 auto ret = HalResult<milliseconds>::fromStatus(result, length);
302 if (!supportsCallback && ret.isOk()) {
303 mCallbackScheduler->schedule(completionCallback, length);
304 }
305
306 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100307}
308
Lais Andrade49b60b12021-02-23 13:27:41 +0000309HalResult<milliseconds> AidlHalWrapper::performComposedEffect(
Lais Andrade92f2af52021-03-22 16:12:50 +0000310 const std::vector<CompositeEffect>& primitives,
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100311 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000312 // This method should always support callbacks, so no need to double check.
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100313 auto cb = new HalCallbackWrapper(completionCallback);
Lais Andrade965284b2021-03-19 20:58:15 +0000314
315 auto durations = getPrimitiveDurations().valueOr({});
Lais Andrade49b60b12021-02-23 13:27:41 +0000316 milliseconds duration(0);
Lais Andrade92f2af52021-03-22 16:12:50 +0000317 for (const auto& effect : primitives) {
Lais Andrade965284b2021-03-19 20:58:15 +0000318 auto primitiveIdx = static_cast<size_t>(effect.primitive);
319 if (primitiveIdx < durations.size()) {
320 duration += durations[primitiveIdx];
321 } else {
322 // Make sure the returned duration is positive to indicate successful vibration.
323 duration += milliseconds(1);
Lais Andrade49b60b12021-02-23 13:27:41 +0000324 }
325 duration += milliseconds(effect.delayMs);
326 }
Lais Andrade49b60b12021-02-23 13:27:41 +0000327
Lais Andrade92f2af52021-03-22 16:12:50 +0000328 return HalResult<milliseconds>::fromStatus(getHal()->compose(primitives, cb), duration);
329}
330
331HalResult<void> AidlHalWrapper::performPwleEffect(const std::vector<PrimitivePwle>& primitives,
332 const std::function<void()>& completionCallback) {
333 // This method should always support callbacks, so no need to double check.
334 auto cb = new HalCallbackWrapper(completionCallback);
335 return HalResult<void>::fromStatus(getHal()->composePwle(primitives, cb));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100336}
337
Lais Andrade10d9dc72020-05-20 12:00:49 +0000338HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
339 int32_t capabilities = 0;
Lais Andradecfd81152020-07-01 09:00:26 +0000340 auto result = getHal()->getCapabilities(&capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000341 return HalResult<Capabilities>::fromStatus(result, static_cast<Capabilities>(capabilities));
342}
343
344HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
345 std::vector<Effect> supportedEffects;
Lais Andradecfd81152020-07-01 09:00:26 +0000346 auto result = getHal()->getSupportedEffects(&supportedEffects);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000347 return HalResult<std::vector<Effect>>::fromStatus(result, supportedEffects);
348}
349
Lais Andrade92f2af52021-03-22 16:12:50 +0000350HalResult<std::vector<Braking>> AidlHalWrapper::getSupportedBrakingInternal() {
351 std::vector<Braking> supportedBraking;
352 auto result = getHal()->getSupportedBraking(&supportedBraking);
353 return HalResult<std::vector<Braking>>::fromStatus(result, supportedBraking);
354}
355
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000356HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() {
357 std::vector<CompositePrimitive> supportedPrimitives;
358 auto result = getHal()->getSupportedPrimitives(&supportedPrimitives);
359 return HalResult<std::vector<CompositePrimitive>>::fromStatus(result, supportedPrimitives);
360}
361
Lais Andrade965284b2021-03-19 20:58:15 +0000362HalResult<std::vector<milliseconds>> AidlHalWrapper::getPrimitiveDurationsInternal(
363 const std::vector<CompositePrimitive>& supportedPrimitives) {
364 std::vector<milliseconds> durations;
365 constexpr auto primitiveRange = enum_range<CompositePrimitive>();
366 constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
367 durations.resize(primitiveCount);
368
369 for (auto primitive : supportedPrimitives) {
370 auto primitiveIdx = static_cast<size_t>(primitive);
371 if (primitiveIdx >= durations.size()) {
372 // Safety check, should not happen if enum_range is correct.
373 continue;
374 }
375 int32_t duration = 0;
376 auto status = getHal()->getPrimitiveDuration(primitive, &duration);
377 if (!status.isOk()) {
378 return HalResult<std::vector<milliseconds>>::failed(status.toString8().c_str());
379 }
380 durations[primitiveIdx] = milliseconds(duration);
381 }
382
383 return HalResult<std::vector<milliseconds>>::ok(durations);
384}
385
Lais Andrade92f2af52021-03-22 16:12:50 +0000386HalResult<float> AidlHalWrapper::getMinFrequencyInternal() {
387 float minFrequency = 0;
388 auto result = getHal()->getFrequencyMinimum(&minFrequency);
389 return HalResult<float>::fromStatus(result, minFrequency);
390}
391
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000392HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() {
393 float f0 = 0;
394 auto result = getHal()->getResonantFrequency(&f0);
395 return HalResult<float>::fromStatus(result, f0);
396}
397
Lais Andrade92f2af52021-03-22 16:12:50 +0000398HalResult<float> AidlHalWrapper::getFrequencyResolutionInternal() {
399 float frequencyResolution = 0;
400 auto result = getHal()->getFrequencyResolution(&frequencyResolution);
401 return HalResult<float>::fromStatus(result, frequencyResolution);
402}
403
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000404HalResult<float> AidlHalWrapper::getQFactorInternal() {
405 float qFactor = 0;
406 auto result = getHal()->getQFactor(&qFactor);
407 return HalResult<float>::fromStatus(result, qFactor);
408}
409
Lais Andrade92f2af52021-03-22 16:12:50 +0000410HalResult<std::vector<float>> AidlHalWrapper::getMaxAmplitudesInternal() {
411 std::vector<float> amplitudes;
412 auto result = getHal()->getBandwidthAmplitudeMap(&amplitudes);
413 return HalResult<std::vector<float>>::fromStatus(result, amplitudes);
414}
415
Lais Andradecfd81152020-07-01 09:00:26 +0000416sp<Aidl::IVibrator> AidlHalWrapper::getHal() {
417 std::lock_guard<std::mutex> lock(mHandleMutex);
418 return mHandle;
419}
420
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100421// -------------------------------------------------------------------------------------------------
422
Lais Andradecfd81152020-07-01 09:00:26 +0000423template <typename I>
424HalResult<void> HidlHalWrapper<I>::ping() {
425 auto result = getHal()->ping();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100426 return HalResult<void>::fromReturn(result);
427}
428
Lais Andradecfd81152020-07-01 09:00:26 +0000429template <typename I>
430void HidlHalWrapper<I>::tryReconnect() {
431 sp<I> newHandle = I::tryGetService();
432 if (newHandle) {
433 std::lock_guard<std::mutex> lock(mHandleMutex);
434 mHandle = std::move(newHandle);
435 }
436}
437
438template <typename I>
439HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
440 const std::function<void()>& completionCallback) {
441 auto result = getHal()->on(timeout.count());
Lais Andrade10d9dc72020-05-20 12:00:49 +0000442 auto ret = HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
443 if (ret.isOk()) {
444 mCallbackScheduler->schedule(completionCallback, timeout);
445 }
446 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100447}
448
Lais Andradecfd81152020-07-01 09:00:26 +0000449template <typename I>
450HalResult<void> HidlHalWrapper<I>::off() {
451 auto result = getHal()->off();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100452 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
453}
454
Lais Andradecfd81152020-07-01 09:00:26 +0000455template <typename I>
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000456HalResult<void> HidlHalWrapper<I>::setAmplitude(float amplitude) {
457 uint8_t amp = static_cast<uint8_t>(amplitude * std::numeric_limits<uint8_t>::max());
458 auto result = getHal()->setAmplitude(amp);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100459 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
460}
461
Lais Andradecfd81152020-07-01 09:00:26 +0000462template <typename I>
463HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100464 ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
465 return HalResult<void>::unsupported();
466}
467
Lais Andradecfd81152020-07-01 09:00:26 +0000468template <typename I>
469HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100470 ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
471 return HalResult<void>::unsupported();
472}
473
Lais Andradecfd81152020-07-01 09:00:26 +0000474template <typename I>
475HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100476 ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
477 return HalResult<void>::unsupported();
478}
479
Lais Andradecfd81152020-07-01 09:00:26 +0000480template <typename I>
Lais Andradecfd81152020-07-01 09:00:26 +0000481HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
482 hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
Lais Andraded39ff7d2020-05-19 10:42:51 +0000483 Capabilities capabilities =
484 result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
485 return HalResult<Capabilities>::fromReturn(result, capabilities);
486}
487
Lais Andradecfd81152020-07-01 09:00:26 +0000488template <typename I>
489template <typename T>
490HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
491 perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
Lais Andrade10d9dc72020-05-20 12:00:49 +0000492 const std::function<void()>& completionCallback) {
493 V1_0::Status status;
494 int32_t lengthMs;
495 auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
496 status = retStatus;
497 lengthMs = retLengthMs;
498 };
499
500 V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
501 auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
502 milliseconds length = milliseconds(lengthMs);
503
504 auto ret = HalResult<milliseconds>::fromReturn(result, status, length);
505 if (ret.isOk()) {
506 mCallbackScheduler->schedule(completionCallback, length);
507 }
508
509 return ret;
510}
511
Lais Andradecfd81152020-07-01 09:00:26 +0000512template <typename I>
513sp<I> HidlHalWrapper<I>::getHal() {
514 std::lock_guard<std::mutex> lock(mHandleMutex);
515 return mHandle;
516}
517
518// -------------------------------------------------------------------------------------------------
519
520HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
Lais Andrade10d9dc72020-05-20 12:00:49 +0000521 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andradecfd81152020-07-01 09:00:26 +0000522 if (isStaticCastValid<V1_0::Effect>(effect)) {
523 return performInternal(&V1_0::IVibrator::perform, getHal(),
524 static_cast<V1_0::Effect>(effect), strength, completionCallback);
525 }
526
527 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
528 Aidl::toString(effect).c_str());
529 return HalResult<milliseconds>::unsupported();
Lais Andrade10d9dc72020-05-20 12:00:49 +0000530}
531
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100532// -------------------------------------------------------------------------------------------------
533
Lais Andrade10d9dc72020-05-20 12:00:49 +0000534HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
535 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100536 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000537 return performInternal(&V1_1::IVibrator::perform, getHal(),
538 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100539 }
540 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000541 return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
542 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100543 }
544
545 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
546 Aidl::toString(effect).c_str());
547 return HalResult<milliseconds>::unsupported();
548}
549
550// -------------------------------------------------------------------------------------------------
551
Lais Andrade10d9dc72020-05-20 12:00:49 +0000552HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
553 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100554 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000555 return performInternal(&V1_2::IVibrator::perform, getHal(),
556 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100557 }
558 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000559 return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
560 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100561 }
562 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000563 return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
564 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100565 }
566
567 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
568 Aidl::toString(effect).c_str());
569 return HalResult<milliseconds>::unsupported();
570}
571
572// -------------------------------------------------------------------------------------------------
573
574HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000575 auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100576 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
577}
578
Lais Andrade10d9dc72020-05-20 12:00:49 +0000579HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
580 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100581 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000582 return performInternal(&V1_3::IVibrator::perform, getHal(),
583 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100584 }
585 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000586 return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
587 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100588 }
589 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000590 return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
591 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100592 }
593 if (isStaticCastValid<V1_3::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000594 return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
595 static_cast<V1_3::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100596 }
597
598 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
599 Aidl::toString(effect).c_str());
600 return HalResult<milliseconds>::unsupported();
601}
602
Lais Andraded39ff7d2020-05-19 10:42:51 +0000603HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
Lais Andrade08666612020-08-07 16:16:31 +0000604 Capabilities capabilities = Capabilities::NONE;
605
Lais Andradecfd81152020-07-01 09:00:26 +0000606 sp<V1_3::IVibrator> hal = getHal();
607 auto amplitudeResult = hal->supportsAmplitudeControl();
608 if (!amplitudeResult.isOk()) {
Lais Andrade08666612020-08-07 16:16:31 +0000609 return HalResult<Capabilities>::fromReturn(amplitudeResult, capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000610 }
611
Lais Andradecfd81152020-07-01 09:00:26 +0000612 auto externalControlResult = hal->supportsExternalControl();
Lais Andradecfd81152020-07-01 09:00:26 +0000613 if (amplitudeResult.withDefault(false)) {
614 capabilities |= Capabilities::AMPLITUDE_CONTROL;
615 }
616 if (externalControlResult.withDefault(false)) {
617 capabilities |= Capabilities::EXTERNAL_CONTROL;
Lais Andrade602ff962020-08-27 12:02:53 +0000618
619 if (amplitudeResult.withDefault(false)) {
620 capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL;
621 }
Lais Andradecfd81152020-07-01 09:00:26 +0000622 }
623
624 return HalResult<Capabilities>::fromReturn(externalControlResult, capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000625}
626
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100627// -------------------------------------------------------------------------------------------------
628
629}; // namespace vibrator
630
631}; // namespace android