blob: 3ddc4f2aca5740e3174c011c4bff2351551a94fe [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
Lais Andrade818a2252024-06-24 14:48:14 +010019#include <aidl/android/hardware/vibrator/IVibrator.h>
Lais Andrade9e9fcc92020-04-07 20:13:08 +010020#include <android/hardware/vibrator/1.3/IVibrator.h>
Lais Andrade9e9fcc92020-04-07 20:13:08 +010021#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 Andrade818a2252024-06-24 14:48:14 +010029using aidl::android::hardware::vibrator::Braking;
30using aidl::android::hardware::vibrator::CompositeEffect;
31using aidl::android::hardware::vibrator::CompositePrimitive;
Ahmad Khalil754a9cc2024-09-28 20:12:14 +000032using aidl::android::hardware::vibrator::CompositePwleV2;
Lais Andrade818a2252024-06-24 14:48:14 +010033using aidl::android::hardware::vibrator::Effect;
34using aidl::android::hardware::vibrator::EffectStrength;
Ahmad Khalil754a9cc2024-09-28 20:12:14 +000035using aidl::android::hardware::vibrator::FrequencyAccelerationMapEntry;
Lais Andrade818a2252024-06-24 14:48:14 +010036using aidl::android::hardware::vibrator::PrimitivePwle;
Lais Andradef172ea12024-07-12 13:45:01 +010037using aidl::android::hardware::vibrator::VendorEffect;
Lais Andrade9e9fcc92020-04-07 20:13:08 +010038
39using std::chrono::milliseconds;
40
41namespace V1_0 = android::hardware::vibrator::V1_0;
42namespace V1_1 = android::hardware::vibrator::V1_1;
43namespace V1_2 = android::hardware::vibrator::V1_2;
44namespace V1_3 = android::hardware::vibrator::V1_3;
Lais Andrade818a2252024-06-24 14:48:14 +010045namespace Aidl = aidl::android::hardware::vibrator;
Lais Andrade9e9fcc92020-04-07 20:13:08 +010046
47namespace android {
48
49namespace vibrator {
50
51// -------------------------------------------------------------------------------------------------
52
53template <class T>
54bool isStaticCastValid(Effect effect) {
55 T castEffect = static_cast<T>(effect);
56 auto iter = hardware::hidl_enum_range<T>();
57 return castEffect >= *iter.begin() && castEffect <= *std::prev(iter.end());
58}
59
Lais Andrade9e9fcc92020-04-07 20:13:08 +010060// -------------------------------------------------------------------------------------------------
61
Lais Andrade965284b2021-03-19 20:58:15 +000062Info HalWrapper::getInfo() {
63 getCapabilities();
64 getPrimitiveDurations();
65 std::lock_guard<std::mutex> lock(mInfoMutex);
66 if (mInfoCache.mSupportedEffects.isFailed()) {
67 mInfoCache.mSupportedEffects = getSupportedEffectsInternal();
68 }
Lais Andrade92f2af52021-03-22 16:12:50 +000069 if (mInfoCache.mSupportedBraking.isFailed()) {
70 mInfoCache.mSupportedBraking = getSupportedBrakingInternal();
71 }
Lais Andrade4aa80c92021-06-03 17:20:16 +010072 if (mInfoCache.mPrimitiveDelayMax.isFailed()) {
73 mInfoCache.mPrimitiveDelayMax = getPrimitiveDelayMaxInternal();
74 }
75 if (mInfoCache.mPwlePrimitiveDurationMax.isFailed()) {
76 mInfoCache.mPwlePrimitiveDurationMax = getPrimitiveDurationMaxInternal();
77 }
78 if (mInfoCache.mCompositionSizeMax.isFailed()) {
79 mInfoCache.mCompositionSizeMax = getCompositionSizeMaxInternal();
80 }
81 if (mInfoCache.mPwleSizeMax.isFailed()) {
82 mInfoCache.mPwleSizeMax = getPwleSizeMaxInternal();
83 }
Lais Andrade92f2af52021-03-22 16:12:50 +000084 if (mInfoCache.mMinFrequency.isFailed()) {
85 mInfoCache.mMinFrequency = getMinFrequencyInternal();
86 }
Lais Andrade965284b2021-03-19 20:58:15 +000087 if (mInfoCache.mResonantFrequency.isFailed()) {
88 mInfoCache.mResonantFrequency = getResonantFrequencyInternal();
89 }
Lais Andrade92f2af52021-03-22 16:12:50 +000090 if (mInfoCache.mFrequencyResolution.isFailed()) {
91 mInfoCache.mFrequencyResolution = getFrequencyResolutionInternal();
92 }
Lais Andrade965284b2021-03-19 20:58:15 +000093 if (mInfoCache.mQFactor.isFailed()) {
94 mInfoCache.mQFactor = getQFactorInternal();
95 }
Lais Andrade92f2af52021-03-22 16:12:50 +000096 if (mInfoCache.mMaxAmplitudes.isFailed()) {
97 mInfoCache.mMaxAmplitudes = getMaxAmplitudesInternal();
98 }
Ahmad Khalil193e37b2024-09-02 10:05:50 +000099 if (mInfoCache.mMaxEnvelopeEffectSize.isFailed()) {
100 mInfoCache.mMaxEnvelopeEffectSize = getMaxEnvelopeEffectSizeInternal();
101 }
102 if (mInfoCache.mMinEnvelopeEffectControlPointDuration.isFailed()) {
103 mInfoCache.mMinEnvelopeEffectControlPointDuration =
104 getMinEnvelopeEffectControlPointDurationInternal();
105 }
106 if (mInfoCache.mMaxEnvelopeEffectControlPointDuration.isFailed()) {
107 mInfoCache.mMaxEnvelopeEffectControlPointDuration =
108 getMaxEnvelopeEffectControlPointDurationInternal();
109 }
Ahmad Khalil648e8e62024-09-23 09:29:36 +0000110 if (mInfoCache.mFrequencyToOutputAccelerationMap.isFailed()) {
111 mInfoCache.mFrequencyToOutputAccelerationMap =
112 getFrequencyToOutputAccelerationMapInternal();
113 }
Lais Andrade965284b2021-03-19 20:58:15 +0000114 return mInfoCache.get();
115}
116
Lais Andradef172ea12024-07-12 13:45:01 +0100117HalResult<void> HalWrapper::performVendorEffect(const VendorEffect&, const std::function<void()>&) {
118 ALOGV("Skipped performVendorEffect because it's not available in Vibrator HAL");
119 return HalResult<void>::unsupported();
120}
121
Lais Andrade92f2af52021-03-22 16:12:50 +0000122HalResult<milliseconds> HalWrapper::performComposedEffect(const std::vector<CompositeEffect>&,
123 const std::function<void()>&) {
124 ALOGV("Skipped performComposedEffect because it's not available in Vibrator HAL");
125 return HalResult<milliseconds>::unsupported();
126}
127
128HalResult<void> HalWrapper::performPwleEffect(const std::vector<PrimitivePwle>&,
129 const std::function<void()>&) {
130 ALOGV("Skipped performPwleEffect because it's not available in Vibrator HAL");
131 return HalResult<void>::unsupported();
132}
133
Ahmad Khalil754a9cc2024-09-28 20:12:14 +0000134HalResult<void> HalWrapper::composePwleV2(const CompositePwleV2&, const std::function<void()>&) {
Ahmad Khalil11111892024-08-05 17:40:17 +0000135 ALOGV("Skipped composePwleV2 because it's not available in Vibrator HAL");
136 return HalResult<void>::unsupported();
137}
138
Lais Andrade965284b2021-03-19 20:58:15 +0000139HalResult<Capabilities> HalWrapper::getCapabilities() {
140 std::lock_guard<std::mutex> lock(mInfoMutex);
141 if (mInfoCache.mCapabilities.isFailed()) {
142 mInfoCache.mCapabilities = getCapabilitiesInternal();
143 }
144 return mInfoCache.mCapabilities;
145}
146
147HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurations() {
148 std::lock_guard<std::mutex> lock(mInfoMutex);
149 if (mInfoCache.mSupportedPrimitives.isFailed()) {
150 mInfoCache.mSupportedPrimitives = getSupportedPrimitivesInternal();
151 if (mInfoCache.mSupportedPrimitives.isUnsupported()) {
152 mInfoCache.mPrimitiveDurations = HalResult<std::vector<milliseconds>>::unsupported();
153 }
154 }
155 if (mInfoCache.mPrimitiveDurations.isFailed() && mInfoCache.mSupportedPrimitives.isOk()) {
156 mInfoCache.mPrimitiveDurations =
157 getPrimitiveDurationsInternal(mInfoCache.mSupportedPrimitives.value());
158 }
159 return mInfoCache.mPrimitiveDurations;
160}
161
162HalResult<std::vector<Effect>> HalWrapper::getSupportedEffectsInternal() {
163 ALOGV("Skipped getSupportedEffects because it's not available in Vibrator HAL");
164 return HalResult<std::vector<Effect>>::unsupported();
165}
166
Lais Andrade92f2af52021-03-22 16:12:50 +0000167HalResult<std::vector<Braking>> HalWrapper::getSupportedBrakingInternal() {
168 ALOGV("Skipped getSupportedBraking because it's not available in Vibrator HAL");
169 return HalResult<std::vector<Braking>>::unsupported();
170}
171
Lais Andrade965284b2021-03-19 20:58:15 +0000172HalResult<std::vector<CompositePrimitive>> HalWrapper::getSupportedPrimitivesInternal() {
173 ALOGV("Skipped getSupportedPrimitives because it's not available in Vibrator HAL");
174 return HalResult<std::vector<CompositePrimitive>>::unsupported();
175}
176
177HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurationsInternal(
178 const std::vector<CompositePrimitive>&) {
179 ALOGV("Skipped getPrimitiveDurations because it's not available in Vibrator HAL");
180 return HalResult<std::vector<milliseconds>>::unsupported();
181}
182
Lais Andrade4aa80c92021-06-03 17:20:16 +0100183HalResult<milliseconds> HalWrapper::getPrimitiveDelayMaxInternal() {
184 ALOGV("Skipped getPrimitiveDelayMaxInternal because it's not available in Vibrator HAL");
185 return HalResult<milliseconds>::unsupported();
186}
187
188HalResult<milliseconds> HalWrapper::getPrimitiveDurationMaxInternal() {
189 ALOGV("Skipped getPrimitiveDurationMaxInternal because it's not available in Vibrator HAL");
190 return HalResult<milliseconds>::unsupported();
191}
192
193HalResult<int32_t> HalWrapper::getCompositionSizeMaxInternal() {
194 ALOGV("Skipped getCompositionSizeMaxInternal because it's not available in Vibrator HAL");
195 return HalResult<int32_t>::unsupported();
196}
197
198HalResult<int32_t> HalWrapper::getPwleSizeMaxInternal() {
199 ALOGV("Skipped getPwleSizeMaxInternal because it's not available in Vibrator HAL");
200 return HalResult<int32_t>::unsupported();
201}
202
Lais Andrade92f2af52021-03-22 16:12:50 +0000203HalResult<float> HalWrapper::getMinFrequencyInternal() {
204 ALOGV("Skipped getMinFrequency because it's not available in Vibrator HAL");
205 return HalResult<float>::unsupported();
206}
207
Lais Andrade965284b2021-03-19 20:58:15 +0000208HalResult<float> HalWrapper::getResonantFrequencyInternal() {
209 ALOGV("Skipped getResonantFrequency because it's not available in Vibrator HAL");
210 return HalResult<float>::unsupported();
211}
212
Lais Andrade92f2af52021-03-22 16:12:50 +0000213HalResult<float> HalWrapper::getFrequencyResolutionInternal() {
214 ALOGV("Skipped getFrequencyResolution because it's not available in Vibrator HAL");
215 return HalResult<float>::unsupported();
216}
217
Lais Andrade965284b2021-03-19 20:58:15 +0000218HalResult<float> HalWrapper::getQFactorInternal() {
219 ALOGV("Skipped getQFactor because it's not available in Vibrator HAL");
220 return HalResult<float>::unsupported();
221}
222
Lais Andrade92f2af52021-03-22 16:12:50 +0000223HalResult<std::vector<float>> HalWrapper::getMaxAmplitudesInternal() {
224 ALOGV("Skipped getMaxAmplitudes because it's not available in Vibrator HAL");
225 return HalResult<std::vector<float>>::unsupported();
226}
Ahmad Khalil193e37b2024-09-02 10:05:50 +0000227HalResult<int32_t> HalWrapper::getMaxEnvelopeEffectSizeInternal() {
228 ALOGV("Skipped getMaxEnvelopeEffectSizeInternal because it's not available "
229 "in Vibrator HAL");
230 return HalResult<int32_t>::unsupported();
231}
232
233HalResult<milliseconds> HalWrapper::getMinEnvelopeEffectControlPointDurationInternal() {
234 ALOGV("Skipped getMinEnvelopeEffectControlPointDurationInternal because it's not "
235 "available in Vibrator HAL");
236 return HalResult<milliseconds>::unsupported();
237}
238
239HalResult<milliseconds> HalWrapper::getMaxEnvelopeEffectControlPointDurationInternal() {
240 ALOGV("Skipped getMaxEnvelopeEffectControlPointDurationInternal because it's not "
241 "available in Vibrator HAL");
242 return HalResult<milliseconds>::unsupported();
243}
Lais Andrade92f2af52021-03-22 16:12:50 +0000244
Ahmad Khalil754a9cc2024-09-28 20:12:14 +0000245HalResult<std::vector<FrequencyAccelerationMapEntry>>
Ahmad Khalil648e8e62024-09-23 09:29:36 +0000246HalWrapper::getFrequencyToOutputAccelerationMapInternal() {
247 ALOGV("Skipped getFrequencyToOutputAccelerationMapInternal because it's not "
248 "available in Vibrator HAL");
Ahmad Khalil754a9cc2024-09-28 20:12:14 +0000249 return HalResult<std::vector<FrequencyAccelerationMapEntry>>::unsupported();
Ahmad Khalil648e8e62024-09-23 09:29:36 +0000250}
251
Lais Andrade965284b2021-03-19 20:58:15 +0000252// -------------------------------------------------------------------------------------------------
253
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100254HalResult<void> AidlHalWrapper::ping() {
Lais Andrade818a2252024-06-24 14:48:14 +0100255 return HalResultFactory::fromStatus(AIBinder_ping(getHal()->asBinder().get()));
Lais Andradecfd81152020-07-01 09:00:26 +0000256}
257
258void AidlHalWrapper::tryReconnect() {
Lais Andrade98c97032020-11-17 19:23:01 +0000259 auto result = mReconnectFn();
260 if (!result.isOk()) {
261 return;
262 }
Lais Andrade818a2252024-06-24 14:48:14 +0100263 std::shared_ptr<Aidl::IVibrator> newHandle = result.value();
Lais Andradecfd81152020-07-01 09:00:26 +0000264 if (newHandle) {
265 std::lock_guard<std::mutex> lock(mHandleMutex);
266 mHandle = std::move(newHandle);
267 }
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100268}
269
270HalResult<void> AidlHalWrapper::on(milliseconds timeout,
271 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000272 HalResult<Capabilities> capabilities = getCapabilities();
273 bool supportsCallback = capabilities.isOk() &&
274 static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
Lais Andrade818a2252024-06-24 14:48:14 +0100275 auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
276 : nullptr;
Lais Andrade10d9dc72020-05-20 12:00:49 +0000277
Lais Andrade641248e2024-02-16 17:49:36 +0000278 auto ret = HalResultFactory::fromStatus(getHal()->on(timeout.count(), cb));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000279 if (!supportsCallback && ret.isOk()) {
280 mCallbackScheduler->schedule(completionCallback, timeout);
281 }
282
283 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100284}
285
286HalResult<void> AidlHalWrapper::off() {
Lais Andrade641248e2024-02-16 17:49:36 +0000287 return HalResultFactory::fromStatus(getHal()->off());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100288}
289
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000290HalResult<void> AidlHalWrapper::setAmplitude(float amplitude) {
Lais Andrade641248e2024-02-16 17:49:36 +0000291 return HalResultFactory::fromStatus(getHal()->setAmplitude(amplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100292}
293
294HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
Lais Andrade641248e2024-02-16 17:49:36 +0000295 return HalResultFactory::fromStatus(getHal()->setExternalControl(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100296}
297
298HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
Lais Andrade641248e2024-02-16 17:49:36 +0000299 return HalResultFactory::fromStatus(getHal()->alwaysOnEnable(id, effect, strength));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100300}
301
302HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
Lais Andrade641248e2024-02-16 17:49:36 +0000303 return HalResultFactory::fromStatus(getHal()->alwaysOnDisable(id));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100304}
305
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100306HalResult<milliseconds> AidlHalWrapper::performEffect(
307 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000308 HalResult<Capabilities> capabilities = getCapabilities();
309 bool supportsCallback = capabilities.isOk() &&
310 static_cast<int32_t>(capabilities.value() & Capabilities::PERFORM_CALLBACK);
Lais Andrade818a2252024-06-24 14:48:14 +0100311 auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
312 : nullptr;
Lais Andrade10d9dc72020-05-20 12:00:49 +0000313
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100314 int32_t lengthMs;
Lais Andrade818a2252024-06-24 14:48:14 +0100315 auto status = getHal()->perform(effect, strength, cb, &lengthMs);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000316 milliseconds length = milliseconds(lengthMs);
317
Lais Andrade818a2252024-06-24 14:48:14 +0100318 auto ret = HalResultFactory::fromStatus<milliseconds>(std::move(status), length);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000319 if (!supportsCallback && ret.isOk()) {
320 mCallbackScheduler->schedule(completionCallback, length);
321 }
322
323 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100324}
325
Lais Andradef172ea12024-07-12 13:45:01 +0100326HalResult<void> AidlHalWrapper::performVendorEffect(
327 const VendorEffect& effect, const std::function<void()>& completionCallback) {
328 // This method should always support callbacks, so no need to double check.
329 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
330 return HalResultFactory::fromStatus(getHal()->performVendorEffect(effect, cb));
331}
332
Lais Andrade49b60b12021-02-23 13:27:41 +0000333HalResult<milliseconds> AidlHalWrapper::performComposedEffect(
Lais Andrade92f2af52021-03-22 16:12:50 +0000334 const std::vector<CompositeEffect>& primitives,
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100335 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000336 // This method should always support callbacks, so no need to double check.
Lais Andrade818a2252024-06-24 14:48:14 +0100337 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
Lais Andrade965284b2021-03-19 20:58:15 +0000338
339 auto durations = getPrimitiveDurations().valueOr({});
Lais Andrade49b60b12021-02-23 13:27:41 +0000340 milliseconds duration(0);
Lais Andrade92f2af52021-03-22 16:12:50 +0000341 for (const auto& effect : primitives) {
Lais Andrade965284b2021-03-19 20:58:15 +0000342 auto primitiveIdx = static_cast<size_t>(effect.primitive);
343 if (primitiveIdx < durations.size()) {
344 duration += durations[primitiveIdx];
345 } else {
346 // Make sure the returned duration is positive to indicate successful vibration.
347 duration += milliseconds(1);
Lais Andrade49b60b12021-02-23 13:27:41 +0000348 }
349 duration += milliseconds(effect.delayMs);
350 }
Lais Andrade49b60b12021-02-23 13:27:41 +0000351
Lais Andrade641248e2024-02-16 17:49:36 +0000352 return HalResultFactory::fromStatus<milliseconds>(getHal()->compose(primitives, cb), duration);
Lais Andrade92f2af52021-03-22 16:12:50 +0000353}
354
355HalResult<void> AidlHalWrapper::performPwleEffect(const std::vector<PrimitivePwle>& primitives,
356 const std::function<void()>& completionCallback) {
357 // This method should always support callbacks, so no need to double check.
Lais Andrade818a2252024-06-24 14:48:14 +0100358 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
Lais Andrade641248e2024-02-16 17:49:36 +0000359 return HalResultFactory::fromStatus(getHal()->composePwle(primitives, cb));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100360}
361
Ahmad Khalil754a9cc2024-09-28 20:12:14 +0000362HalResult<void> AidlHalWrapper::composePwleV2(const CompositePwleV2& composite,
Ahmad Khalil11111892024-08-05 17:40:17 +0000363 const std::function<void()>& completionCallback) {
364 // This method should always support callbacks, so no need to double check.
365 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
366 return HalResultFactory::fromStatus(getHal()->composePwleV2(composite, cb));
367}
368
Lais Andrade10d9dc72020-05-20 12:00:49 +0000369HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
Lais Andrade818a2252024-06-24 14:48:14 +0100370 int32_t cap = 0;
371 auto status = getHal()->getCapabilities(&cap);
372 auto capabilities = static_cast<Capabilities>(cap);
373 return HalResultFactory::fromStatus<Capabilities>(std::move(status), capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000374}
375
376HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
377 std::vector<Effect> supportedEffects;
Lais Andrade818a2252024-06-24 14:48:14 +0100378 auto status = getHal()->getSupportedEffects(&supportedEffects);
379 return HalResultFactory::fromStatus<std::vector<Effect>>(std::move(status), supportedEffects);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000380}
381
Lais Andrade92f2af52021-03-22 16:12:50 +0000382HalResult<std::vector<Braking>> AidlHalWrapper::getSupportedBrakingInternal() {
383 std::vector<Braking> supportedBraking;
Lais Andrade818a2252024-06-24 14:48:14 +0100384 auto status = getHal()->getSupportedBraking(&supportedBraking);
385 return HalResultFactory::fromStatus<std::vector<Braking>>(std::move(status), supportedBraking);
Lais Andrade92f2af52021-03-22 16:12:50 +0000386}
387
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000388HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() {
389 std::vector<CompositePrimitive> supportedPrimitives;
Lais Andrade818a2252024-06-24 14:48:14 +0100390 auto status = getHal()->getSupportedPrimitives(&supportedPrimitives);
391 return HalResultFactory::fromStatus<std::vector<CompositePrimitive>>(std::move(status),
Lais Andrade641248e2024-02-16 17:49:36 +0000392 supportedPrimitives);
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000393}
394
Lais Andrade965284b2021-03-19 20:58:15 +0000395HalResult<std::vector<milliseconds>> AidlHalWrapper::getPrimitiveDurationsInternal(
396 const std::vector<CompositePrimitive>& supportedPrimitives) {
397 std::vector<milliseconds> durations;
Lais Andrade818a2252024-06-24 14:48:14 +0100398 constexpr auto primitiveRange = ndk::enum_range<CompositePrimitive>();
Lais Andrade965284b2021-03-19 20:58:15 +0000399 constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
400 durations.resize(primitiveCount);
401
402 for (auto primitive : supportedPrimitives) {
403 auto primitiveIdx = static_cast<size_t>(primitive);
404 if (primitiveIdx >= durations.size()) {
405 // Safety check, should not happen if enum_range is correct.
Lais Andrade4928bfd2021-08-25 18:21:12 +0100406 ALOGE("Supported primitive %zu is outside range [0,%zu), skipping load duration",
407 primitiveIdx, durations.size());
Lais Andrade965284b2021-03-19 20:58:15 +0000408 continue;
409 }
410 int32_t duration = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100411 auto status = getHal()->getPrimitiveDuration(primitive, &duration);
412 auto halResult = HalResultFactory::fromStatus<int32_t>(std::move(status), duration);
Lais Andrade4928bfd2021-08-25 18:21:12 +0100413 if (halResult.isUnsupported()) {
414 // Should not happen, supported primitives should always support requesting duration.
415 ALOGE("Supported primitive %zu returned unsupported for getPrimitiveDuration",
416 primitiveIdx);
417 }
418 if (halResult.isFailed()) {
419 // Fail entire request if one request has failed.
Lais Andradef172ea12024-07-12 13:45:01 +0100420 return HalResult<std::vector<milliseconds>>::failed(halResult.errorMessage());
Lais Andrade965284b2021-03-19 20:58:15 +0000421 }
422 durations[primitiveIdx] = milliseconds(duration);
423 }
424
425 return HalResult<std::vector<milliseconds>>::ok(durations);
426}
427
Lais Andrade4aa80c92021-06-03 17:20:16 +0100428HalResult<milliseconds> AidlHalWrapper::getPrimitiveDelayMaxInternal() {
429 int32_t delay = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100430 auto status = getHal()->getCompositionDelayMax(&delay);
431 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(delay));
Lais Andrade4aa80c92021-06-03 17:20:16 +0100432}
433
434HalResult<milliseconds> AidlHalWrapper::getPrimitiveDurationMaxInternal() {
435 int32_t delay = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100436 auto status = getHal()->getPwlePrimitiveDurationMax(&delay);
437 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(delay));
Lais Andrade4aa80c92021-06-03 17:20:16 +0100438}
439
440HalResult<int32_t> AidlHalWrapper::getCompositionSizeMaxInternal() {
441 int32_t size = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100442 auto status = getHal()->getCompositionSizeMax(&size);
443 return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
Lais Andrade4aa80c92021-06-03 17:20:16 +0100444}
445
446HalResult<int32_t> AidlHalWrapper::getPwleSizeMaxInternal() {
447 int32_t size = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100448 auto status = getHal()->getPwleCompositionSizeMax(&size);
449 return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
Lais Andrade4aa80c92021-06-03 17:20:16 +0100450}
451
Lais Andrade92f2af52021-03-22 16:12:50 +0000452HalResult<float> AidlHalWrapper::getMinFrequencyInternal() {
453 float minFrequency = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100454 auto status = getHal()->getFrequencyMinimum(&minFrequency);
455 return HalResultFactory::fromStatus<float>(std::move(status), minFrequency);
Lais Andrade92f2af52021-03-22 16:12:50 +0000456}
457
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000458HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() {
459 float f0 = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100460 auto status = getHal()->getResonantFrequency(&f0);
461 return HalResultFactory::fromStatus<float>(std::move(status), f0);
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000462}
463
Lais Andrade92f2af52021-03-22 16:12:50 +0000464HalResult<float> AidlHalWrapper::getFrequencyResolutionInternal() {
465 float frequencyResolution = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100466 auto status = getHal()->getFrequencyResolution(&frequencyResolution);
467 return HalResultFactory::fromStatus<float>(std::move(status), frequencyResolution);
Lais Andrade92f2af52021-03-22 16:12:50 +0000468}
469
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000470HalResult<float> AidlHalWrapper::getQFactorInternal() {
471 float qFactor = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100472 auto status = getHal()->getQFactor(&qFactor);
473 return HalResultFactory::fromStatus<float>(std::move(status), qFactor);
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000474}
475
Lais Andrade92f2af52021-03-22 16:12:50 +0000476HalResult<std::vector<float>> AidlHalWrapper::getMaxAmplitudesInternal() {
477 std::vector<float> amplitudes;
Lais Andrade818a2252024-06-24 14:48:14 +0100478 auto status = getHal()->getBandwidthAmplitudeMap(&amplitudes);
479 return HalResultFactory::fromStatus<std::vector<float>>(std::move(status), amplitudes);
Lais Andrade92f2af52021-03-22 16:12:50 +0000480}
481
Ahmad Khalil193e37b2024-09-02 10:05:50 +0000482HalResult<int32_t> AidlHalWrapper::getMaxEnvelopeEffectSizeInternal() {
483 int32_t size = 0;
484 auto status = getHal()->getPwleV2CompositionSizeMax(&size);
485 return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
486}
487
488HalResult<milliseconds> AidlHalWrapper::getMinEnvelopeEffectControlPointDurationInternal() {
489 int32_t durationMs = 0;
490 auto status = getHal()->getPwleV2PrimitiveDurationMinMillis(&durationMs);
491 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(durationMs));
492}
493
494HalResult<milliseconds> AidlHalWrapper::getMaxEnvelopeEffectControlPointDurationInternal() {
495 int32_t durationMs = 0;
496 auto status = getHal()->getPwleV2PrimitiveDurationMaxMillis(&durationMs);
497 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(durationMs));
498}
499
Ahmad Khalil754a9cc2024-09-28 20:12:14 +0000500HalResult<std::vector<FrequencyAccelerationMapEntry>>
Ahmad Khalil648e8e62024-09-23 09:29:36 +0000501AidlHalWrapper::getFrequencyToOutputAccelerationMapInternal() {
Ahmad Khalil754a9cc2024-09-28 20:12:14 +0000502 std::vector<FrequencyAccelerationMapEntry> frequencyToOutputAccelerationMap;
503 auto status = getHal()->getFrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap);
Ahmad Khalil648e8e62024-09-23 09:29:36 +0000504 return HalResultFactory::fromStatus<
Ahmad Khalil754a9cc2024-09-28 20:12:14 +0000505 std::vector<FrequencyAccelerationMapEntry>>(std::move(status),
506 frequencyToOutputAccelerationMap);
Ahmad Khalil648e8e62024-09-23 09:29:36 +0000507}
508
Lais Andrade818a2252024-06-24 14:48:14 +0100509std::shared_ptr<Aidl::IVibrator> AidlHalWrapper::getHal() {
Lais Andradecfd81152020-07-01 09:00:26 +0000510 std::lock_guard<std::mutex> lock(mHandleMutex);
511 return mHandle;
512}
513
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100514// -------------------------------------------------------------------------------------------------
515
Lais Andradecfd81152020-07-01 09:00:26 +0000516template <typename I>
517HalResult<void> HidlHalWrapper<I>::ping() {
Lais Andrade818a2252024-06-24 14:48:14 +0100518 return HalResultFactory::fromReturn(getHal()->ping());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100519}
520
Lais Andradecfd81152020-07-01 09:00:26 +0000521template <typename I>
522void HidlHalWrapper<I>::tryReconnect() {
523 sp<I> newHandle = I::tryGetService();
524 if (newHandle) {
525 std::lock_guard<std::mutex> lock(mHandleMutex);
526 mHandle = std::move(newHandle);
527 }
528}
529
530template <typename I>
531HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
532 const std::function<void()>& completionCallback) {
Lais Andrade818a2252024-06-24 14:48:14 +0100533 auto status = getHal()->on(timeout.count());
534 auto ret = HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000535 if (ret.isOk()) {
536 mCallbackScheduler->schedule(completionCallback, timeout);
537 }
538 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100539}
540
Lais Andradecfd81152020-07-01 09:00:26 +0000541template <typename I>
542HalResult<void> HidlHalWrapper<I>::off() {
Lais Andrade818a2252024-06-24 14:48:14 +0100543 auto status = getHal()->off();
544 return HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100545}
546
Lais Andradecfd81152020-07-01 09:00:26 +0000547template <typename I>
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000548HalResult<void> HidlHalWrapper<I>::setAmplitude(float amplitude) {
549 uint8_t amp = static_cast<uint8_t>(amplitude * std::numeric_limits<uint8_t>::max());
Lais Andrade818a2252024-06-24 14:48:14 +0100550 auto status = getHal()->setAmplitude(amp);
551 return HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100552}
553
Lais Andradecfd81152020-07-01 09:00:26 +0000554template <typename I>
555HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100556 ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
557 return HalResult<void>::unsupported();
558}
559
Lais Andradecfd81152020-07-01 09:00:26 +0000560template <typename I>
561HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100562 ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
563 return HalResult<void>::unsupported();
564}
565
Lais Andradecfd81152020-07-01 09:00:26 +0000566template <typename I>
567HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100568 ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
569 return HalResult<void>::unsupported();
570}
571
Lais Andradecfd81152020-07-01 09:00:26 +0000572template <typename I>
Lais Andradecfd81152020-07-01 09:00:26 +0000573HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
574 hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
Lais Andraded39ff7d2020-05-19 10:42:51 +0000575 Capabilities capabilities =
576 result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
Lais Andrade818a2252024-06-24 14:48:14 +0100577 return HalResultFactory::fromReturn<Capabilities>(std::move(result), capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000578}
579
Lais Andradecfd81152020-07-01 09:00:26 +0000580template <typename I>
581template <typename T>
582HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
583 perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
Lais Andrade10d9dc72020-05-20 12:00:49 +0000584 const std::function<void()>& completionCallback) {
585 V1_0::Status status;
586 int32_t lengthMs;
587 auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
588 status = retStatus;
589 lengthMs = retLengthMs;
590 };
591
592 V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
593 auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
594 milliseconds length = milliseconds(lengthMs);
595
Lais Andrade818a2252024-06-24 14:48:14 +0100596 auto ret = HalResultFactory::fromReturn<milliseconds>(std::move(result), status, length);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000597 if (ret.isOk()) {
598 mCallbackScheduler->schedule(completionCallback, length);
599 }
600
601 return ret;
602}
603
Lais Andradecfd81152020-07-01 09:00:26 +0000604template <typename I>
605sp<I> HidlHalWrapper<I>::getHal() {
606 std::lock_guard<std::mutex> lock(mHandleMutex);
607 return mHandle;
608}
609
610// -------------------------------------------------------------------------------------------------
611
612HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
Lais Andrade10d9dc72020-05-20 12:00:49 +0000613 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andradecfd81152020-07-01 09:00:26 +0000614 if (isStaticCastValid<V1_0::Effect>(effect)) {
615 return performInternal(&V1_0::IVibrator::perform, getHal(),
616 static_cast<V1_0::Effect>(effect), strength, completionCallback);
617 }
618
619 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
620 Aidl::toString(effect).c_str());
621 return HalResult<milliseconds>::unsupported();
Lais Andrade10d9dc72020-05-20 12:00:49 +0000622}
623
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100624// -------------------------------------------------------------------------------------------------
625
Lais Andrade10d9dc72020-05-20 12:00:49 +0000626HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
627 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100628 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000629 return performInternal(&V1_1::IVibrator::perform, getHal(),
630 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100631 }
632 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000633 return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
634 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100635 }
636
637 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
638 Aidl::toString(effect).c_str());
639 return HalResult<milliseconds>::unsupported();
640}
641
642// -------------------------------------------------------------------------------------------------
643
Lais Andrade10d9dc72020-05-20 12:00:49 +0000644HalResult<milliseconds> HidlHalWrapperV1_2::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_2::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_2::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_2::IVibrator::perform_1_2, getHal(),
656 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100657 }
658
659 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
660 Aidl::toString(effect).c_str());
661 return HalResult<milliseconds>::unsupported();
662}
663
664// -------------------------------------------------------------------------------------------------
665
666HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000667 auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
Lais Andrade641248e2024-02-16 17:49:36 +0000668 return HalResultFactory::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100669}
670
Lais Andrade10d9dc72020-05-20 12:00:49 +0000671HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
672 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100673 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000674 return performInternal(&V1_3::IVibrator::perform, getHal(),
675 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100676 }
677 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000678 return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
679 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100680 }
681 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000682 return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
683 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100684 }
685 if (isStaticCastValid<V1_3::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000686 return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
687 static_cast<V1_3::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100688 }
689
690 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
691 Aidl::toString(effect).c_str());
692 return HalResult<milliseconds>::unsupported();
693}
694
Lais Andraded39ff7d2020-05-19 10:42:51 +0000695HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
Lais Andrade08666612020-08-07 16:16:31 +0000696 Capabilities capabilities = Capabilities::NONE;
697
Lais Andradecfd81152020-07-01 09:00:26 +0000698 sp<V1_3::IVibrator> hal = getHal();
699 auto amplitudeResult = hal->supportsAmplitudeControl();
700 if (!amplitudeResult.isOk()) {
Lais Andrade818a2252024-06-24 14:48:14 +0100701 return HalResultFactory::fromReturn<Capabilities>(std::move(amplitudeResult), capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000702 }
703
Lais Andradecfd81152020-07-01 09:00:26 +0000704 auto externalControlResult = hal->supportsExternalControl();
Lais Andradecfd81152020-07-01 09:00:26 +0000705 if (amplitudeResult.withDefault(false)) {
706 capabilities |= Capabilities::AMPLITUDE_CONTROL;
707 }
708 if (externalControlResult.withDefault(false)) {
709 capabilities |= Capabilities::EXTERNAL_CONTROL;
Lais Andrade602ff962020-08-27 12:02:53 +0000710
711 if (amplitudeResult.withDefault(false)) {
712 capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL;
713 }
Lais Andradecfd81152020-07-01 09:00:26 +0000714 }
715
Lais Andrade818a2252024-06-24 14:48:14 +0100716 return HalResultFactory::fromReturn<Capabilities>(std::move(externalControlResult),
717 capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000718}
719
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100720// -------------------------------------------------------------------------------------------------
721
722}; // namespace vibrator
723
724}; // namespace android