blob: 3d8124b81bdac68aa4200ce5cdf248be11eaa8f0 [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 }
Lais Andrade965284b2021-03-19 20:58:15 +000099 return mInfoCache.get();
100}
101
Lais Andradef172ea12024-07-12 13:45:01 +0100102HalResult<void> HalWrapper::performVendorEffect(const VendorEffect&, const std::function<void()>&) {
103 ALOGV("Skipped performVendorEffect because it's not available in Vibrator HAL");
104 return HalResult<void>::unsupported();
105}
106
Lais Andrade92f2af52021-03-22 16:12:50 +0000107HalResult<milliseconds> HalWrapper::performComposedEffect(const std::vector<CompositeEffect>&,
108 const std::function<void()>&) {
109 ALOGV("Skipped performComposedEffect because it's not available in Vibrator HAL");
110 return HalResult<milliseconds>::unsupported();
111}
112
113HalResult<void> HalWrapper::performPwleEffect(const std::vector<PrimitivePwle>&,
114 const std::function<void()>&) {
115 ALOGV("Skipped performPwleEffect because it's not available in Vibrator HAL");
116 return HalResult<void>::unsupported();
117}
118
Ahmad Khalil11111892024-08-05 17:40:17 +0000119HalResult<void> HalWrapper::composePwleV2(const std::vector<PwleV2Primitive>&,
120 const std::function<void()>&) {
121 ALOGV("Skipped composePwleV2 because it's not available in Vibrator HAL");
122 return HalResult<void>::unsupported();
123}
124
Lais Andrade965284b2021-03-19 20:58:15 +0000125HalResult<Capabilities> HalWrapper::getCapabilities() {
126 std::lock_guard<std::mutex> lock(mInfoMutex);
127 if (mInfoCache.mCapabilities.isFailed()) {
128 mInfoCache.mCapabilities = getCapabilitiesInternal();
129 }
130 return mInfoCache.mCapabilities;
131}
132
133HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurations() {
134 std::lock_guard<std::mutex> lock(mInfoMutex);
135 if (mInfoCache.mSupportedPrimitives.isFailed()) {
136 mInfoCache.mSupportedPrimitives = getSupportedPrimitivesInternal();
137 if (mInfoCache.mSupportedPrimitives.isUnsupported()) {
138 mInfoCache.mPrimitiveDurations = HalResult<std::vector<milliseconds>>::unsupported();
139 }
140 }
141 if (mInfoCache.mPrimitiveDurations.isFailed() && mInfoCache.mSupportedPrimitives.isOk()) {
142 mInfoCache.mPrimitiveDurations =
143 getPrimitiveDurationsInternal(mInfoCache.mSupportedPrimitives.value());
144 }
145 return mInfoCache.mPrimitiveDurations;
146}
147
148HalResult<std::vector<Effect>> HalWrapper::getSupportedEffectsInternal() {
149 ALOGV("Skipped getSupportedEffects because it's not available in Vibrator HAL");
150 return HalResult<std::vector<Effect>>::unsupported();
151}
152
Lais Andrade92f2af52021-03-22 16:12:50 +0000153HalResult<std::vector<Braking>> HalWrapper::getSupportedBrakingInternal() {
154 ALOGV("Skipped getSupportedBraking because it's not available in Vibrator HAL");
155 return HalResult<std::vector<Braking>>::unsupported();
156}
157
Lais Andrade965284b2021-03-19 20:58:15 +0000158HalResult<std::vector<CompositePrimitive>> HalWrapper::getSupportedPrimitivesInternal() {
159 ALOGV("Skipped getSupportedPrimitives because it's not available in Vibrator HAL");
160 return HalResult<std::vector<CompositePrimitive>>::unsupported();
161}
162
163HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurationsInternal(
164 const std::vector<CompositePrimitive>&) {
165 ALOGV("Skipped getPrimitiveDurations because it's not available in Vibrator HAL");
166 return HalResult<std::vector<milliseconds>>::unsupported();
167}
168
Lais Andrade4aa80c92021-06-03 17:20:16 +0100169HalResult<milliseconds> HalWrapper::getPrimitiveDelayMaxInternal() {
170 ALOGV("Skipped getPrimitiveDelayMaxInternal because it's not available in Vibrator HAL");
171 return HalResult<milliseconds>::unsupported();
172}
173
174HalResult<milliseconds> HalWrapper::getPrimitiveDurationMaxInternal() {
175 ALOGV("Skipped getPrimitiveDurationMaxInternal because it's not available in Vibrator HAL");
176 return HalResult<milliseconds>::unsupported();
177}
178
179HalResult<int32_t> HalWrapper::getCompositionSizeMaxInternal() {
180 ALOGV("Skipped getCompositionSizeMaxInternal because it's not available in Vibrator HAL");
181 return HalResult<int32_t>::unsupported();
182}
183
184HalResult<int32_t> HalWrapper::getPwleSizeMaxInternal() {
185 ALOGV("Skipped getPwleSizeMaxInternal because it's not available in Vibrator HAL");
186 return HalResult<int32_t>::unsupported();
187}
188
Lais Andrade92f2af52021-03-22 16:12:50 +0000189HalResult<float> HalWrapper::getMinFrequencyInternal() {
190 ALOGV("Skipped getMinFrequency because it's not available in Vibrator HAL");
191 return HalResult<float>::unsupported();
192}
193
Lais Andrade965284b2021-03-19 20:58:15 +0000194HalResult<float> HalWrapper::getResonantFrequencyInternal() {
195 ALOGV("Skipped getResonantFrequency because it's not available in Vibrator HAL");
196 return HalResult<float>::unsupported();
197}
198
Lais Andrade92f2af52021-03-22 16:12:50 +0000199HalResult<float> HalWrapper::getFrequencyResolutionInternal() {
200 ALOGV("Skipped getFrequencyResolution because it's not available in Vibrator HAL");
201 return HalResult<float>::unsupported();
202}
203
Lais Andrade965284b2021-03-19 20:58:15 +0000204HalResult<float> HalWrapper::getQFactorInternal() {
205 ALOGV("Skipped getQFactor because it's not available in Vibrator HAL");
206 return HalResult<float>::unsupported();
207}
208
Lais Andrade92f2af52021-03-22 16:12:50 +0000209HalResult<std::vector<float>> HalWrapper::getMaxAmplitudesInternal() {
210 ALOGV("Skipped getMaxAmplitudes because it's not available in Vibrator HAL");
211 return HalResult<std::vector<float>>::unsupported();
212}
213
Lais Andrade965284b2021-03-19 20:58:15 +0000214// -------------------------------------------------------------------------------------------------
215
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100216HalResult<void> AidlHalWrapper::ping() {
Lais Andrade818a2252024-06-24 14:48:14 +0100217 return HalResultFactory::fromStatus(AIBinder_ping(getHal()->asBinder().get()));
Lais Andradecfd81152020-07-01 09:00:26 +0000218}
219
220void AidlHalWrapper::tryReconnect() {
Lais Andrade98c97032020-11-17 19:23:01 +0000221 auto result = mReconnectFn();
222 if (!result.isOk()) {
223 return;
224 }
Lais Andrade818a2252024-06-24 14:48:14 +0100225 std::shared_ptr<Aidl::IVibrator> newHandle = result.value();
Lais Andradecfd81152020-07-01 09:00:26 +0000226 if (newHandle) {
227 std::lock_guard<std::mutex> lock(mHandleMutex);
228 mHandle = std::move(newHandle);
229 }
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100230}
231
232HalResult<void> AidlHalWrapper::on(milliseconds timeout,
233 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000234 HalResult<Capabilities> capabilities = getCapabilities();
235 bool supportsCallback = capabilities.isOk() &&
236 static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
Lais Andrade818a2252024-06-24 14:48:14 +0100237 auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
238 : nullptr;
Lais Andrade10d9dc72020-05-20 12:00:49 +0000239
Lais Andrade641248e2024-02-16 17:49:36 +0000240 auto ret = HalResultFactory::fromStatus(getHal()->on(timeout.count(), cb));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000241 if (!supportsCallback && ret.isOk()) {
242 mCallbackScheduler->schedule(completionCallback, timeout);
243 }
244
245 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100246}
247
248HalResult<void> AidlHalWrapper::off() {
Lais Andrade641248e2024-02-16 17:49:36 +0000249 return HalResultFactory::fromStatus(getHal()->off());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100250}
251
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000252HalResult<void> AidlHalWrapper::setAmplitude(float amplitude) {
Lais Andrade641248e2024-02-16 17:49:36 +0000253 return HalResultFactory::fromStatus(getHal()->setAmplitude(amplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100254}
255
256HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
Lais Andrade641248e2024-02-16 17:49:36 +0000257 return HalResultFactory::fromStatus(getHal()->setExternalControl(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100258}
259
260HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
Lais Andrade641248e2024-02-16 17:49:36 +0000261 return HalResultFactory::fromStatus(getHal()->alwaysOnEnable(id, effect, strength));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100262}
263
264HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
Lais Andrade641248e2024-02-16 17:49:36 +0000265 return HalResultFactory::fromStatus(getHal()->alwaysOnDisable(id));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100266}
267
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100268HalResult<milliseconds> AidlHalWrapper::performEffect(
269 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000270 HalResult<Capabilities> capabilities = getCapabilities();
271 bool supportsCallback = capabilities.isOk() &&
272 static_cast<int32_t>(capabilities.value() & Capabilities::PERFORM_CALLBACK);
Lais Andrade818a2252024-06-24 14:48:14 +0100273 auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
274 : nullptr;
Lais Andrade10d9dc72020-05-20 12:00:49 +0000275
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100276 int32_t lengthMs;
Lais Andrade818a2252024-06-24 14:48:14 +0100277 auto status = getHal()->perform(effect, strength, cb, &lengthMs);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000278 milliseconds length = milliseconds(lengthMs);
279
Lais Andrade818a2252024-06-24 14:48:14 +0100280 auto ret = HalResultFactory::fromStatus<milliseconds>(std::move(status), length);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000281 if (!supportsCallback && ret.isOk()) {
282 mCallbackScheduler->schedule(completionCallback, length);
283 }
284
285 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100286}
287
Lais Andradef172ea12024-07-12 13:45:01 +0100288HalResult<void> AidlHalWrapper::performVendorEffect(
289 const VendorEffect& effect, const std::function<void()>& completionCallback) {
290 // This method should always support callbacks, so no need to double check.
291 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
292 return HalResultFactory::fromStatus(getHal()->performVendorEffect(effect, cb));
293}
294
Lais Andrade49b60b12021-02-23 13:27:41 +0000295HalResult<milliseconds> AidlHalWrapper::performComposedEffect(
Lais Andrade92f2af52021-03-22 16:12:50 +0000296 const std::vector<CompositeEffect>& primitives,
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100297 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000298 // This method should always support callbacks, so no need to double check.
Lais Andrade818a2252024-06-24 14:48:14 +0100299 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
Lais Andrade965284b2021-03-19 20:58:15 +0000300
301 auto durations = getPrimitiveDurations().valueOr({});
Lais Andrade49b60b12021-02-23 13:27:41 +0000302 milliseconds duration(0);
Lais Andrade92f2af52021-03-22 16:12:50 +0000303 for (const auto& effect : primitives) {
Lais Andrade965284b2021-03-19 20:58:15 +0000304 auto primitiveIdx = static_cast<size_t>(effect.primitive);
305 if (primitiveIdx < durations.size()) {
306 duration += durations[primitiveIdx];
307 } else {
308 // Make sure the returned duration is positive to indicate successful vibration.
309 duration += milliseconds(1);
Lais Andrade49b60b12021-02-23 13:27:41 +0000310 }
311 duration += milliseconds(effect.delayMs);
312 }
Lais Andrade49b60b12021-02-23 13:27:41 +0000313
Lais Andrade641248e2024-02-16 17:49:36 +0000314 return HalResultFactory::fromStatus<milliseconds>(getHal()->compose(primitives, cb), duration);
Lais Andrade92f2af52021-03-22 16:12:50 +0000315}
316
317HalResult<void> AidlHalWrapper::performPwleEffect(const std::vector<PrimitivePwle>& primitives,
318 const std::function<void()>& completionCallback) {
319 // This method should always support callbacks, so no need to double check.
Lais Andrade818a2252024-06-24 14:48:14 +0100320 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
Lais Andrade641248e2024-02-16 17:49:36 +0000321 return HalResultFactory::fromStatus(getHal()->composePwle(primitives, cb));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100322}
323
Ahmad Khalil11111892024-08-05 17:40:17 +0000324HalResult<void> AidlHalWrapper::composePwleV2(const std::vector<PwleV2Primitive>& composite,
325 const std::function<void()>& completionCallback) {
326 // This method should always support callbacks, so no need to double check.
327 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
328 return HalResultFactory::fromStatus(getHal()->composePwleV2(composite, cb));
329}
330
Lais Andrade10d9dc72020-05-20 12:00:49 +0000331HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
Lais Andrade818a2252024-06-24 14:48:14 +0100332 int32_t cap = 0;
333 auto status = getHal()->getCapabilities(&cap);
334 auto capabilities = static_cast<Capabilities>(cap);
335 return HalResultFactory::fromStatus<Capabilities>(std::move(status), capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000336}
337
338HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
339 std::vector<Effect> supportedEffects;
Lais Andrade818a2252024-06-24 14:48:14 +0100340 auto status = getHal()->getSupportedEffects(&supportedEffects);
341 return HalResultFactory::fromStatus<std::vector<Effect>>(std::move(status), supportedEffects);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000342}
343
Lais Andrade92f2af52021-03-22 16:12:50 +0000344HalResult<std::vector<Braking>> AidlHalWrapper::getSupportedBrakingInternal() {
345 std::vector<Braking> supportedBraking;
Lais Andrade818a2252024-06-24 14:48:14 +0100346 auto status = getHal()->getSupportedBraking(&supportedBraking);
347 return HalResultFactory::fromStatus<std::vector<Braking>>(std::move(status), supportedBraking);
Lais Andrade92f2af52021-03-22 16:12:50 +0000348}
349
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000350HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() {
351 std::vector<CompositePrimitive> supportedPrimitives;
Lais Andrade818a2252024-06-24 14:48:14 +0100352 auto status = getHal()->getSupportedPrimitives(&supportedPrimitives);
353 return HalResultFactory::fromStatus<std::vector<CompositePrimitive>>(std::move(status),
Lais Andrade641248e2024-02-16 17:49:36 +0000354 supportedPrimitives);
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000355}
356
Lais Andrade965284b2021-03-19 20:58:15 +0000357HalResult<std::vector<milliseconds>> AidlHalWrapper::getPrimitiveDurationsInternal(
358 const std::vector<CompositePrimitive>& supportedPrimitives) {
359 std::vector<milliseconds> durations;
Lais Andrade818a2252024-06-24 14:48:14 +0100360 constexpr auto primitiveRange = ndk::enum_range<CompositePrimitive>();
Lais Andrade965284b2021-03-19 20:58:15 +0000361 constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
362 durations.resize(primitiveCount);
363
364 for (auto primitive : supportedPrimitives) {
365 auto primitiveIdx = static_cast<size_t>(primitive);
366 if (primitiveIdx >= durations.size()) {
367 // Safety check, should not happen if enum_range is correct.
Lais Andrade4928bfd2021-08-25 18:21:12 +0100368 ALOGE("Supported primitive %zu is outside range [0,%zu), skipping load duration",
369 primitiveIdx, durations.size());
Lais Andrade965284b2021-03-19 20:58:15 +0000370 continue;
371 }
372 int32_t duration = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100373 auto status = getHal()->getPrimitiveDuration(primitive, &duration);
374 auto halResult = HalResultFactory::fromStatus<int32_t>(std::move(status), duration);
Lais Andrade4928bfd2021-08-25 18:21:12 +0100375 if (halResult.isUnsupported()) {
376 // Should not happen, supported primitives should always support requesting duration.
377 ALOGE("Supported primitive %zu returned unsupported for getPrimitiveDuration",
378 primitiveIdx);
379 }
380 if (halResult.isFailed()) {
381 // Fail entire request if one request has failed.
Lais Andradef172ea12024-07-12 13:45:01 +0100382 return HalResult<std::vector<milliseconds>>::failed(halResult.errorMessage());
Lais Andrade965284b2021-03-19 20:58:15 +0000383 }
384 durations[primitiveIdx] = milliseconds(duration);
385 }
386
387 return HalResult<std::vector<milliseconds>>::ok(durations);
388}
389
Lais Andrade4aa80c92021-06-03 17:20:16 +0100390HalResult<milliseconds> AidlHalWrapper::getPrimitiveDelayMaxInternal() {
391 int32_t delay = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100392 auto status = getHal()->getCompositionDelayMax(&delay);
393 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(delay));
Lais Andrade4aa80c92021-06-03 17:20:16 +0100394}
395
396HalResult<milliseconds> AidlHalWrapper::getPrimitiveDurationMaxInternal() {
397 int32_t delay = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100398 auto status = getHal()->getPwlePrimitiveDurationMax(&delay);
399 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(delay));
Lais Andrade4aa80c92021-06-03 17:20:16 +0100400}
401
402HalResult<int32_t> AidlHalWrapper::getCompositionSizeMaxInternal() {
403 int32_t size = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100404 auto status = getHal()->getCompositionSizeMax(&size);
405 return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
Lais Andrade4aa80c92021-06-03 17:20:16 +0100406}
407
408HalResult<int32_t> AidlHalWrapper::getPwleSizeMaxInternal() {
409 int32_t size = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100410 auto status = getHal()->getPwleCompositionSizeMax(&size);
411 return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
Lais Andrade4aa80c92021-06-03 17:20:16 +0100412}
413
Lais Andrade92f2af52021-03-22 16:12:50 +0000414HalResult<float> AidlHalWrapper::getMinFrequencyInternal() {
415 float minFrequency = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100416 auto status = getHal()->getFrequencyMinimum(&minFrequency);
417 return HalResultFactory::fromStatus<float>(std::move(status), minFrequency);
Lais Andrade92f2af52021-03-22 16:12:50 +0000418}
419
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000420HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() {
421 float f0 = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100422 auto status = getHal()->getResonantFrequency(&f0);
423 return HalResultFactory::fromStatus<float>(std::move(status), f0);
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000424}
425
Lais Andrade92f2af52021-03-22 16:12:50 +0000426HalResult<float> AidlHalWrapper::getFrequencyResolutionInternal() {
427 float frequencyResolution = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100428 auto status = getHal()->getFrequencyResolution(&frequencyResolution);
429 return HalResultFactory::fromStatus<float>(std::move(status), frequencyResolution);
Lais Andrade92f2af52021-03-22 16:12:50 +0000430}
431
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000432HalResult<float> AidlHalWrapper::getQFactorInternal() {
433 float qFactor = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100434 auto status = getHal()->getQFactor(&qFactor);
435 return HalResultFactory::fromStatus<float>(std::move(status), qFactor);
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000436}
437
Lais Andrade92f2af52021-03-22 16:12:50 +0000438HalResult<std::vector<float>> AidlHalWrapper::getMaxAmplitudesInternal() {
439 std::vector<float> amplitudes;
Lais Andrade818a2252024-06-24 14:48:14 +0100440 auto status = getHal()->getBandwidthAmplitudeMap(&amplitudes);
441 return HalResultFactory::fromStatus<std::vector<float>>(std::move(status), amplitudes);
Lais Andrade92f2af52021-03-22 16:12:50 +0000442}
443
Lais Andrade818a2252024-06-24 14:48:14 +0100444std::shared_ptr<Aidl::IVibrator> AidlHalWrapper::getHal() {
Lais Andradecfd81152020-07-01 09:00:26 +0000445 std::lock_guard<std::mutex> lock(mHandleMutex);
446 return mHandle;
447}
448
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100449// -------------------------------------------------------------------------------------------------
450
Lais Andradecfd81152020-07-01 09:00:26 +0000451template <typename I>
452HalResult<void> HidlHalWrapper<I>::ping() {
Lais Andrade818a2252024-06-24 14:48:14 +0100453 return HalResultFactory::fromReturn(getHal()->ping());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100454}
455
Lais Andradecfd81152020-07-01 09:00:26 +0000456template <typename I>
457void HidlHalWrapper<I>::tryReconnect() {
458 sp<I> newHandle = I::tryGetService();
459 if (newHandle) {
460 std::lock_guard<std::mutex> lock(mHandleMutex);
461 mHandle = std::move(newHandle);
462 }
463}
464
465template <typename I>
466HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
467 const std::function<void()>& completionCallback) {
Lais Andrade818a2252024-06-24 14:48:14 +0100468 auto status = getHal()->on(timeout.count());
469 auto ret = HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000470 if (ret.isOk()) {
471 mCallbackScheduler->schedule(completionCallback, timeout);
472 }
473 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100474}
475
Lais Andradecfd81152020-07-01 09:00:26 +0000476template <typename I>
477HalResult<void> HidlHalWrapper<I>::off() {
Lais Andrade818a2252024-06-24 14:48:14 +0100478 auto status = getHal()->off();
479 return HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100480}
481
Lais Andradecfd81152020-07-01 09:00:26 +0000482template <typename I>
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000483HalResult<void> HidlHalWrapper<I>::setAmplitude(float amplitude) {
484 uint8_t amp = static_cast<uint8_t>(amplitude * std::numeric_limits<uint8_t>::max());
Lais Andrade818a2252024-06-24 14:48:14 +0100485 auto status = getHal()->setAmplitude(amp);
486 return HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100487}
488
Lais Andradecfd81152020-07-01 09:00:26 +0000489template <typename I>
490HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100491 ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
492 return HalResult<void>::unsupported();
493}
494
Lais Andradecfd81152020-07-01 09:00:26 +0000495template <typename I>
496HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100497 ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
498 return HalResult<void>::unsupported();
499}
500
Lais Andradecfd81152020-07-01 09:00:26 +0000501template <typename I>
502HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100503 ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
504 return HalResult<void>::unsupported();
505}
506
Lais Andradecfd81152020-07-01 09:00:26 +0000507template <typename I>
Lais Andradecfd81152020-07-01 09:00:26 +0000508HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
509 hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
Lais Andraded39ff7d2020-05-19 10:42:51 +0000510 Capabilities capabilities =
511 result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
Lais Andrade818a2252024-06-24 14:48:14 +0100512 return HalResultFactory::fromReturn<Capabilities>(std::move(result), capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000513}
514
Lais Andradecfd81152020-07-01 09:00:26 +0000515template <typename I>
516template <typename T>
517HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
518 perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
Lais Andrade10d9dc72020-05-20 12:00:49 +0000519 const std::function<void()>& completionCallback) {
520 V1_0::Status status;
521 int32_t lengthMs;
522 auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
523 status = retStatus;
524 lengthMs = retLengthMs;
525 };
526
527 V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
528 auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
529 milliseconds length = milliseconds(lengthMs);
530
Lais Andrade818a2252024-06-24 14:48:14 +0100531 auto ret = HalResultFactory::fromReturn<milliseconds>(std::move(result), status, length);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000532 if (ret.isOk()) {
533 mCallbackScheduler->schedule(completionCallback, length);
534 }
535
536 return ret;
537}
538
Lais Andradecfd81152020-07-01 09:00:26 +0000539template <typename I>
540sp<I> HidlHalWrapper<I>::getHal() {
541 std::lock_guard<std::mutex> lock(mHandleMutex);
542 return mHandle;
543}
544
545// -------------------------------------------------------------------------------------------------
546
547HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
Lais Andrade10d9dc72020-05-20 12:00:49 +0000548 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andradecfd81152020-07-01 09:00:26 +0000549 if (isStaticCastValid<V1_0::Effect>(effect)) {
550 return performInternal(&V1_0::IVibrator::perform, getHal(),
551 static_cast<V1_0::Effect>(effect), strength, completionCallback);
552 }
553
554 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
555 Aidl::toString(effect).c_str());
556 return HalResult<milliseconds>::unsupported();
Lais Andrade10d9dc72020-05-20 12:00:49 +0000557}
558
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100559// -------------------------------------------------------------------------------------------------
560
Lais Andrade10d9dc72020-05-20 12:00:49 +0000561HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
562 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100563 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000564 return performInternal(&V1_1::IVibrator::perform, getHal(),
565 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100566 }
567 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000568 return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
569 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100570 }
571
572 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
573 Aidl::toString(effect).c_str());
574 return HalResult<milliseconds>::unsupported();
575}
576
577// -------------------------------------------------------------------------------------------------
578
Lais Andrade10d9dc72020-05-20 12:00:49 +0000579HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
580 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100581 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000582 return performInternal(&V1_2::IVibrator::perform, getHal(),
583 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100584 }
585 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000586 return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
587 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100588 }
589 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000590 return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
591 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100592 }
593
594 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
595 Aidl::toString(effect).c_str());
596 return HalResult<milliseconds>::unsupported();
597}
598
599// -------------------------------------------------------------------------------------------------
600
601HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000602 auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
Lais Andrade641248e2024-02-16 17:49:36 +0000603 return HalResultFactory::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100604}
605
Lais Andrade10d9dc72020-05-20 12:00:49 +0000606HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
607 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100608 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000609 return performInternal(&V1_3::IVibrator::perform, getHal(),
610 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100611 }
612 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000613 return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
614 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100615 }
616 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000617 return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
618 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100619 }
620 if (isStaticCastValid<V1_3::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000621 return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
622 static_cast<V1_3::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100623 }
624
625 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
626 Aidl::toString(effect).c_str());
627 return HalResult<milliseconds>::unsupported();
628}
629
Lais Andraded39ff7d2020-05-19 10:42:51 +0000630HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
Lais Andrade08666612020-08-07 16:16:31 +0000631 Capabilities capabilities = Capabilities::NONE;
632
Lais Andradecfd81152020-07-01 09:00:26 +0000633 sp<V1_3::IVibrator> hal = getHal();
634 auto amplitudeResult = hal->supportsAmplitudeControl();
635 if (!amplitudeResult.isOk()) {
Lais Andrade818a2252024-06-24 14:48:14 +0100636 return HalResultFactory::fromReturn<Capabilities>(std::move(amplitudeResult), capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000637 }
638
Lais Andradecfd81152020-07-01 09:00:26 +0000639 auto externalControlResult = hal->supportsExternalControl();
Lais Andradecfd81152020-07-01 09:00:26 +0000640 if (amplitudeResult.withDefault(false)) {
641 capabilities |= Capabilities::AMPLITUDE_CONTROL;
642 }
643 if (externalControlResult.withDefault(false)) {
644 capabilities |= Capabilities::EXTERNAL_CONTROL;
Lais Andrade602ff962020-08-27 12:02:53 +0000645
646 if (amplitudeResult.withDefault(false)) {
647 capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL;
648 }
Lais Andradecfd81152020-07-01 09:00:26 +0000649 }
650
Lais Andrade818a2252024-06-24 14:48:14 +0100651 return HalResultFactory::fromReturn<Capabilities>(std::move(externalControlResult),
652 capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000653}
654
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100655// -------------------------------------------------------------------------------------------------
656
657}; // namespace vibrator
658
659}; // namespace android