blob: b06ee3b2b5a8642070f43941c3691cde28a022ca [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;
32using aidl::android::hardware::vibrator::Effect;
33using aidl::android::hardware::vibrator::EffectStrength;
34using aidl::android::hardware::vibrator::PrimitivePwle;
Ahmad Khalil11111892024-08-05 17:40:17 +000035using aidl::android::hardware::vibrator::PwleV2OutputMapEntry;
36using aidl::android::hardware::vibrator::PwleV2Primitive;
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 Khalil11111892024-08-05 17:40:17 +0000134HalResult<void> HalWrapper::composePwleV2(const std::vector<PwleV2Primitive>&,
135 const std::function<void()>&) {
136 ALOGV("Skipped composePwleV2 because it's not available in Vibrator HAL");
137 return HalResult<void>::unsupported();
138}
139
Lais Andrade965284b2021-03-19 20:58:15 +0000140HalResult<Capabilities> HalWrapper::getCapabilities() {
141 std::lock_guard<std::mutex> lock(mInfoMutex);
142 if (mInfoCache.mCapabilities.isFailed()) {
143 mInfoCache.mCapabilities = getCapabilitiesInternal();
144 }
145 return mInfoCache.mCapabilities;
146}
147
148HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurations() {
149 std::lock_guard<std::mutex> lock(mInfoMutex);
150 if (mInfoCache.mSupportedPrimitives.isFailed()) {
151 mInfoCache.mSupportedPrimitives = getSupportedPrimitivesInternal();
152 if (mInfoCache.mSupportedPrimitives.isUnsupported()) {
153 mInfoCache.mPrimitiveDurations = HalResult<std::vector<milliseconds>>::unsupported();
154 }
155 }
156 if (mInfoCache.mPrimitiveDurations.isFailed() && mInfoCache.mSupportedPrimitives.isOk()) {
157 mInfoCache.mPrimitiveDurations =
158 getPrimitiveDurationsInternal(mInfoCache.mSupportedPrimitives.value());
159 }
160 return mInfoCache.mPrimitiveDurations;
161}
162
163HalResult<std::vector<Effect>> HalWrapper::getSupportedEffectsInternal() {
164 ALOGV("Skipped getSupportedEffects because it's not available in Vibrator HAL");
165 return HalResult<std::vector<Effect>>::unsupported();
166}
167
Lais Andrade92f2af52021-03-22 16:12:50 +0000168HalResult<std::vector<Braking>> HalWrapper::getSupportedBrakingInternal() {
169 ALOGV("Skipped getSupportedBraking because it's not available in Vibrator HAL");
170 return HalResult<std::vector<Braking>>::unsupported();
171}
172
Lais Andrade965284b2021-03-19 20:58:15 +0000173HalResult<std::vector<CompositePrimitive>> HalWrapper::getSupportedPrimitivesInternal() {
174 ALOGV("Skipped getSupportedPrimitives because it's not available in Vibrator HAL");
175 return HalResult<std::vector<CompositePrimitive>>::unsupported();
176}
177
178HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurationsInternal(
179 const std::vector<CompositePrimitive>&) {
180 ALOGV("Skipped getPrimitiveDurations because it's not available in Vibrator HAL");
181 return HalResult<std::vector<milliseconds>>::unsupported();
182}
183
Lais Andrade4aa80c92021-06-03 17:20:16 +0100184HalResult<milliseconds> HalWrapper::getPrimitiveDelayMaxInternal() {
185 ALOGV("Skipped getPrimitiveDelayMaxInternal because it's not available in Vibrator HAL");
186 return HalResult<milliseconds>::unsupported();
187}
188
189HalResult<milliseconds> HalWrapper::getPrimitiveDurationMaxInternal() {
190 ALOGV("Skipped getPrimitiveDurationMaxInternal because it's not available in Vibrator HAL");
191 return HalResult<milliseconds>::unsupported();
192}
193
194HalResult<int32_t> HalWrapper::getCompositionSizeMaxInternal() {
195 ALOGV("Skipped getCompositionSizeMaxInternal because it's not available in Vibrator HAL");
196 return HalResult<int32_t>::unsupported();
197}
198
199HalResult<int32_t> HalWrapper::getPwleSizeMaxInternal() {
200 ALOGV("Skipped getPwleSizeMaxInternal because it's not available in Vibrator HAL");
201 return HalResult<int32_t>::unsupported();
202}
203
Lais Andrade92f2af52021-03-22 16:12:50 +0000204HalResult<float> HalWrapper::getMinFrequencyInternal() {
205 ALOGV("Skipped getMinFrequency because it's not available in Vibrator HAL");
206 return HalResult<float>::unsupported();
207}
208
Lais Andrade965284b2021-03-19 20:58:15 +0000209HalResult<float> HalWrapper::getResonantFrequencyInternal() {
210 ALOGV("Skipped getResonantFrequency because it's not available in Vibrator HAL");
211 return HalResult<float>::unsupported();
212}
213
Lais Andrade92f2af52021-03-22 16:12:50 +0000214HalResult<float> HalWrapper::getFrequencyResolutionInternal() {
215 ALOGV("Skipped getFrequencyResolution because it's not available in Vibrator HAL");
216 return HalResult<float>::unsupported();
217}
218
Lais Andrade965284b2021-03-19 20:58:15 +0000219HalResult<float> HalWrapper::getQFactorInternal() {
220 ALOGV("Skipped getQFactor because it's not available in Vibrator HAL");
221 return HalResult<float>::unsupported();
222}
223
Lais Andrade92f2af52021-03-22 16:12:50 +0000224HalResult<std::vector<float>> HalWrapper::getMaxAmplitudesInternal() {
225 ALOGV("Skipped getMaxAmplitudes because it's not available in Vibrator HAL");
226 return HalResult<std::vector<float>>::unsupported();
227}
Ahmad Khalil193e37b2024-09-02 10:05:50 +0000228HalResult<int32_t> HalWrapper::getMaxEnvelopeEffectSizeInternal() {
229 ALOGV("Skipped getMaxEnvelopeEffectSizeInternal because it's not available "
230 "in Vibrator HAL");
231 return HalResult<int32_t>::unsupported();
232}
233
234HalResult<milliseconds> HalWrapper::getMinEnvelopeEffectControlPointDurationInternal() {
235 ALOGV("Skipped getMinEnvelopeEffectControlPointDurationInternal because it's not "
236 "available in Vibrator HAL");
237 return HalResult<milliseconds>::unsupported();
238}
239
240HalResult<milliseconds> HalWrapper::getMaxEnvelopeEffectControlPointDurationInternal() {
241 ALOGV("Skipped getMaxEnvelopeEffectControlPointDurationInternal because it's not "
242 "available in Vibrator HAL");
243 return HalResult<milliseconds>::unsupported();
244}
Lais Andrade92f2af52021-03-22 16:12:50 +0000245
Ahmad Khalil648e8e62024-09-23 09:29:36 +0000246HalResult<std::vector<PwleV2OutputMapEntry>>
247HalWrapper::getFrequencyToOutputAccelerationMapInternal() {
248 ALOGV("Skipped getFrequencyToOutputAccelerationMapInternal because it's not "
249 "available in Vibrator HAL");
250 return HalResult<std::vector<PwleV2OutputMapEntry>>::unsupported();
251}
252
Lais Andrade965284b2021-03-19 20:58:15 +0000253// -------------------------------------------------------------------------------------------------
254
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100255HalResult<void> AidlHalWrapper::ping() {
Lais Andrade818a2252024-06-24 14:48:14 +0100256 return HalResultFactory::fromStatus(AIBinder_ping(getHal()->asBinder().get()));
Lais Andradecfd81152020-07-01 09:00:26 +0000257}
258
259void AidlHalWrapper::tryReconnect() {
Lais Andrade98c97032020-11-17 19:23:01 +0000260 auto result = mReconnectFn();
261 if (!result.isOk()) {
262 return;
263 }
Lais Andrade818a2252024-06-24 14:48:14 +0100264 std::shared_ptr<Aidl::IVibrator> newHandle = result.value();
Lais Andradecfd81152020-07-01 09:00:26 +0000265 if (newHandle) {
266 std::lock_guard<std::mutex> lock(mHandleMutex);
267 mHandle = std::move(newHandle);
268 }
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100269}
270
271HalResult<void> AidlHalWrapper::on(milliseconds timeout,
272 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000273 HalResult<Capabilities> capabilities = getCapabilities();
274 bool supportsCallback = capabilities.isOk() &&
275 static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
Lais Andrade818a2252024-06-24 14:48:14 +0100276 auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
277 : nullptr;
Lais Andrade10d9dc72020-05-20 12:00:49 +0000278
Lais Andrade641248e2024-02-16 17:49:36 +0000279 auto ret = HalResultFactory::fromStatus(getHal()->on(timeout.count(), cb));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000280 if (!supportsCallback && ret.isOk()) {
281 mCallbackScheduler->schedule(completionCallback, timeout);
282 }
283
284 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100285}
286
287HalResult<void> AidlHalWrapper::off() {
Lais Andrade641248e2024-02-16 17:49:36 +0000288 return HalResultFactory::fromStatus(getHal()->off());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100289}
290
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000291HalResult<void> AidlHalWrapper::setAmplitude(float amplitude) {
Lais Andrade641248e2024-02-16 17:49:36 +0000292 return HalResultFactory::fromStatus(getHal()->setAmplitude(amplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100293}
294
295HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
Lais Andrade641248e2024-02-16 17:49:36 +0000296 return HalResultFactory::fromStatus(getHal()->setExternalControl(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100297}
298
299HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
Lais Andrade641248e2024-02-16 17:49:36 +0000300 return HalResultFactory::fromStatus(getHal()->alwaysOnEnable(id, effect, strength));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100301}
302
303HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
Lais Andrade641248e2024-02-16 17:49:36 +0000304 return HalResultFactory::fromStatus(getHal()->alwaysOnDisable(id));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100305}
306
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100307HalResult<milliseconds> AidlHalWrapper::performEffect(
308 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000309 HalResult<Capabilities> capabilities = getCapabilities();
310 bool supportsCallback = capabilities.isOk() &&
311 static_cast<int32_t>(capabilities.value() & Capabilities::PERFORM_CALLBACK);
Lais Andrade818a2252024-06-24 14:48:14 +0100312 auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
313 : nullptr;
Lais Andrade10d9dc72020-05-20 12:00:49 +0000314
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100315 int32_t lengthMs;
Lais Andrade818a2252024-06-24 14:48:14 +0100316 auto status = getHal()->perform(effect, strength, cb, &lengthMs);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000317 milliseconds length = milliseconds(lengthMs);
318
Lais Andrade818a2252024-06-24 14:48:14 +0100319 auto ret = HalResultFactory::fromStatus<milliseconds>(std::move(status), length);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000320 if (!supportsCallback && ret.isOk()) {
321 mCallbackScheduler->schedule(completionCallback, length);
322 }
323
324 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100325}
326
Lais Andradef172ea12024-07-12 13:45:01 +0100327HalResult<void> AidlHalWrapper::performVendorEffect(
328 const VendorEffect& effect, const std::function<void()>& completionCallback) {
329 // This method should always support callbacks, so no need to double check.
330 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
331 return HalResultFactory::fromStatus(getHal()->performVendorEffect(effect, cb));
332}
333
Lais Andrade49b60b12021-02-23 13:27:41 +0000334HalResult<milliseconds> AidlHalWrapper::performComposedEffect(
Lais Andrade92f2af52021-03-22 16:12:50 +0000335 const std::vector<CompositeEffect>& primitives,
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100336 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000337 // This method should always support callbacks, so no need to double check.
Lais Andrade818a2252024-06-24 14:48:14 +0100338 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
Lais Andrade965284b2021-03-19 20:58:15 +0000339
340 auto durations = getPrimitiveDurations().valueOr({});
Lais Andrade49b60b12021-02-23 13:27:41 +0000341 milliseconds duration(0);
Lais Andrade92f2af52021-03-22 16:12:50 +0000342 for (const auto& effect : primitives) {
Lais Andrade965284b2021-03-19 20:58:15 +0000343 auto primitiveIdx = static_cast<size_t>(effect.primitive);
344 if (primitiveIdx < durations.size()) {
345 duration += durations[primitiveIdx];
346 } else {
347 // Make sure the returned duration is positive to indicate successful vibration.
348 duration += milliseconds(1);
Lais Andrade49b60b12021-02-23 13:27:41 +0000349 }
350 duration += milliseconds(effect.delayMs);
351 }
Lais Andrade49b60b12021-02-23 13:27:41 +0000352
Lais Andrade641248e2024-02-16 17:49:36 +0000353 return HalResultFactory::fromStatus<milliseconds>(getHal()->compose(primitives, cb), duration);
Lais Andrade92f2af52021-03-22 16:12:50 +0000354}
355
356HalResult<void> AidlHalWrapper::performPwleEffect(const std::vector<PrimitivePwle>& primitives,
357 const std::function<void()>& completionCallback) {
358 // This method should always support callbacks, so no need to double check.
Lais Andrade818a2252024-06-24 14:48:14 +0100359 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
Lais Andrade641248e2024-02-16 17:49:36 +0000360 return HalResultFactory::fromStatus(getHal()->composePwle(primitives, cb));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100361}
362
Ahmad Khalil11111892024-08-05 17:40:17 +0000363HalResult<void> AidlHalWrapper::composePwleV2(const std::vector<PwleV2Primitive>& composite,
364 const std::function<void()>& completionCallback) {
365 // This method should always support callbacks, so no need to double check.
366 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
367 return HalResultFactory::fromStatus(getHal()->composePwleV2(composite, cb));
368}
369
Lais Andrade10d9dc72020-05-20 12:00:49 +0000370HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
Lais Andrade818a2252024-06-24 14:48:14 +0100371 int32_t cap = 0;
372 auto status = getHal()->getCapabilities(&cap);
373 auto capabilities = static_cast<Capabilities>(cap);
374 return HalResultFactory::fromStatus<Capabilities>(std::move(status), capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000375}
376
377HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
378 std::vector<Effect> supportedEffects;
Lais Andrade818a2252024-06-24 14:48:14 +0100379 auto status = getHal()->getSupportedEffects(&supportedEffects);
380 return HalResultFactory::fromStatus<std::vector<Effect>>(std::move(status), supportedEffects);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000381}
382
Lais Andrade92f2af52021-03-22 16:12:50 +0000383HalResult<std::vector<Braking>> AidlHalWrapper::getSupportedBrakingInternal() {
384 std::vector<Braking> supportedBraking;
Lais Andrade818a2252024-06-24 14:48:14 +0100385 auto status = getHal()->getSupportedBraking(&supportedBraking);
386 return HalResultFactory::fromStatus<std::vector<Braking>>(std::move(status), supportedBraking);
Lais Andrade92f2af52021-03-22 16:12:50 +0000387}
388
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000389HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() {
390 std::vector<CompositePrimitive> supportedPrimitives;
Lais Andrade818a2252024-06-24 14:48:14 +0100391 auto status = getHal()->getSupportedPrimitives(&supportedPrimitives);
392 return HalResultFactory::fromStatus<std::vector<CompositePrimitive>>(std::move(status),
Lais Andrade641248e2024-02-16 17:49:36 +0000393 supportedPrimitives);
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000394}
395
Lais Andrade965284b2021-03-19 20:58:15 +0000396HalResult<std::vector<milliseconds>> AidlHalWrapper::getPrimitiveDurationsInternal(
397 const std::vector<CompositePrimitive>& supportedPrimitives) {
398 std::vector<milliseconds> durations;
Lais Andrade818a2252024-06-24 14:48:14 +0100399 constexpr auto primitiveRange = ndk::enum_range<CompositePrimitive>();
Lais Andrade965284b2021-03-19 20:58:15 +0000400 constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
401 durations.resize(primitiveCount);
402
403 for (auto primitive : supportedPrimitives) {
404 auto primitiveIdx = static_cast<size_t>(primitive);
405 if (primitiveIdx >= durations.size()) {
406 // Safety check, should not happen if enum_range is correct.
Lais Andrade4928bfd2021-08-25 18:21:12 +0100407 ALOGE("Supported primitive %zu is outside range [0,%zu), skipping load duration",
408 primitiveIdx, durations.size());
Lais Andrade965284b2021-03-19 20:58:15 +0000409 continue;
410 }
411 int32_t duration = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100412 auto status = getHal()->getPrimitiveDuration(primitive, &duration);
413 auto halResult = HalResultFactory::fromStatus<int32_t>(std::move(status), duration);
Lais Andrade4928bfd2021-08-25 18:21:12 +0100414 if (halResult.isUnsupported()) {
415 // Should not happen, supported primitives should always support requesting duration.
416 ALOGE("Supported primitive %zu returned unsupported for getPrimitiveDuration",
417 primitiveIdx);
418 }
419 if (halResult.isFailed()) {
420 // Fail entire request if one request has failed.
Lais Andradef172ea12024-07-12 13:45:01 +0100421 return HalResult<std::vector<milliseconds>>::failed(halResult.errorMessage());
Lais Andrade965284b2021-03-19 20:58:15 +0000422 }
423 durations[primitiveIdx] = milliseconds(duration);
424 }
425
426 return HalResult<std::vector<milliseconds>>::ok(durations);
427}
428
Lais Andrade4aa80c92021-06-03 17:20:16 +0100429HalResult<milliseconds> AidlHalWrapper::getPrimitiveDelayMaxInternal() {
430 int32_t delay = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100431 auto status = getHal()->getCompositionDelayMax(&delay);
432 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(delay));
Lais Andrade4aa80c92021-06-03 17:20:16 +0100433}
434
435HalResult<milliseconds> AidlHalWrapper::getPrimitiveDurationMaxInternal() {
436 int32_t delay = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100437 auto status = getHal()->getPwlePrimitiveDurationMax(&delay);
438 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(delay));
Lais Andrade4aa80c92021-06-03 17:20:16 +0100439}
440
441HalResult<int32_t> AidlHalWrapper::getCompositionSizeMaxInternal() {
442 int32_t size = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100443 auto status = getHal()->getCompositionSizeMax(&size);
444 return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
Lais Andrade4aa80c92021-06-03 17:20:16 +0100445}
446
447HalResult<int32_t> AidlHalWrapper::getPwleSizeMaxInternal() {
448 int32_t size = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100449 auto status = getHal()->getPwleCompositionSizeMax(&size);
450 return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
Lais Andrade4aa80c92021-06-03 17:20:16 +0100451}
452
Lais Andrade92f2af52021-03-22 16:12:50 +0000453HalResult<float> AidlHalWrapper::getMinFrequencyInternal() {
454 float minFrequency = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100455 auto status = getHal()->getFrequencyMinimum(&minFrequency);
456 return HalResultFactory::fromStatus<float>(std::move(status), minFrequency);
Lais Andrade92f2af52021-03-22 16:12:50 +0000457}
458
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000459HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() {
460 float f0 = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100461 auto status = getHal()->getResonantFrequency(&f0);
462 return HalResultFactory::fromStatus<float>(std::move(status), f0);
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000463}
464
Lais Andrade92f2af52021-03-22 16:12:50 +0000465HalResult<float> AidlHalWrapper::getFrequencyResolutionInternal() {
466 float frequencyResolution = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100467 auto status = getHal()->getFrequencyResolution(&frequencyResolution);
468 return HalResultFactory::fromStatus<float>(std::move(status), frequencyResolution);
Lais Andrade92f2af52021-03-22 16:12:50 +0000469}
470
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000471HalResult<float> AidlHalWrapper::getQFactorInternal() {
472 float qFactor = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100473 auto status = getHal()->getQFactor(&qFactor);
474 return HalResultFactory::fromStatus<float>(std::move(status), qFactor);
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000475}
476
Lais Andrade92f2af52021-03-22 16:12:50 +0000477HalResult<std::vector<float>> AidlHalWrapper::getMaxAmplitudesInternal() {
478 std::vector<float> amplitudes;
Lais Andrade818a2252024-06-24 14:48:14 +0100479 auto status = getHal()->getBandwidthAmplitudeMap(&amplitudes);
480 return HalResultFactory::fromStatus<std::vector<float>>(std::move(status), amplitudes);
Lais Andrade92f2af52021-03-22 16:12:50 +0000481}
482
Ahmad Khalil193e37b2024-09-02 10:05:50 +0000483HalResult<int32_t> AidlHalWrapper::getMaxEnvelopeEffectSizeInternal() {
484 int32_t size = 0;
485 auto status = getHal()->getPwleV2CompositionSizeMax(&size);
486 return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
487}
488
489HalResult<milliseconds> AidlHalWrapper::getMinEnvelopeEffectControlPointDurationInternal() {
490 int32_t durationMs = 0;
491 auto status = getHal()->getPwleV2PrimitiveDurationMinMillis(&durationMs);
492 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(durationMs));
493}
494
495HalResult<milliseconds> AidlHalWrapper::getMaxEnvelopeEffectControlPointDurationInternal() {
496 int32_t durationMs = 0;
497 auto status = getHal()->getPwleV2PrimitiveDurationMaxMillis(&durationMs);
498 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(durationMs));
499}
500
Ahmad Khalil648e8e62024-09-23 09:29:36 +0000501HalResult<std::vector<PwleV2OutputMapEntry>>
502AidlHalWrapper::getFrequencyToOutputAccelerationMapInternal() {
503 std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap;
504 auto status =
505 getHal()->getPwleV2FrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap);
506 return HalResultFactory::fromStatus<
507 std::vector<PwleV2OutputMapEntry>>(std::move(status), frequencyToOutputAccelerationMap);
508}
509
Lais Andrade818a2252024-06-24 14:48:14 +0100510std::shared_ptr<Aidl::IVibrator> AidlHalWrapper::getHal() {
Lais Andradecfd81152020-07-01 09:00:26 +0000511 std::lock_guard<std::mutex> lock(mHandleMutex);
512 return mHandle;
513}
514
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100515// -------------------------------------------------------------------------------------------------
516
Lais Andradecfd81152020-07-01 09:00:26 +0000517template <typename I>
518HalResult<void> HidlHalWrapper<I>::ping() {
Lais Andrade818a2252024-06-24 14:48:14 +0100519 return HalResultFactory::fromReturn(getHal()->ping());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100520}
521
Lais Andradecfd81152020-07-01 09:00:26 +0000522template <typename I>
523void HidlHalWrapper<I>::tryReconnect() {
524 sp<I> newHandle = I::tryGetService();
525 if (newHandle) {
526 std::lock_guard<std::mutex> lock(mHandleMutex);
527 mHandle = std::move(newHandle);
528 }
529}
530
531template <typename I>
532HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
533 const std::function<void()>& completionCallback) {
Lais Andrade818a2252024-06-24 14:48:14 +0100534 auto status = getHal()->on(timeout.count());
535 auto ret = HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000536 if (ret.isOk()) {
537 mCallbackScheduler->schedule(completionCallback, timeout);
538 }
539 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100540}
541
Lais Andradecfd81152020-07-01 09:00:26 +0000542template <typename I>
543HalResult<void> HidlHalWrapper<I>::off() {
Lais Andrade818a2252024-06-24 14:48:14 +0100544 auto status = getHal()->off();
545 return HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100546}
547
Lais Andradecfd81152020-07-01 09:00:26 +0000548template <typename I>
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000549HalResult<void> HidlHalWrapper<I>::setAmplitude(float amplitude) {
550 uint8_t amp = static_cast<uint8_t>(amplitude * std::numeric_limits<uint8_t>::max());
Lais Andrade818a2252024-06-24 14:48:14 +0100551 auto status = getHal()->setAmplitude(amp);
552 return HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100553}
554
Lais Andradecfd81152020-07-01 09:00:26 +0000555template <typename I>
556HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100557 ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
558 return HalResult<void>::unsupported();
559}
560
Lais Andradecfd81152020-07-01 09:00:26 +0000561template <typename I>
562HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100563 ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
564 return HalResult<void>::unsupported();
565}
566
Lais Andradecfd81152020-07-01 09:00:26 +0000567template <typename I>
568HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100569 ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
570 return HalResult<void>::unsupported();
571}
572
Lais Andradecfd81152020-07-01 09:00:26 +0000573template <typename I>
Lais Andradecfd81152020-07-01 09:00:26 +0000574HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
575 hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
Lais Andraded39ff7d2020-05-19 10:42:51 +0000576 Capabilities capabilities =
577 result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
Lais Andrade818a2252024-06-24 14:48:14 +0100578 return HalResultFactory::fromReturn<Capabilities>(std::move(result), capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000579}
580
Lais Andradecfd81152020-07-01 09:00:26 +0000581template <typename I>
582template <typename T>
583HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
584 perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
Lais Andrade10d9dc72020-05-20 12:00:49 +0000585 const std::function<void()>& completionCallback) {
586 V1_0::Status status;
587 int32_t lengthMs;
588 auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
589 status = retStatus;
590 lengthMs = retLengthMs;
591 };
592
593 V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
594 auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
595 milliseconds length = milliseconds(lengthMs);
596
Lais Andrade818a2252024-06-24 14:48:14 +0100597 auto ret = HalResultFactory::fromReturn<milliseconds>(std::move(result), status, length);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000598 if (ret.isOk()) {
599 mCallbackScheduler->schedule(completionCallback, length);
600 }
601
602 return ret;
603}
604
Lais Andradecfd81152020-07-01 09:00:26 +0000605template <typename I>
606sp<I> HidlHalWrapper<I>::getHal() {
607 std::lock_guard<std::mutex> lock(mHandleMutex);
608 return mHandle;
609}
610
611// -------------------------------------------------------------------------------------------------
612
613HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
Lais Andrade10d9dc72020-05-20 12:00:49 +0000614 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andradecfd81152020-07-01 09:00:26 +0000615 if (isStaticCastValid<V1_0::Effect>(effect)) {
616 return performInternal(&V1_0::IVibrator::perform, getHal(),
617 static_cast<V1_0::Effect>(effect), strength, completionCallback);
618 }
619
620 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
621 Aidl::toString(effect).c_str());
622 return HalResult<milliseconds>::unsupported();
Lais Andrade10d9dc72020-05-20 12:00:49 +0000623}
624
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100625// -------------------------------------------------------------------------------------------------
626
Lais Andrade10d9dc72020-05-20 12:00:49 +0000627HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
628 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100629 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000630 return performInternal(&V1_1::IVibrator::perform, getHal(),
631 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100632 }
633 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000634 return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
635 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100636 }
637
638 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
639 Aidl::toString(effect).c_str());
640 return HalResult<milliseconds>::unsupported();
641}
642
643// -------------------------------------------------------------------------------------------------
644
Lais Andrade10d9dc72020-05-20 12:00:49 +0000645HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
646 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100647 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000648 return performInternal(&V1_2::IVibrator::perform, getHal(),
649 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100650 }
651 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000652 return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
653 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100654 }
655 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000656 return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
657 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100658 }
659
660 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
661 Aidl::toString(effect).c_str());
662 return HalResult<milliseconds>::unsupported();
663}
664
665// -------------------------------------------------------------------------------------------------
666
667HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000668 auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
Lais Andrade641248e2024-02-16 17:49:36 +0000669 return HalResultFactory::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100670}
671
Lais Andrade10d9dc72020-05-20 12:00:49 +0000672HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
673 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100674 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000675 return performInternal(&V1_3::IVibrator::perform, getHal(),
676 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100677 }
678 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000679 return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
680 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100681 }
682 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000683 return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
684 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100685 }
686 if (isStaticCastValid<V1_3::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000687 return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
688 static_cast<V1_3::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100689 }
690
691 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
692 Aidl::toString(effect).c_str());
693 return HalResult<milliseconds>::unsupported();
694}
695
Lais Andraded39ff7d2020-05-19 10:42:51 +0000696HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
Lais Andrade08666612020-08-07 16:16:31 +0000697 Capabilities capabilities = Capabilities::NONE;
698
Lais Andradecfd81152020-07-01 09:00:26 +0000699 sp<V1_3::IVibrator> hal = getHal();
700 auto amplitudeResult = hal->supportsAmplitudeControl();
701 if (!amplitudeResult.isOk()) {
Lais Andrade818a2252024-06-24 14:48:14 +0100702 return HalResultFactory::fromReturn<Capabilities>(std::move(amplitudeResult), capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000703 }
704
Lais Andradecfd81152020-07-01 09:00:26 +0000705 auto externalControlResult = hal->supportsExternalControl();
Lais Andradecfd81152020-07-01 09:00:26 +0000706 if (amplitudeResult.withDefault(false)) {
707 capabilities |= Capabilities::AMPLITUDE_CONTROL;
708 }
709 if (externalControlResult.withDefault(false)) {
710 capabilities |= Capabilities::EXTERNAL_CONTROL;
Lais Andrade602ff962020-08-27 12:02:53 +0000711
712 if (amplitudeResult.withDefault(false)) {
713 capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL;
714 }
Lais Andradecfd81152020-07-01 09:00:26 +0000715 }
716
Lais Andrade818a2252024-06-24 14:48:14 +0100717 return HalResultFactory::fromReturn<Capabilities>(std::move(externalControlResult),
718 capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000719}
720
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100721// -------------------------------------------------------------------------------------------------
722
723}; // namespace vibrator
724
725}; // namespace android