blob: 4ac16188fab77e665637803cb198c53387aa7890 [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 }
Lais Andrade965284b2021-03-19 20:58:15 +0000110 return mInfoCache.get();
111}
112
Lais Andradef172ea12024-07-12 13:45:01 +0100113HalResult<void> HalWrapper::performVendorEffect(const VendorEffect&, const std::function<void()>&) {
114 ALOGV("Skipped performVendorEffect because it's not available in Vibrator HAL");
115 return HalResult<void>::unsupported();
116}
117
Lais Andrade92f2af52021-03-22 16:12:50 +0000118HalResult<milliseconds> HalWrapper::performComposedEffect(const std::vector<CompositeEffect>&,
119 const std::function<void()>&) {
120 ALOGV("Skipped performComposedEffect because it's not available in Vibrator HAL");
121 return HalResult<milliseconds>::unsupported();
122}
123
124HalResult<void> HalWrapper::performPwleEffect(const std::vector<PrimitivePwle>&,
125 const std::function<void()>&) {
126 ALOGV("Skipped performPwleEffect because it's not available in Vibrator HAL");
127 return HalResult<void>::unsupported();
128}
129
Ahmad Khalil11111892024-08-05 17:40:17 +0000130HalResult<void> HalWrapper::composePwleV2(const std::vector<PwleV2Primitive>&,
131 const std::function<void()>&) {
132 ALOGV("Skipped composePwleV2 because it's not available in Vibrator HAL");
133 return HalResult<void>::unsupported();
134}
135
Lais Andrade965284b2021-03-19 20:58:15 +0000136HalResult<Capabilities> HalWrapper::getCapabilities() {
137 std::lock_guard<std::mutex> lock(mInfoMutex);
138 if (mInfoCache.mCapabilities.isFailed()) {
139 mInfoCache.mCapabilities = getCapabilitiesInternal();
140 }
141 return mInfoCache.mCapabilities;
142}
143
144HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurations() {
145 std::lock_guard<std::mutex> lock(mInfoMutex);
146 if (mInfoCache.mSupportedPrimitives.isFailed()) {
147 mInfoCache.mSupportedPrimitives = getSupportedPrimitivesInternal();
148 if (mInfoCache.mSupportedPrimitives.isUnsupported()) {
149 mInfoCache.mPrimitiveDurations = HalResult<std::vector<milliseconds>>::unsupported();
150 }
151 }
152 if (mInfoCache.mPrimitiveDurations.isFailed() && mInfoCache.mSupportedPrimitives.isOk()) {
153 mInfoCache.mPrimitiveDurations =
154 getPrimitiveDurationsInternal(mInfoCache.mSupportedPrimitives.value());
155 }
156 return mInfoCache.mPrimitiveDurations;
157}
158
159HalResult<std::vector<Effect>> HalWrapper::getSupportedEffectsInternal() {
160 ALOGV("Skipped getSupportedEffects because it's not available in Vibrator HAL");
161 return HalResult<std::vector<Effect>>::unsupported();
162}
163
Lais Andrade92f2af52021-03-22 16:12:50 +0000164HalResult<std::vector<Braking>> HalWrapper::getSupportedBrakingInternal() {
165 ALOGV("Skipped getSupportedBraking because it's not available in Vibrator HAL");
166 return HalResult<std::vector<Braking>>::unsupported();
167}
168
Lais Andrade965284b2021-03-19 20:58:15 +0000169HalResult<std::vector<CompositePrimitive>> HalWrapper::getSupportedPrimitivesInternal() {
170 ALOGV("Skipped getSupportedPrimitives because it's not available in Vibrator HAL");
171 return HalResult<std::vector<CompositePrimitive>>::unsupported();
172}
173
174HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurationsInternal(
175 const std::vector<CompositePrimitive>&) {
176 ALOGV("Skipped getPrimitiveDurations because it's not available in Vibrator HAL");
177 return HalResult<std::vector<milliseconds>>::unsupported();
178}
179
Lais Andrade4aa80c92021-06-03 17:20:16 +0100180HalResult<milliseconds> HalWrapper::getPrimitiveDelayMaxInternal() {
181 ALOGV("Skipped getPrimitiveDelayMaxInternal because it's not available in Vibrator HAL");
182 return HalResult<milliseconds>::unsupported();
183}
184
185HalResult<milliseconds> HalWrapper::getPrimitiveDurationMaxInternal() {
186 ALOGV("Skipped getPrimitiveDurationMaxInternal because it's not available in Vibrator HAL");
187 return HalResult<milliseconds>::unsupported();
188}
189
190HalResult<int32_t> HalWrapper::getCompositionSizeMaxInternal() {
191 ALOGV("Skipped getCompositionSizeMaxInternal because it's not available in Vibrator HAL");
192 return HalResult<int32_t>::unsupported();
193}
194
195HalResult<int32_t> HalWrapper::getPwleSizeMaxInternal() {
196 ALOGV("Skipped getPwleSizeMaxInternal because it's not available in Vibrator HAL");
197 return HalResult<int32_t>::unsupported();
198}
199
Lais Andrade92f2af52021-03-22 16:12:50 +0000200HalResult<float> HalWrapper::getMinFrequencyInternal() {
201 ALOGV("Skipped getMinFrequency because it's not available in Vibrator HAL");
202 return HalResult<float>::unsupported();
203}
204
Lais Andrade965284b2021-03-19 20:58:15 +0000205HalResult<float> HalWrapper::getResonantFrequencyInternal() {
206 ALOGV("Skipped getResonantFrequency because it's not available in Vibrator HAL");
207 return HalResult<float>::unsupported();
208}
209
Lais Andrade92f2af52021-03-22 16:12:50 +0000210HalResult<float> HalWrapper::getFrequencyResolutionInternal() {
211 ALOGV("Skipped getFrequencyResolution because it's not available in Vibrator HAL");
212 return HalResult<float>::unsupported();
213}
214
Lais Andrade965284b2021-03-19 20:58:15 +0000215HalResult<float> HalWrapper::getQFactorInternal() {
216 ALOGV("Skipped getQFactor because it's not available in Vibrator HAL");
217 return HalResult<float>::unsupported();
218}
219
Lais Andrade92f2af52021-03-22 16:12:50 +0000220HalResult<std::vector<float>> HalWrapper::getMaxAmplitudesInternal() {
221 ALOGV("Skipped getMaxAmplitudes because it's not available in Vibrator HAL");
222 return HalResult<std::vector<float>>::unsupported();
223}
Ahmad Khalil193e37b2024-09-02 10:05:50 +0000224HalResult<int32_t> HalWrapper::getMaxEnvelopeEffectSizeInternal() {
225 ALOGV("Skipped getMaxEnvelopeEffectSizeInternal because it's not available "
226 "in Vibrator HAL");
227 return HalResult<int32_t>::unsupported();
228}
229
230HalResult<milliseconds> HalWrapper::getMinEnvelopeEffectControlPointDurationInternal() {
231 ALOGV("Skipped getMinEnvelopeEffectControlPointDurationInternal because it's not "
232 "available in Vibrator HAL");
233 return HalResult<milliseconds>::unsupported();
234}
235
236HalResult<milliseconds> HalWrapper::getMaxEnvelopeEffectControlPointDurationInternal() {
237 ALOGV("Skipped getMaxEnvelopeEffectControlPointDurationInternal because it's not "
238 "available in Vibrator HAL");
239 return HalResult<milliseconds>::unsupported();
240}
Lais Andrade92f2af52021-03-22 16:12:50 +0000241
Lais Andrade965284b2021-03-19 20:58:15 +0000242// -------------------------------------------------------------------------------------------------
243
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100244HalResult<void> AidlHalWrapper::ping() {
Lais Andrade818a2252024-06-24 14:48:14 +0100245 return HalResultFactory::fromStatus(AIBinder_ping(getHal()->asBinder().get()));
Lais Andradecfd81152020-07-01 09:00:26 +0000246}
247
248void AidlHalWrapper::tryReconnect() {
Lais Andrade98c97032020-11-17 19:23:01 +0000249 auto result = mReconnectFn();
250 if (!result.isOk()) {
251 return;
252 }
Lais Andrade818a2252024-06-24 14:48:14 +0100253 std::shared_ptr<Aidl::IVibrator> newHandle = result.value();
Lais Andradecfd81152020-07-01 09:00:26 +0000254 if (newHandle) {
255 std::lock_guard<std::mutex> lock(mHandleMutex);
256 mHandle = std::move(newHandle);
257 }
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100258}
259
260HalResult<void> AidlHalWrapper::on(milliseconds timeout,
261 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000262 HalResult<Capabilities> capabilities = getCapabilities();
263 bool supportsCallback = capabilities.isOk() &&
264 static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
Lais Andrade818a2252024-06-24 14:48:14 +0100265 auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
266 : nullptr;
Lais Andrade10d9dc72020-05-20 12:00:49 +0000267
Lais Andrade641248e2024-02-16 17:49:36 +0000268 auto ret = HalResultFactory::fromStatus(getHal()->on(timeout.count(), cb));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000269 if (!supportsCallback && ret.isOk()) {
270 mCallbackScheduler->schedule(completionCallback, timeout);
271 }
272
273 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100274}
275
276HalResult<void> AidlHalWrapper::off() {
Lais Andrade641248e2024-02-16 17:49:36 +0000277 return HalResultFactory::fromStatus(getHal()->off());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100278}
279
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000280HalResult<void> AidlHalWrapper::setAmplitude(float amplitude) {
Lais Andrade641248e2024-02-16 17:49:36 +0000281 return HalResultFactory::fromStatus(getHal()->setAmplitude(amplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100282}
283
284HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
Lais Andrade641248e2024-02-16 17:49:36 +0000285 return HalResultFactory::fromStatus(getHal()->setExternalControl(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100286}
287
288HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
Lais Andrade641248e2024-02-16 17:49:36 +0000289 return HalResultFactory::fromStatus(getHal()->alwaysOnEnable(id, effect, strength));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100290}
291
292HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
Lais Andrade641248e2024-02-16 17:49:36 +0000293 return HalResultFactory::fromStatus(getHal()->alwaysOnDisable(id));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100294}
295
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100296HalResult<milliseconds> AidlHalWrapper::performEffect(
297 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000298 HalResult<Capabilities> capabilities = getCapabilities();
299 bool supportsCallback = capabilities.isOk() &&
300 static_cast<int32_t>(capabilities.value() & Capabilities::PERFORM_CALLBACK);
Lais Andrade818a2252024-06-24 14:48:14 +0100301 auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
302 : nullptr;
Lais Andrade10d9dc72020-05-20 12:00:49 +0000303
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100304 int32_t lengthMs;
Lais Andrade818a2252024-06-24 14:48:14 +0100305 auto status = getHal()->perform(effect, strength, cb, &lengthMs);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000306 milliseconds length = milliseconds(lengthMs);
307
Lais Andrade818a2252024-06-24 14:48:14 +0100308 auto ret = HalResultFactory::fromStatus<milliseconds>(std::move(status), length);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000309 if (!supportsCallback && ret.isOk()) {
310 mCallbackScheduler->schedule(completionCallback, length);
311 }
312
313 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100314}
315
Lais Andradef172ea12024-07-12 13:45:01 +0100316HalResult<void> AidlHalWrapper::performVendorEffect(
317 const VendorEffect& effect, const std::function<void()>& completionCallback) {
318 // This method should always support callbacks, so no need to double check.
319 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
320 return HalResultFactory::fromStatus(getHal()->performVendorEffect(effect, cb));
321}
322
Lais Andrade49b60b12021-02-23 13:27:41 +0000323HalResult<milliseconds> AidlHalWrapper::performComposedEffect(
Lais Andrade92f2af52021-03-22 16:12:50 +0000324 const std::vector<CompositeEffect>& primitives,
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100325 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000326 // This method should always support callbacks, so no need to double check.
Lais Andrade818a2252024-06-24 14:48:14 +0100327 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
Lais Andrade965284b2021-03-19 20:58:15 +0000328
329 auto durations = getPrimitiveDurations().valueOr({});
Lais Andrade49b60b12021-02-23 13:27:41 +0000330 milliseconds duration(0);
Lais Andrade92f2af52021-03-22 16:12:50 +0000331 for (const auto& effect : primitives) {
Lais Andrade965284b2021-03-19 20:58:15 +0000332 auto primitiveIdx = static_cast<size_t>(effect.primitive);
333 if (primitiveIdx < durations.size()) {
334 duration += durations[primitiveIdx];
335 } else {
336 // Make sure the returned duration is positive to indicate successful vibration.
337 duration += milliseconds(1);
Lais Andrade49b60b12021-02-23 13:27:41 +0000338 }
339 duration += milliseconds(effect.delayMs);
340 }
Lais Andrade49b60b12021-02-23 13:27:41 +0000341
Lais Andrade641248e2024-02-16 17:49:36 +0000342 return HalResultFactory::fromStatus<milliseconds>(getHal()->compose(primitives, cb), duration);
Lais Andrade92f2af52021-03-22 16:12:50 +0000343}
344
345HalResult<void> AidlHalWrapper::performPwleEffect(const std::vector<PrimitivePwle>& primitives,
346 const std::function<void()>& completionCallback) {
347 // This method should always support callbacks, so no need to double check.
Lais Andrade818a2252024-06-24 14:48:14 +0100348 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
Lais Andrade641248e2024-02-16 17:49:36 +0000349 return HalResultFactory::fromStatus(getHal()->composePwle(primitives, cb));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100350}
351
Ahmad Khalil11111892024-08-05 17:40:17 +0000352HalResult<void> AidlHalWrapper::composePwleV2(const std::vector<PwleV2Primitive>& composite,
353 const std::function<void()>& completionCallback) {
354 // This method should always support callbacks, so no need to double check.
355 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
356 return HalResultFactory::fromStatus(getHal()->composePwleV2(composite, cb));
357}
358
Lais Andrade10d9dc72020-05-20 12:00:49 +0000359HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
Lais Andrade818a2252024-06-24 14:48:14 +0100360 int32_t cap = 0;
361 auto status = getHal()->getCapabilities(&cap);
362 auto capabilities = static_cast<Capabilities>(cap);
363 return HalResultFactory::fromStatus<Capabilities>(std::move(status), capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000364}
365
366HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
367 std::vector<Effect> supportedEffects;
Lais Andrade818a2252024-06-24 14:48:14 +0100368 auto status = getHal()->getSupportedEffects(&supportedEffects);
369 return HalResultFactory::fromStatus<std::vector<Effect>>(std::move(status), supportedEffects);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000370}
371
Lais Andrade92f2af52021-03-22 16:12:50 +0000372HalResult<std::vector<Braking>> AidlHalWrapper::getSupportedBrakingInternal() {
373 std::vector<Braking> supportedBraking;
Lais Andrade818a2252024-06-24 14:48:14 +0100374 auto status = getHal()->getSupportedBraking(&supportedBraking);
375 return HalResultFactory::fromStatus<std::vector<Braking>>(std::move(status), supportedBraking);
Lais Andrade92f2af52021-03-22 16:12:50 +0000376}
377
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000378HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() {
379 std::vector<CompositePrimitive> supportedPrimitives;
Lais Andrade818a2252024-06-24 14:48:14 +0100380 auto status = getHal()->getSupportedPrimitives(&supportedPrimitives);
381 return HalResultFactory::fromStatus<std::vector<CompositePrimitive>>(std::move(status),
Lais Andrade641248e2024-02-16 17:49:36 +0000382 supportedPrimitives);
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000383}
384
Lais Andrade965284b2021-03-19 20:58:15 +0000385HalResult<std::vector<milliseconds>> AidlHalWrapper::getPrimitiveDurationsInternal(
386 const std::vector<CompositePrimitive>& supportedPrimitives) {
387 std::vector<milliseconds> durations;
Lais Andrade818a2252024-06-24 14:48:14 +0100388 constexpr auto primitiveRange = ndk::enum_range<CompositePrimitive>();
Lais Andrade965284b2021-03-19 20:58:15 +0000389 constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
390 durations.resize(primitiveCount);
391
392 for (auto primitive : supportedPrimitives) {
393 auto primitiveIdx = static_cast<size_t>(primitive);
394 if (primitiveIdx >= durations.size()) {
395 // Safety check, should not happen if enum_range is correct.
Lais Andrade4928bfd2021-08-25 18:21:12 +0100396 ALOGE("Supported primitive %zu is outside range [0,%zu), skipping load duration",
397 primitiveIdx, durations.size());
Lais Andrade965284b2021-03-19 20:58:15 +0000398 continue;
399 }
400 int32_t duration = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100401 auto status = getHal()->getPrimitiveDuration(primitive, &duration);
402 auto halResult = HalResultFactory::fromStatus<int32_t>(std::move(status), duration);
Lais Andrade4928bfd2021-08-25 18:21:12 +0100403 if (halResult.isUnsupported()) {
404 // Should not happen, supported primitives should always support requesting duration.
405 ALOGE("Supported primitive %zu returned unsupported for getPrimitiveDuration",
406 primitiveIdx);
407 }
408 if (halResult.isFailed()) {
409 // Fail entire request if one request has failed.
Lais Andradef172ea12024-07-12 13:45:01 +0100410 return HalResult<std::vector<milliseconds>>::failed(halResult.errorMessage());
Lais Andrade965284b2021-03-19 20:58:15 +0000411 }
412 durations[primitiveIdx] = milliseconds(duration);
413 }
414
415 return HalResult<std::vector<milliseconds>>::ok(durations);
416}
417
Lais Andrade4aa80c92021-06-03 17:20:16 +0100418HalResult<milliseconds> AidlHalWrapper::getPrimitiveDelayMaxInternal() {
419 int32_t delay = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100420 auto status = getHal()->getCompositionDelayMax(&delay);
421 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(delay));
Lais Andrade4aa80c92021-06-03 17:20:16 +0100422}
423
424HalResult<milliseconds> AidlHalWrapper::getPrimitiveDurationMaxInternal() {
425 int32_t delay = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100426 auto status = getHal()->getPwlePrimitiveDurationMax(&delay);
427 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(delay));
Lais Andrade4aa80c92021-06-03 17:20:16 +0100428}
429
430HalResult<int32_t> AidlHalWrapper::getCompositionSizeMaxInternal() {
431 int32_t size = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100432 auto status = getHal()->getCompositionSizeMax(&size);
433 return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
Lais Andrade4aa80c92021-06-03 17:20:16 +0100434}
435
436HalResult<int32_t> AidlHalWrapper::getPwleSizeMaxInternal() {
437 int32_t size = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100438 auto status = getHal()->getPwleCompositionSizeMax(&size);
439 return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
Lais Andrade4aa80c92021-06-03 17:20:16 +0100440}
441
Lais Andrade92f2af52021-03-22 16:12:50 +0000442HalResult<float> AidlHalWrapper::getMinFrequencyInternal() {
443 float minFrequency = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100444 auto status = getHal()->getFrequencyMinimum(&minFrequency);
445 return HalResultFactory::fromStatus<float>(std::move(status), minFrequency);
Lais Andrade92f2af52021-03-22 16:12:50 +0000446}
447
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000448HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() {
449 float f0 = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100450 auto status = getHal()->getResonantFrequency(&f0);
451 return HalResultFactory::fromStatus<float>(std::move(status), f0);
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000452}
453
Lais Andrade92f2af52021-03-22 16:12:50 +0000454HalResult<float> AidlHalWrapper::getFrequencyResolutionInternal() {
455 float frequencyResolution = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100456 auto status = getHal()->getFrequencyResolution(&frequencyResolution);
457 return HalResultFactory::fromStatus<float>(std::move(status), frequencyResolution);
Lais Andrade92f2af52021-03-22 16:12:50 +0000458}
459
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000460HalResult<float> AidlHalWrapper::getQFactorInternal() {
461 float qFactor = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100462 auto status = getHal()->getQFactor(&qFactor);
463 return HalResultFactory::fromStatus<float>(std::move(status), qFactor);
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000464}
465
Lais Andrade92f2af52021-03-22 16:12:50 +0000466HalResult<std::vector<float>> AidlHalWrapper::getMaxAmplitudesInternal() {
467 std::vector<float> amplitudes;
Lais Andrade818a2252024-06-24 14:48:14 +0100468 auto status = getHal()->getBandwidthAmplitudeMap(&amplitudes);
469 return HalResultFactory::fromStatus<std::vector<float>>(std::move(status), amplitudes);
Lais Andrade92f2af52021-03-22 16:12:50 +0000470}
471
Ahmad Khalil193e37b2024-09-02 10:05:50 +0000472HalResult<int32_t> AidlHalWrapper::getMaxEnvelopeEffectSizeInternal() {
473 int32_t size = 0;
474 auto status = getHal()->getPwleV2CompositionSizeMax(&size);
475 return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
476}
477
478HalResult<milliseconds> AidlHalWrapper::getMinEnvelopeEffectControlPointDurationInternal() {
479 int32_t durationMs = 0;
480 auto status = getHal()->getPwleV2PrimitiveDurationMinMillis(&durationMs);
481 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(durationMs));
482}
483
484HalResult<milliseconds> AidlHalWrapper::getMaxEnvelopeEffectControlPointDurationInternal() {
485 int32_t durationMs = 0;
486 auto status = getHal()->getPwleV2PrimitiveDurationMaxMillis(&durationMs);
487 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(durationMs));
488}
489
Lais Andrade818a2252024-06-24 14:48:14 +0100490std::shared_ptr<Aidl::IVibrator> AidlHalWrapper::getHal() {
Lais Andradecfd81152020-07-01 09:00:26 +0000491 std::lock_guard<std::mutex> lock(mHandleMutex);
492 return mHandle;
493}
494
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100495// -------------------------------------------------------------------------------------------------
496
Lais Andradecfd81152020-07-01 09:00:26 +0000497template <typename I>
498HalResult<void> HidlHalWrapper<I>::ping() {
Lais Andrade818a2252024-06-24 14:48:14 +0100499 return HalResultFactory::fromReturn(getHal()->ping());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100500}
501
Lais Andradecfd81152020-07-01 09:00:26 +0000502template <typename I>
503void HidlHalWrapper<I>::tryReconnect() {
504 sp<I> newHandle = I::tryGetService();
505 if (newHandle) {
506 std::lock_guard<std::mutex> lock(mHandleMutex);
507 mHandle = std::move(newHandle);
508 }
509}
510
511template <typename I>
512HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
513 const std::function<void()>& completionCallback) {
Lais Andrade818a2252024-06-24 14:48:14 +0100514 auto status = getHal()->on(timeout.count());
515 auto ret = HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000516 if (ret.isOk()) {
517 mCallbackScheduler->schedule(completionCallback, timeout);
518 }
519 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100520}
521
Lais Andradecfd81152020-07-01 09:00:26 +0000522template <typename I>
523HalResult<void> HidlHalWrapper<I>::off() {
Lais Andrade818a2252024-06-24 14:48:14 +0100524 auto status = getHal()->off();
525 return HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100526}
527
Lais Andradecfd81152020-07-01 09:00:26 +0000528template <typename I>
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000529HalResult<void> HidlHalWrapper<I>::setAmplitude(float amplitude) {
530 uint8_t amp = static_cast<uint8_t>(amplitude * std::numeric_limits<uint8_t>::max());
Lais Andrade818a2252024-06-24 14:48:14 +0100531 auto status = getHal()->setAmplitude(amp);
532 return HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100533}
534
Lais Andradecfd81152020-07-01 09:00:26 +0000535template <typename I>
536HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100537 ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
538 return HalResult<void>::unsupported();
539}
540
Lais Andradecfd81152020-07-01 09:00:26 +0000541template <typename I>
542HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100543 ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
544 return HalResult<void>::unsupported();
545}
546
Lais Andradecfd81152020-07-01 09:00:26 +0000547template <typename I>
548HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100549 ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
550 return HalResult<void>::unsupported();
551}
552
Lais Andradecfd81152020-07-01 09:00:26 +0000553template <typename I>
Lais Andradecfd81152020-07-01 09:00:26 +0000554HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
555 hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
Lais Andraded39ff7d2020-05-19 10:42:51 +0000556 Capabilities capabilities =
557 result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
Lais Andrade818a2252024-06-24 14:48:14 +0100558 return HalResultFactory::fromReturn<Capabilities>(std::move(result), capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000559}
560
Lais Andradecfd81152020-07-01 09:00:26 +0000561template <typename I>
562template <typename T>
563HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
564 perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
Lais Andrade10d9dc72020-05-20 12:00:49 +0000565 const std::function<void()>& completionCallback) {
566 V1_0::Status status;
567 int32_t lengthMs;
568 auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
569 status = retStatus;
570 lengthMs = retLengthMs;
571 };
572
573 V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
574 auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
575 milliseconds length = milliseconds(lengthMs);
576
Lais Andrade818a2252024-06-24 14:48:14 +0100577 auto ret = HalResultFactory::fromReturn<milliseconds>(std::move(result), status, length);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000578 if (ret.isOk()) {
579 mCallbackScheduler->schedule(completionCallback, length);
580 }
581
582 return ret;
583}
584
Lais Andradecfd81152020-07-01 09:00:26 +0000585template <typename I>
586sp<I> HidlHalWrapper<I>::getHal() {
587 std::lock_guard<std::mutex> lock(mHandleMutex);
588 return mHandle;
589}
590
591// -------------------------------------------------------------------------------------------------
592
593HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
Lais Andrade10d9dc72020-05-20 12:00:49 +0000594 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andradecfd81152020-07-01 09:00:26 +0000595 if (isStaticCastValid<V1_0::Effect>(effect)) {
596 return performInternal(&V1_0::IVibrator::perform, getHal(),
597 static_cast<V1_0::Effect>(effect), strength, completionCallback);
598 }
599
600 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
601 Aidl::toString(effect).c_str());
602 return HalResult<milliseconds>::unsupported();
Lais Andrade10d9dc72020-05-20 12:00:49 +0000603}
604
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100605// -------------------------------------------------------------------------------------------------
606
Lais Andrade10d9dc72020-05-20 12:00:49 +0000607HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
608 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100609 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000610 return performInternal(&V1_1::IVibrator::perform, getHal(),
611 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100612 }
613 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000614 return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
615 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100616 }
617
618 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
619 Aidl::toString(effect).c_str());
620 return HalResult<milliseconds>::unsupported();
621}
622
623// -------------------------------------------------------------------------------------------------
624
Lais Andrade10d9dc72020-05-20 12:00:49 +0000625HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
626 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100627 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000628 return performInternal(&V1_2::IVibrator::perform, getHal(),
629 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100630 }
631 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000632 return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
633 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100634 }
635 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000636 return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
637 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100638 }
639
640 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
641 Aidl::toString(effect).c_str());
642 return HalResult<milliseconds>::unsupported();
643}
644
645// -------------------------------------------------------------------------------------------------
646
647HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000648 auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
Lais Andrade641248e2024-02-16 17:49:36 +0000649 return HalResultFactory::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100650}
651
Lais Andrade10d9dc72020-05-20 12:00:49 +0000652HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
653 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100654 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000655 return performInternal(&V1_3::IVibrator::perform, getHal(),
656 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100657 }
658 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000659 return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
660 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100661 }
662 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000663 return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
664 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100665 }
666 if (isStaticCastValid<V1_3::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000667 return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
668 static_cast<V1_3::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100669 }
670
671 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
672 Aidl::toString(effect).c_str());
673 return HalResult<milliseconds>::unsupported();
674}
675
Lais Andraded39ff7d2020-05-19 10:42:51 +0000676HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
Lais Andrade08666612020-08-07 16:16:31 +0000677 Capabilities capabilities = Capabilities::NONE;
678
Lais Andradecfd81152020-07-01 09:00:26 +0000679 sp<V1_3::IVibrator> hal = getHal();
680 auto amplitudeResult = hal->supportsAmplitudeControl();
681 if (!amplitudeResult.isOk()) {
Lais Andrade818a2252024-06-24 14:48:14 +0100682 return HalResultFactory::fromReturn<Capabilities>(std::move(amplitudeResult), capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000683 }
684
Lais Andradecfd81152020-07-01 09:00:26 +0000685 auto externalControlResult = hal->supportsExternalControl();
Lais Andradecfd81152020-07-01 09:00:26 +0000686 if (amplitudeResult.withDefault(false)) {
687 capabilities |= Capabilities::AMPLITUDE_CONTROL;
688 }
689 if (externalControlResult.withDefault(false)) {
690 capabilities |= Capabilities::EXTERNAL_CONTROL;
Lais Andrade602ff962020-08-27 12:02:53 +0000691
692 if (amplitudeResult.withDefault(false)) {
693 capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL;
694 }
Lais Andradecfd81152020-07-01 09:00:26 +0000695 }
696
Lais Andrade818a2252024-06-24 14:48:14 +0100697 return HalResultFactory::fromReturn<Capabilities>(std::move(externalControlResult),
698 capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000699}
700
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100701// -------------------------------------------------------------------------------------------------
702
703}; // namespace vibrator
704
705}; // namespace android