blob: 63ecaec06ff1d7d910c8ceef3aef64fe4466a66d [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 }
Lais Andrade4aa80c92021-06-03 17:20:16 +0100138 if (mInfoCache.mPrimitiveDelayMax.isFailed()) {
139 mInfoCache.mPrimitiveDelayMax = getPrimitiveDelayMaxInternal();
140 }
141 if (mInfoCache.mPwlePrimitiveDurationMax.isFailed()) {
142 mInfoCache.mPwlePrimitiveDurationMax = getPrimitiveDurationMaxInternal();
143 }
144 if (mInfoCache.mCompositionSizeMax.isFailed()) {
145 mInfoCache.mCompositionSizeMax = getCompositionSizeMaxInternal();
146 }
147 if (mInfoCache.mPwleSizeMax.isFailed()) {
148 mInfoCache.mPwleSizeMax = getPwleSizeMaxInternal();
149 }
Lais Andrade92f2af52021-03-22 16:12:50 +0000150 if (mInfoCache.mMinFrequency.isFailed()) {
151 mInfoCache.mMinFrequency = getMinFrequencyInternal();
152 }
Lais Andrade965284b2021-03-19 20:58:15 +0000153 if (mInfoCache.mResonantFrequency.isFailed()) {
154 mInfoCache.mResonantFrequency = getResonantFrequencyInternal();
155 }
Lais Andrade92f2af52021-03-22 16:12:50 +0000156 if (mInfoCache.mFrequencyResolution.isFailed()) {
157 mInfoCache.mFrequencyResolution = getFrequencyResolutionInternal();
158 }
Lais Andrade965284b2021-03-19 20:58:15 +0000159 if (mInfoCache.mQFactor.isFailed()) {
160 mInfoCache.mQFactor = getQFactorInternal();
161 }
Lais Andrade92f2af52021-03-22 16:12:50 +0000162 if (mInfoCache.mMaxAmplitudes.isFailed()) {
163 mInfoCache.mMaxAmplitudes = getMaxAmplitudesInternal();
164 }
Lais Andrade965284b2021-03-19 20:58:15 +0000165 return mInfoCache.get();
166}
167
Lais Andrade92f2af52021-03-22 16:12:50 +0000168HalResult<milliseconds> HalWrapper::performComposedEffect(const std::vector<CompositeEffect>&,
169 const std::function<void()>&) {
170 ALOGV("Skipped performComposedEffect because it's not available in Vibrator HAL");
171 return HalResult<milliseconds>::unsupported();
172}
173
174HalResult<void> HalWrapper::performPwleEffect(const std::vector<PrimitivePwle>&,
175 const std::function<void()>&) {
176 ALOGV("Skipped performPwleEffect because it's not available in Vibrator HAL");
177 return HalResult<void>::unsupported();
178}
179
Lais Andrade965284b2021-03-19 20:58:15 +0000180HalResult<Capabilities> HalWrapper::getCapabilities() {
181 std::lock_guard<std::mutex> lock(mInfoMutex);
182 if (mInfoCache.mCapabilities.isFailed()) {
183 mInfoCache.mCapabilities = getCapabilitiesInternal();
184 }
185 return mInfoCache.mCapabilities;
186}
187
188HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurations() {
189 std::lock_guard<std::mutex> lock(mInfoMutex);
190 if (mInfoCache.mSupportedPrimitives.isFailed()) {
191 mInfoCache.mSupportedPrimitives = getSupportedPrimitivesInternal();
192 if (mInfoCache.mSupportedPrimitives.isUnsupported()) {
193 mInfoCache.mPrimitiveDurations = HalResult<std::vector<milliseconds>>::unsupported();
194 }
195 }
196 if (mInfoCache.mPrimitiveDurations.isFailed() && mInfoCache.mSupportedPrimitives.isOk()) {
197 mInfoCache.mPrimitiveDurations =
198 getPrimitiveDurationsInternal(mInfoCache.mSupportedPrimitives.value());
199 }
200 return mInfoCache.mPrimitiveDurations;
201}
202
203HalResult<std::vector<Effect>> HalWrapper::getSupportedEffectsInternal() {
204 ALOGV("Skipped getSupportedEffects because it's not available in Vibrator HAL");
205 return HalResult<std::vector<Effect>>::unsupported();
206}
207
Lais Andrade92f2af52021-03-22 16:12:50 +0000208HalResult<std::vector<Braking>> HalWrapper::getSupportedBrakingInternal() {
209 ALOGV("Skipped getSupportedBraking because it's not available in Vibrator HAL");
210 return HalResult<std::vector<Braking>>::unsupported();
211}
212
Lais Andrade965284b2021-03-19 20:58:15 +0000213HalResult<std::vector<CompositePrimitive>> HalWrapper::getSupportedPrimitivesInternal() {
214 ALOGV("Skipped getSupportedPrimitives because it's not available in Vibrator HAL");
215 return HalResult<std::vector<CompositePrimitive>>::unsupported();
216}
217
218HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurationsInternal(
219 const std::vector<CompositePrimitive>&) {
220 ALOGV("Skipped getPrimitiveDurations because it's not available in Vibrator HAL");
221 return HalResult<std::vector<milliseconds>>::unsupported();
222}
223
Lais Andrade4aa80c92021-06-03 17:20:16 +0100224HalResult<milliseconds> HalWrapper::getPrimitiveDelayMaxInternal() {
225 ALOGV("Skipped getPrimitiveDelayMaxInternal because it's not available in Vibrator HAL");
226 return HalResult<milliseconds>::unsupported();
227}
228
229HalResult<milliseconds> HalWrapper::getPrimitiveDurationMaxInternal() {
230 ALOGV("Skipped getPrimitiveDurationMaxInternal because it's not available in Vibrator HAL");
231 return HalResult<milliseconds>::unsupported();
232}
233
234HalResult<int32_t> HalWrapper::getCompositionSizeMaxInternal() {
235 ALOGV("Skipped getCompositionSizeMaxInternal because it's not available in Vibrator HAL");
236 return HalResult<int32_t>::unsupported();
237}
238
239HalResult<int32_t> HalWrapper::getPwleSizeMaxInternal() {
240 ALOGV("Skipped getPwleSizeMaxInternal because it's not available in Vibrator HAL");
241 return HalResult<int32_t>::unsupported();
242}
243
Lais Andrade92f2af52021-03-22 16:12:50 +0000244HalResult<float> HalWrapper::getMinFrequencyInternal() {
245 ALOGV("Skipped getMinFrequency because it's not available in Vibrator HAL");
246 return HalResult<float>::unsupported();
247}
248
Lais Andrade965284b2021-03-19 20:58:15 +0000249HalResult<float> HalWrapper::getResonantFrequencyInternal() {
250 ALOGV("Skipped getResonantFrequency because it's not available in Vibrator HAL");
251 return HalResult<float>::unsupported();
252}
253
Lais Andrade92f2af52021-03-22 16:12:50 +0000254HalResult<float> HalWrapper::getFrequencyResolutionInternal() {
255 ALOGV("Skipped getFrequencyResolution because it's not available in Vibrator HAL");
256 return HalResult<float>::unsupported();
257}
258
Lais Andrade965284b2021-03-19 20:58:15 +0000259HalResult<float> HalWrapper::getQFactorInternal() {
260 ALOGV("Skipped getQFactor because it's not available in Vibrator HAL");
261 return HalResult<float>::unsupported();
262}
263
Lais Andrade92f2af52021-03-22 16:12:50 +0000264HalResult<std::vector<float>> HalWrapper::getMaxAmplitudesInternal() {
265 ALOGV("Skipped getMaxAmplitudes because it's not available in Vibrator HAL");
266 return HalResult<std::vector<float>>::unsupported();
267}
268
Lais Andrade965284b2021-03-19 20:58:15 +0000269// -------------------------------------------------------------------------------------------------
270
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100271HalResult<void> AidlHalWrapper::ping() {
Lais Andrade08666612020-08-07 16:16:31 +0000272 return HalResult<void>::fromStatus(IInterface::asBinder(getHal())->pingBinder());
Lais Andradecfd81152020-07-01 09:00:26 +0000273}
274
275void AidlHalWrapper::tryReconnect() {
Lais Andrade98c97032020-11-17 19:23:01 +0000276 auto result = mReconnectFn();
277 if (!result.isOk()) {
278 return;
279 }
280 sp<Aidl::IVibrator> newHandle = result.value();
Lais Andradecfd81152020-07-01 09:00:26 +0000281 if (newHandle) {
282 std::lock_guard<std::mutex> lock(mHandleMutex);
283 mHandle = std::move(newHandle);
284 }
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100285}
286
287HalResult<void> AidlHalWrapper::on(milliseconds timeout,
288 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::ON_CALLBACK);
292 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
293
Lais Andradecfd81152020-07-01 09:00:26 +0000294 auto ret = HalResult<void>::fromStatus(getHal()->on(timeout.count(), cb));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000295 if (!supportsCallback && ret.isOk()) {
296 mCallbackScheduler->schedule(completionCallback, timeout);
297 }
298
299 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100300}
301
302HalResult<void> AidlHalWrapper::off() {
Lais Andradecfd81152020-07-01 09:00:26 +0000303 return HalResult<void>::fromStatus(getHal()->off());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100304}
305
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000306HalResult<void> AidlHalWrapper::setAmplitude(float amplitude) {
307 return HalResult<void>::fromStatus(getHal()->setAmplitude(amplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100308}
309
310HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000311 return HalResult<void>::fromStatus(getHal()->setExternalControl(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100312}
313
314HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
Lais Andradecfd81152020-07-01 09:00:26 +0000315 return HalResult<void>::fromStatus(getHal()->alwaysOnEnable(id, effect, strength));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100316}
317
318HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
Lais Andradecfd81152020-07-01 09:00:26 +0000319 return HalResult<void>::fromStatus(getHal()->alwaysOnDisable(id));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100320}
321
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100322HalResult<milliseconds> AidlHalWrapper::performEffect(
323 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000324 HalResult<Capabilities> capabilities = getCapabilities();
325 bool supportsCallback = capabilities.isOk() &&
326 static_cast<int32_t>(capabilities.value() & Capabilities::PERFORM_CALLBACK);
327 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
328
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100329 int32_t lengthMs;
Lais Andradecfd81152020-07-01 09:00:26 +0000330 auto result = getHal()->perform(effect, strength, cb, &lengthMs);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000331 milliseconds length = milliseconds(lengthMs);
332
333 auto ret = HalResult<milliseconds>::fromStatus(result, length);
334 if (!supportsCallback && ret.isOk()) {
335 mCallbackScheduler->schedule(completionCallback, length);
336 }
337
338 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100339}
340
Lais Andrade49b60b12021-02-23 13:27:41 +0000341HalResult<milliseconds> AidlHalWrapper::performComposedEffect(
Lais Andrade92f2af52021-03-22 16:12:50 +0000342 const std::vector<CompositeEffect>& primitives,
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100343 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000344 // This method should always support callbacks, so no need to double check.
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100345 auto cb = new HalCallbackWrapper(completionCallback);
Lais Andrade965284b2021-03-19 20:58:15 +0000346
347 auto durations = getPrimitiveDurations().valueOr({});
Lais Andrade49b60b12021-02-23 13:27:41 +0000348 milliseconds duration(0);
Lais Andrade92f2af52021-03-22 16:12:50 +0000349 for (const auto& effect : primitives) {
Lais Andrade965284b2021-03-19 20:58:15 +0000350 auto primitiveIdx = static_cast<size_t>(effect.primitive);
351 if (primitiveIdx < durations.size()) {
352 duration += durations[primitiveIdx];
353 } else {
354 // Make sure the returned duration is positive to indicate successful vibration.
355 duration += milliseconds(1);
Lais Andrade49b60b12021-02-23 13:27:41 +0000356 }
357 duration += milliseconds(effect.delayMs);
358 }
Lais Andrade49b60b12021-02-23 13:27:41 +0000359
Lais Andrade92f2af52021-03-22 16:12:50 +0000360 return HalResult<milliseconds>::fromStatus(getHal()->compose(primitives, cb), duration);
361}
362
363HalResult<void> AidlHalWrapper::performPwleEffect(const std::vector<PrimitivePwle>& primitives,
364 const std::function<void()>& completionCallback) {
365 // This method should always support callbacks, so no need to double check.
366 auto cb = new HalCallbackWrapper(completionCallback);
367 return HalResult<void>::fromStatus(getHal()->composePwle(primitives, cb));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100368}
369
Lais Andrade10d9dc72020-05-20 12:00:49 +0000370HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
371 int32_t capabilities = 0;
Lais Andradecfd81152020-07-01 09:00:26 +0000372 auto result = getHal()->getCapabilities(&capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000373 return HalResult<Capabilities>::fromStatus(result, static_cast<Capabilities>(capabilities));
374}
375
376HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
377 std::vector<Effect> supportedEffects;
Lais Andradecfd81152020-07-01 09:00:26 +0000378 auto result = getHal()->getSupportedEffects(&supportedEffects);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000379 return HalResult<std::vector<Effect>>::fromStatus(result, supportedEffects);
380}
381
Lais Andrade92f2af52021-03-22 16:12:50 +0000382HalResult<std::vector<Braking>> AidlHalWrapper::getSupportedBrakingInternal() {
383 std::vector<Braking> supportedBraking;
384 auto result = getHal()->getSupportedBraking(&supportedBraking);
385 return HalResult<std::vector<Braking>>::fromStatus(result, supportedBraking);
386}
387
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000388HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() {
389 std::vector<CompositePrimitive> supportedPrimitives;
390 auto result = getHal()->getSupportedPrimitives(&supportedPrimitives);
391 return HalResult<std::vector<CompositePrimitive>>::fromStatus(result, supportedPrimitives);
392}
393
Lais Andrade965284b2021-03-19 20:58:15 +0000394HalResult<std::vector<milliseconds>> AidlHalWrapper::getPrimitiveDurationsInternal(
395 const std::vector<CompositePrimitive>& supportedPrimitives) {
396 std::vector<milliseconds> durations;
397 constexpr auto primitiveRange = enum_range<CompositePrimitive>();
398 constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
399 durations.resize(primitiveCount);
400
401 for (auto primitive : supportedPrimitives) {
402 auto primitiveIdx = static_cast<size_t>(primitive);
403 if (primitiveIdx >= durations.size()) {
404 // Safety check, should not happen if enum_range is correct.
Lais Andrade4928bfd2021-08-25 18:21:12 +0100405 ALOGE("Supported primitive %zu is outside range [0,%zu), skipping load duration",
406 primitiveIdx, durations.size());
Lais Andrade965284b2021-03-19 20:58:15 +0000407 continue;
408 }
409 int32_t duration = 0;
Lais Andrade4928bfd2021-08-25 18:21:12 +0100410 auto result = getHal()->getPrimitiveDuration(primitive, &duration);
411 auto halResult = HalResult<int32_t>::fromStatus(result, duration);
412 if (halResult.isUnsupported()) {
413 // Should not happen, supported primitives should always support requesting duration.
414 ALOGE("Supported primitive %zu returned unsupported for getPrimitiveDuration",
415 primitiveIdx);
416 }
417 if (halResult.isFailed()) {
418 // Fail entire request if one request has failed.
419 return HalResult<std::vector<milliseconds>>::failed(result.toString8().c_str());
Lais Andrade965284b2021-03-19 20:58:15 +0000420 }
421 durations[primitiveIdx] = milliseconds(duration);
422 }
423
424 return HalResult<std::vector<milliseconds>>::ok(durations);
425}
426
Lais Andrade4aa80c92021-06-03 17:20:16 +0100427HalResult<milliseconds> AidlHalWrapper::getPrimitiveDelayMaxInternal() {
428 int32_t delay = 0;
429 auto result = getHal()->getCompositionDelayMax(&delay);
430 return HalResult<milliseconds>::fromStatus(result, milliseconds(delay));
431}
432
433HalResult<milliseconds> AidlHalWrapper::getPrimitiveDurationMaxInternal() {
434 int32_t delay = 0;
435 auto result = getHal()->getPwlePrimitiveDurationMax(&delay);
436 return HalResult<milliseconds>::fromStatus(result, milliseconds(delay));
437}
438
439HalResult<int32_t> AidlHalWrapper::getCompositionSizeMaxInternal() {
440 int32_t size = 0;
441 auto result = getHal()->getCompositionSizeMax(&size);
442 return HalResult<int32_t>::fromStatus(result, size);
443}
444
445HalResult<int32_t> AidlHalWrapper::getPwleSizeMaxInternal() {
446 int32_t size = 0;
447 auto result = getHal()->getPwleCompositionSizeMax(&size);
448 return HalResult<int32_t>::fromStatus(result, size);
449}
450
Lais Andrade92f2af52021-03-22 16:12:50 +0000451HalResult<float> AidlHalWrapper::getMinFrequencyInternal() {
452 float minFrequency = 0;
453 auto result = getHal()->getFrequencyMinimum(&minFrequency);
454 return HalResult<float>::fromStatus(result, minFrequency);
455}
456
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000457HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() {
458 float f0 = 0;
459 auto result = getHal()->getResonantFrequency(&f0);
460 return HalResult<float>::fromStatus(result, f0);
461}
462
Lais Andrade92f2af52021-03-22 16:12:50 +0000463HalResult<float> AidlHalWrapper::getFrequencyResolutionInternal() {
464 float frequencyResolution = 0;
465 auto result = getHal()->getFrequencyResolution(&frequencyResolution);
466 return HalResult<float>::fromStatus(result, frequencyResolution);
467}
468
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000469HalResult<float> AidlHalWrapper::getQFactorInternal() {
470 float qFactor = 0;
471 auto result = getHal()->getQFactor(&qFactor);
472 return HalResult<float>::fromStatus(result, qFactor);
473}
474
Lais Andrade92f2af52021-03-22 16:12:50 +0000475HalResult<std::vector<float>> AidlHalWrapper::getMaxAmplitudesInternal() {
476 std::vector<float> amplitudes;
477 auto result = getHal()->getBandwidthAmplitudeMap(&amplitudes);
478 return HalResult<std::vector<float>>::fromStatus(result, amplitudes);
479}
480
Lais Andradecfd81152020-07-01 09:00:26 +0000481sp<Aidl::IVibrator> AidlHalWrapper::getHal() {
482 std::lock_guard<std::mutex> lock(mHandleMutex);
483 return mHandle;
484}
485
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100486// -------------------------------------------------------------------------------------------------
487
Lais Andradecfd81152020-07-01 09:00:26 +0000488template <typename I>
489HalResult<void> HidlHalWrapper<I>::ping() {
490 auto result = getHal()->ping();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100491 return HalResult<void>::fromReturn(result);
492}
493
Lais Andradecfd81152020-07-01 09:00:26 +0000494template <typename I>
495void HidlHalWrapper<I>::tryReconnect() {
496 sp<I> newHandle = I::tryGetService();
497 if (newHandle) {
498 std::lock_guard<std::mutex> lock(mHandleMutex);
499 mHandle = std::move(newHandle);
500 }
501}
502
503template <typename I>
504HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
505 const std::function<void()>& completionCallback) {
506 auto result = getHal()->on(timeout.count());
Lais Andrade10d9dc72020-05-20 12:00:49 +0000507 auto ret = HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
508 if (ret.isOk()) {
509 mCallbackScheduler->schedule(completionCallback, timeout);
510 }
511 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100512}
513
Lais Andradecfd81152020-07-01 09:00:26 +0000514template <typename I>
515HalResult<void> HidlHalWrapper<I>::off() {
516 auto result = getHal()->off();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100517 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
518}
519
Lais Andradecfd81152020-07-01 09:00:26 +0000520template <typename I>
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000521HalResult<void> HidlHalWrapper<I>::setAmplitude(float amplitude) {
522 uint8_t amp = static_cast<uint8_t>(amplitude * std::numeric_limits<uint8_t>::max());
523 auto result = getHal()->setAmplitude(amp);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100524 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
525}
526
Lais Andradecfd81152020-07-01 09:00:26 +0000527template <typename I>
528HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100529 ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
530 return HalResult<void>::unsupported();
531}
532
Lais Andradecfd81152020-07-01 09:00:26 +0000533template <typename I>
534HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100535 ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
536 return HalResult<void>::unsupported();
537}
538
Lais Andradecfd81152020-07-01 09:00:26 +0000539template <typename I>
540HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100541 ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
542 return HalResult<void>::unsupported();
543}
544
Lais Andradecfd81152020-07-01 09:00:26 +0000545template <typename I>
Lais Andradecfd81152020-07-01 09:00:26 +0000546HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
547 hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
Lais Andraded39ff7d2020-05-19 10:42:51 +0000548 Capabilities capabilities =
549 result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
550 return HalResult<Capabilities>::fromReturn(result, capabilities);
551}
552
Lais Andradecfd81152020-07-01 09:00:26 +0000553template <typename I>
554template <typename T>
555HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
556 perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
Lais Andrade10d9dc72020-05-20 12:00:49 +0000557 const std::function<void()>& completionCallback) {
558 V1_0::Status status;
559 int32_t lengthMs;
560 auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
561 status = retStatus;
562 lengthMs = retLengthMs;
563 };
564
565 V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
566 auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
567 milliseconds length = milliseconds(lengthMs);
568
569 auto ret = HalResult<milliseconds>::fromReturn(result, status, length);
570 if (ret.isOk()) {
571 mCallbackScheduler->schedule(completionCallback, length);
572 }
573
574 return ret;
575}
576
Lais Andradecfd81152020-07-01 09:00:26 +0000577template <typename I>
578sp<I> HidlHalWrapper<I>::getHal() {
579 std::lock_guard<std::mutex> lock(mHandleMutex);
580 return mHandle;
581}
582
583// -------------------------------------------------------------------------------------------------
584
585HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
Lais Andrade10d9dc72020-05-20 12:00:49 +0000586 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andradecfd81152020-07-01 09:00:26 +0000587 if (isStaticCastValid<V1_0::Effect>(effect)) {
588 return performInternal(&V1_0::IVibrator::perform, getHal(),
589 static_cast<V1_0::Effect>(effect), strength, completionCallback);
590 }
591
592 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
593 Aidl::toString(effect).c_str());
594 return HalResult<milliseconds>::unsupported();
Lais Andrade10d9dc72020-05-20 12:00:49 +0000595}
596
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100597// -------------------------------------------------------------------------------------------------
598
Lais Andrade10d9dc72020-05-20 12:00:49 +0000599HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
600 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100601 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000602 return performInternal(&V1_1::IVibrator::perform, getHal(),
603 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100604 }
605 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000606 return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
607 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100608 }
609
610 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
611 Aidl::toString(effect).c_str());
612 return HalResult<milliseconds>::unsupported();
613}
614
615// -------------------------------------------------------------------------------------------------
616
Lais Andrade10d9dc72020-05-20 12:00:49 +0000617HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
618 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100619 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000620 return performInternal(&V1_2::IVibrator::perform, getHal(),
621 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100622 }
623 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000624 return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
625 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100626 }
627 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000628 return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
629 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100630 }
631
632 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
633 Aidl::toString(effect).c_str());
634 return HalResult<milliseconds>::unsupported();
635}
636
637// -------------------------------------------------------------------------------------------------
638
639HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000640 auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100641 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
642}
643
Lais Andrade10d9dc72020-05-20 12:00:49 +0000644HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
645 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100646 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000647 return performInternal(&V1_3::IVibrator::perform, getHal(),
648 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100649 }
650 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000651 return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
652 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100653 }
654 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000655 return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
656 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100657 }
658 if (isStaticCastValid<V1_3::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000659 return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
660 static_cast<V1_3::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100661 }
662
663 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
664 Aidl::toString(effect).c_str());
665 return HalResult<milliseconds>::unsupported();
666}
667
Lais Andraded39ff7d2020-05-19 10:42:51 +0000668HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
Lais Andrade08666612020-08-07 16:16:31 +0000669 Capabilities capabilities = Capabilities::NONE;
670
Lais Andradecfd81152020-07-01 09:00:26 +0000671 sp<V1_3::IVibrator> hal = getHal();
672 auto amplitudeResult = hal->supportsAmplitudeControl();
673 if (!amplitudeResult.isOk()) {
Lais Andrade08666612020-08-07 16:16:31 +0000674 return HalResult<Capabilities>::fromReturn(amplitudeResult, capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000675 }
676
Lais Andradecfd81152020-07-01 09:00:26 +0000677 auto externalControlResult = hal->supportsExternalControl();
Lais Andradecfd81152020-07-01 09:00:26 +0000678 if (amplitudeResult.withDefault(false)) {
679 capabilities |= Capabilities::AMPLITUDE_CONTROL;
680 }
681 if (externalControlResult.withDefault(false)) {
682 capabilities |= Capabilities::EXTERNAL_CONTROL;
Lais Andrade602ff962020-08-27 12:02:53 +0000683
684 if (amplitudeResult.withDefault(false)) {
685 capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL;
686 }
Lais Andradecfd81152020-07-01 09:00:26 +0000687 }
688
689 return HalResult<Capabilities>::fromReturn(externalControlResult, capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000690}
691
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100692// -------------------------------------------------------------------------------------------------
693
694}; // namespace vibrator
695
696}; // namespace android