blob: c97f4014eb2eb2bf11075f8961729f745d2cb6bd [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;
Lais Andradef172ea12024-07-12 13:45:01 +010035using aidl::android::hardware::vibrator::VendorEffect;
Lais Andrade9e9fcc92020-04-07 20:13:08 +010036
37using std::chrono::milliseconds;
38
39namespace V1_0 = android::hardware::vibrator::V1_0;
40namespace V1_1 = android::hardware::vibrator::V1_1;
41namespace V1_2 = android::hardware::vibrator::V1_2;
42namespace V1_3 = android::hardware::vibrator::V1_3;
Lais Andrade818a2252024-06-24 14:48:14 +010043namespace Aidl = aidl::android::hardware::vibrator;
Lais Andrade9e9fcc92020-04-07 20:13:08 +010044
45namespace android {
46
47namespace vibrator {
48
49// -------------------------------------------------------------------------------------------------
50
51template <class T>
52bool isStaticCastValid(Effect effect) {
53 T castEffect = static_cast<T>(effect);
54 auto iter = hardware::hidl_enum_range<T>();
55 return castEffect >= *iter.begin() && castEffect <= *std::prev(iter.end());
56}
57
Lais Andrade9e9fcc92020-04-07 20:13:08 +010058// -------------------------------------------------------------------------------------------------
59
Lais Andrade965284b2021-03-19 20:58:15 +000060Info HalWrapper::getInfo() {
61 getCapabilities();
62 getPrimitiveDurations();
63 std::lock_guard<std::mutex> lock(mInfoMutex);
64 if (mInfoCache.mSupportedEffects.isFailed()) {
65 mInfoCache.mSupportedEffects = getSupportedEffectsInternal();
66 }
Lais Andrade92f2af52021-03-22 16:12:50 +000067 if (mInfoCache.mSupportedBraking.isFailed()) {
68 mInfoCache.mSupportedBraking = getSupportedBrakingInternal();
69 }
Lais Andrade4aa80c92021-06-03 17:20:16 +010070 if (mInfoCache.mPrimitiveDelayMax.isFailed()) {
71 mInfoCache.mPrimitiveDelayMax = getPrimitiveDelayMaxInternal();
72 }
73 if (mInfoCache.mPwlePrimitiveDurationMax.isFailed()) {
74 mInfoCache.mPwlePrimitiveDurationMax = getPrimitiveDurationMaxInternal();
75 }
76 if (mInfoCache.mCompositionSizeMax.isFailed()) {
77 mInfoCache.mCompositionSizeMax = getCompositionSizeMaxInternal();
78 }
79 if (mInfoCache.mPwleSizeMax.isFailed()) {
80 mInfoCache.mPwleSizeMax = getPwleSizeMaxInternal();
81 }
Lais Andrade92f2af52021-03-22 16:12:50 +000082 if (mInfoCache.mMinFrequency.isFailed()) {
83 mInfoCache.mMinFrequency = getMinFrequencyInternal();
84 }
Lais Andrade965284b2021-03-19 20:58:15 +000085 if (mInfoCache.mResonantFrequency.isFailed()) {
86 mInfoCache.mResonantFrequency = getResonantFrequencyInternal();
87 }
Lais Andrade92f2af52021-03-22 16:12:50 +000088 if (mInfoCache.mFrequencyResolution.isFailed()) {
89 mInfoCache.mFrequencyResolution = getFrequencyResolutionInternal();
90 }
Lais Andrade965284b2021-03-19 20:58:15 +000091 if (mInfoCache.mQFactor.isFailed()) {
92 mInfoCache.mQFactor = getQFactorInternal();
93 }
Lais Andrade92f2af52021-03-22 16:12:50 +000094 if (mInfoCache.mMaxAmplitudes.isFailed()) {
95 mInfoCache.mMaxAmplitudes = getMaxAmplitudesInternal();
96 }
Lais Andrade965284b2021-03-19 20:58:15 +000097 return mInfoCache.get();
98}
99
Lais Andradef172ea12024-07-12 13:45:01 +0100100HalResult<void> HalWrapper::performVendorEffect(const VendorEffect&, const std::function<void()>&) {
101 ALOGV("Skipped performVendorEffect because it's not available in Vibrator HAL");
102 return HalResult<void>::unsupported();
103}
104
Lais Andrade92f2af52021-03-22 16:12:50 +0000105HalResult<milliseconds> HalWrapper::performComposedEffect(const std::vector<CompositeEffect>&,
106 const std::function<void()>&) {
107 ALOGV("Skipped performComposedEffect because it's not available in Vibrator HAL");
108 return HalResult<milliseconds>::unsupported();
109}
110
111HalResult<void> HalWrapper::performPwleEffect(const std::vector<PrimitivePwle>&,
112 const std::function<void()>&) {
113 ALOGV("Skipped performPwleEffect because it's not available in Vibrator HAL");
114 return HalResult<void>::unsupported();
115}
116
Lais Andrade965284b2021-03-19 20:58:15 +0000117HalResult<Capabilities> HalWrapper::getCapabilities() {
118 std::lock_guard<std::mutex> lock(mInfoMutex);
119 if (mInfoCache.mCapabilities.isFailed()) {
120 mInfoCache.mCapabilities = getCapabilitiesInternal();
121 }
122 return mInfoCache.mCapabilities;
123}
124
125HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurations() {
126 std::lock_guard<std::mutex> lock(mInfoMutex);
127 if (mInfoCache.mSupportedPrimitives.isFailed()) {
128 mInfoCache.mSupportedPrimitives = getSupportedPrimitivesInternal();
129 if (mInfoCache.mSupportedPrimitives.isUnsupported()) {
130 mInfoCache.mPrimitiveDurations = HalResult<std::vector<milliseconds>>::unsupported();
131 }
132 }
133 if (mInfoCache.mPrimitiveDurations.isFailed() && mInfoCache.mSupportedPrimitives.isOk()) {
134 mInfoCache.mPrimitiveDurations =
135 getPrimitiveDurationsInternal(mInfoCache.mSupportedPrimitives.value());
136 }
137 return mInfoCache.mPrimitiveDurations;
138}
139
140HalResult<std::vector<Effect>> HalWrapper::getSupportedEffectsInternal() {
141 ALOGV("Skipped getSupportedEffects because it's not available in Vibrator HAL");
142 return HalResult<std::vector<Effect>>::unsupported();
143}
144
Lais Andrade92f2af52021-03-22 16:12:50 +0000145HalResult<std::vector<Braking>> HalWrapper::getSupportedBrakingInternal() {
146 ALOGV("Skipped getSupportedBraking because it's not available in Vibrator HAL");
147 return HalResult<std::vector<Braking>>::unsupported();
148}
149
Lais Andrade965284b2021-03-19 20:58:15 +0000150HalResult<std::vector<CompositePrimitive>> HalWrapper::getSupportedPrimitivesInternal() {
151 ALOGV("Skipped getSupportedPrimitives because it's not available in Vibrator HAL");
152 return HalResult<std::vector<CompositePrimitive>>::unsupported();
153}
154
155HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurationsInternal(
156 const std::vector<CompositePrimitive>&) {
157 ALOGV("Skipped getPrimitiveDurations because it's not available in Vibrator HAL");
158 return HalResult<std::vector<milliseconds>>::unsupported();
159}
160
Lais Andrade4aa80c92021-06-03 17:20:16 +0100161HalResult<milliseconds> HalWrapper::getPrimitiveDelayMaxInternal() {
162 ALOGV("Skipped getPrimitiveDelayMaxInternal because it's not available in Vibrator HAL");
163 return HalResult<milliseconds>::unsupported();
164}
165
166HalResult<milliseconds> HalWrapper::getPrimitiveDurationMaxInternal() {
167 ALOGV("Skipped getPrimitiveDurationMaxInternal because it's not available in Vibrator HAL");
168 return HalResult<milliseconds>::unsupported();
169}
170
171HalResult<int32_t> HalWrapper::getCompositionSizeMaxInternal() {
172 ALOGV("Skipped getCompositionSizeMaxInternal because it's not available in Vibrator HAL");
173 return HalResult<int32_t>::unsupported();
174}
175
176HalResult<int32_t> HalWrapper::getPwleSizeMaxInternal() {
177 ALOGV("Skipped getPwleSizeMaxInternal because it's not available in Vibrator HAL");
178 return HalResult<int32_t>::unsupported();
179}
180
Lais Andrade92f2af52021-03-22 16:12:50 +0000181HalResult<float> HalWrapper::getMinFrequencyInternal() {
182 ALOGV("Skipped getMinFrequency because it's not available in Vibrator HAL");
183 return HalResult<float>::unsupported();
184}
185
Lais Andrade965284b2021-03-19 20:58:15 +0000186HalResult<float> HalWrapper::getResonantFrequencyInternal() {
187 ALOGV("Skipped getResonantFrequency because it's not available in Vibrator HAL");
188 return HalResult<float>::unsupported();
189}
190
Lais Andrade92f2af52021-03-22 16:12:50 +0000191HalResult<float> HalWrapper::getFrequencyResolutionInternal() {
192 ALOGV("Skipped getFrequencyResolution because it's not available in Vibrator HAL");
193 return HalResult<float>::unsupported();
194}
195
Lais Andrade965284b2021-03-19 20:58:15 +0000196HalResult<float> HalWrapper::getQFactorInternal() {
197 ALOGV("Skipped getQFactor because it's not available in Vibrator HAL");
198 return HalResult<float>::unsupported();
199}
200
Lais Andrade92f2af52021-03-22 16:12:50 +0000201HalResult<std::vector<float>> HalWrapper::getMaxAmplitudesInternal() {
202 ALOGV("Skipped getMaxAmplitudes because it's not available in Vibrator HAL");
203 return HalResult<std::vector<float>>::unsupported();
204}
205
Lais Andrade965284b2021-03-19 20:58:15 +0000206// -------------------------------------------------------------------------------------------------
207
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100208HalResult<void> AidlHalWrapper::ping() {
Lais Andrade818a2252024-06-24 14:48:14 +0100209 return HalResultFactory::fromStatus(AIBinder_ping(getHal()->asBinder().get()));
Lais Andradecfd81152020-07-01 09:00:26 +0000210}
211
212void AidlHalWrapper::tryReconnect() {
Lais Andrade98c97032020-11-17 19:23:01 +0000213 auto result = mReconnectFn();
214 if (!result.isOk()) {
215 return;
216 }
Lais Andrade818a2252024-06-24 14:48:14 +0100217 std::shared_ptr<Aidl::IVibrator> newHandle = result.value();
Lais Andradecfd81152020-07-01 09:00:26 +0000218 if (newHandle) {
219 std::lock_guard<std::mutex> lock(mHandleMutex);
220 mHandle = std::move(newHandle);
221 }
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100222}
223
224HalResult<void> AidlHalWrapper::on(milliseconds timeout,
225 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000226 HalResult<Capabilities> capabilities = getCapabilities();
227 bool supportsCallback = capabilities.isOk() &&
228 static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
Lais Andrade818a2252024-06-24 14:48:14 +0100229 auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
230 : nullptr;
Lais Andrade10d9dc72020-05-20 12:00:49 +0000231
Lais Andrade641248e2024-02-16 17:49:36 +0000232 auto ret = HalResultFactory::fromStatus(getHal()->on(timeout.count(), cb));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000233 if (!supportsCallback && ret.isOk()) {
234 mCallbackScheduler->schedule(completionCallback, timeout);
235 }
236
237 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100238}
239
240HalResult<void> AidlHalWrapper::off() {
Lais Andrade641248e2024-02-16 17:49:36 +0000241 return HalResultFactory::fromStatus(getHal()->off());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100242}
243
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000244HalResult<void> AidlHalWrapper::setAmplitude(float amplitude) {
Lais Andrade641248e2024-02-16 17:49:36 +0000245 return HalResultFactory::fromStatus(getHal()->setAmplitude(amplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100246}
247
248HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
Lais Andrade641248e2024-02-16 17:49:36 +0000249 return HalResultFactory::fromStatus(getHal()->setExternalControl(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100250}
251
252HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
Lais Andrade641248e2024-02-16 17:49:36 +0000253 return HalResultFactory::fromStatus(getHal()->alwaysOnEnable(id, effect, strength));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100254}
255
256HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
Lais Andrade641248e2024-02-16 17:49:36 +0000257 return HalResultFactory::fromStatus(getHal()->alwaysOnDisable(id));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100258}
259
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100260HalResult<milliseconds> AidlHalWrapper::performEffect(
261 Effect effect, EffectStrength strength, 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::PERFORM_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 Andrade9e9fcc92020-04-07 20:13:08 +0100268 int32_t lengthMs;
Lais Andrade818a2252024-06-24 14:48:14 +0100269 auto status = getHal()->perform(effect, strength, cb, &lengthMs);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000270 milliseconds length = milliseconds(lengthMs);
271
Lais Andrade818a2252024-06-24 14:48:14 +0100272 auto ret = HalResultFactory::fromStatus<milliseconds>(std::move(status), length);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000273 if (!supportsCallback && ret.isOk()) {
274 mCallbackScheduler->schedule(completionCallback, length);
275 }
276
277 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100278}
279
Lais Andradef172ea12024-07-12 13:45:01 +0100280HalResult<void> AidlHalWrapper::performVendorEffect(
281 const VendorEffect& effect, const std::function<void()>& completionCallback) {
282 // This method should always support callbacks, so no need to double check.
283 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
284 return HalResultFactory::fromStatus(getHal()->performVendorEffect(effect, cb));
285}
286
Lais Andrade49b60b12021-02-23 13:27:41 +0000287HalResult<milliseconds> AidlHalWrapper::performComposedEffect(
Lais Andrade92f2af52021-03-22 16:12:50 +0000288 const std::vector<CompositeEffect>& primitives,
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100289 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000290 // This method should always support callbacks, so no need to double check.
Lais Andrade818a2252024-06-24 14:48:14 +0100291 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
Lais Andrade965284b2021-03-19 20:58:15 +0000292
293 auto durations = getPrimitiveDurations().valueOr({});
Lais Andrade49b60b12021-02-23 13:27:41 +0000294 milliseconds duration(0);
Lais Andrade92f2af52021-03-22 16:12:50 +0000295 for (const auto& effect : primitives) {
Lais Andrade965284b2021-03-19 20:58:15 +0000296 auto primitiveIdx = static_cast<size_t>(effect.primitive);
297 if (primitiveIdx < durations.size()) {
298 duration += durations[primitiveIdx];
299 } else {
300 // Make sure the returned duration is positive to indicate successful vibration.
301 duration += milliseconds(1);
Lais Andrade49b60b12021-02-23 13:27:41 +0000302 }
303 duration += milliseconds(effect.delayMs);
304 }
Lais Andrade49b60b12021-02-23 13:27:41 +0000305
Lais Andrade641248e2024-02-16 17:49:36 +0000306 return HalResultFactory::fromStatus<milliseconds>(getHal()->compose(primitives, cb), duration);
Lais Andrade92f2af52021-03-22 16:12:50 +0000307}
308
309HalResult<void> AidlHalWrapper::performPwleEffect(const std::vector<PrimitivePwle>& primitives,
310 const std::function<void()>& completionCallback) {
311 // This method should always support callbacks, so no need to double check.
Lais Andrade818a2252024-06-24 14:48:14 +0100312 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
Lais Andrade641248e2024-02-16 17:49:36 +0000313 return HalResultFactory::fromStatus(getHal()->composePwle(primitives, cb));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100314}
315
Lais Andrade10d9dc72020-05-20 12:00:49 +0000316HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
Lais Andrade818a2252024-06-24 14:48:14 +0100317 int32_t cap = 0;
318 auto status = getHal()->getCapabilities(&cap);
319 auto capabilities = static_cast<Capabilities>(cap);
320 return HalResultFactory::fromStatus<Capabilities>(std::move(status), capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000321}
322
323HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
324 std::vector<Effect> supportedEffects;
Lais Andrade818a2252024-06-24 14:48:14 +0100325 auto status = getHal()->getSupportedEffects(&supportedEffects);
326 return HalResultFactory::fromStatus<std::vector<Effect>>(std::move(status), supportedEffects);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000327}
328
Lais Andrade92f2af52021-03-22 16:12:50 +0000329HalResult<std::vector<Braking>> AidlHalWrapper::getSupportedBrakingInternal() {
330 std::vector<Braking> supportedBraking;
Lais Andrade818a2252024-06-24 14:48:14 +0100331 auto status = getHal()->getSupportedBraking(&supportedBraking);
332 return HalResultFactory::fromStatus<std::vector<Braking>>(std::move(status), supportedBraking);
Lais Andrade92f2af52021-03-22 16:12:50 +0000333}
334
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000335HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() {
336 std::vector<CompositePrimitive> supportedPrimitives;
Lais Andrade818a2252024-06-24 14:48:14 +0100337 auto status = getHal()->getSupportedPrimitives(&supportedPrimitives);
338 return HalResultFactory::fromStatus<std::vector<CompositePrimitive>>(std::move(status),
Lais Andrade641248e2024-02-16 17:49:36 +0000339 supportedPrimitives);
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000340}
341
Lais Andrade965284b2021-03-19 20:58:15 +0000342HalResult<std::vector<milliseconds>> AidlHalWrapper::getPrimitiveDurationsInternal(
343 const std::vector<CompositePrimitive>& supportedPrimitives) {
344 std::vector<milliseconds> durations;
Lais Andrade818a2252024-06-24 14:48:14 +0100345 constexpr auto primitiveRange = ndk::enum_range<CompositePrimitive>();
Lais Andrade965284b2021-03-19 20:58:15 +0000346 constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
347 durations.resize(primitiveCount);
348
349 for (auto primitive : supportedPrimitives) {
350 auto primitiveIdx = static_cast<size_t>(primitive);
351 if (primitiveIdx >= durations.size()) {
352 // Safety check, should not happen if enum_range is correct.
Lais Andrade4928bfd2021-08-25 18:21:12 +0100353 ALOGE("Supported primitive %zu is outside range [0,%zu), skipping load duration",
354 primitiveIdx, durations.size());
Lais Andrade965284b2021-03-19 20:58:15 +0000355 continue;
356 }
357 int32_t duration = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100358 auto status = getHal()->getPrimitiveDuration(primitive, &duration);
359 auto halResult = HalResultFactory::fromStatus<int32_t>(std::move(status), duration);
Lais Andrade4928bfd2021-08-25 18:21:12 +0100360 if (halResult.isUnsupported()) {
361 // Should not happen, supported primitives should always support requesting duration.
362 ALOGE("Supported primitive %zu returned unsupported for getPrimitiveDuration",
363 primitiveIdx);
364 }
365 if (halResult.isFailed()) {
366 // Fail entire request if one request has failed.
Lais Andradef172ea12024-07-12 13:45:01 +0100367 return HalResult<std::vector<milliseconds>>::failed(halResult.errorMessage());
Lais Andrade965284b2021-03-19 20:58:15 +0000368 }
369 durations[primitiveIdx] = milliseconds(duration);
370 }
371
372 return HalResult<std::vector<milliseconds>>::ok(durations);
373}
374
Lais Andrade4aa80c92021-06-03 17:20:16 +0100375HalResult<milliseconds> AidlHalWrapper::getPrimitiveDelayMaxInternal() {
376 int32_t delay = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100377 auto status = getHal()->getCompositionDelayMax(&delay);
378 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(delay));
Lais Andrade4aa80c92021-06-03 17:20:16 +0100379}
380
381HalResult<milliseconds> AidlHalWrapper::getPrimitiveDurationMaxInternal() {
382 int32_t delay = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100383 auto status = getHal()->getPwlePrimitiveDurationMax(&delay);
384 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(delay));
Lais Andrade4aa80c92021-06-03 17:20:16 +0100385}
386
387HalResult<int32_t> AidlHalWrapper::getCompositionSizeMaxInternal() {
388 int32_t size = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100389 auto status = getHal()->getCompositionSizeMax(&size);
390 return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
Lais Andrade4aa80c92021-06-03 17:20:16 +0100391}
392
393HalResult<int32_t> AidlHalWrapper::getPwleSizeMaxInternal() {
394 int32_t size = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100395 auto status = getHal()->getPwleCompositionSizeMax(&size);
396 return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
Lais Andrade4aa80c92021-06-03 17:20:16 +0100397}
398
Lais Andrade92f2af52021-03-22 16:12:50 +0000399HalResult<float> AidlHalWrapper::getMinFrequencyInternal() {
400 float minFrequency = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100401 auto status = getHal()->getFrequencyMinimum(&minFrequency);
402 return HalResultFactory::fromStatus<float>(std::move(status), minFrequency);
Lais Andrade92f2af52021-03-22 16:12:50 +0000403}
404
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000405HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() {
406 float f0 = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100407 auto status = getHal()->getResonantFrequency(&f0);
408 return HalResultFactory::fromStatus<float>(std::move(status), f0);
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000409}
410
Lais Andrade92f2af52021-03-22 16:12:50 +0000411HalResult<float> AidlHalWrapper::getFrequencyResolutionInternal() {
412 float frequencyResolution = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100413 auto status = getHal()->getFrequencyResolution(&frequencyResolution);
414 return HalResultFactory::fromStatus<float>(std::move(status), frequencyResolution);
Lais Andrade92f2af52021-03-22 16:12:50 +0000415}
416
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000417HalResult<float> AidlHalWrapper::getQFactorInternal() {
418 float qFactor = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100419 auto status = getHal()->getQFactor(&qFactor);
420 return HalResultFactory::fromStatus<float>(std::move(status), qFactor);
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000421}
422
Lais Andrade92f2af52021-03-22 16:12:50 +0000423HalResult<std::vector<float>> AidlHalWrapper::getMaxAmplitudesInternal() {
424 std::vector<float> amplitudes;
Lais Andrade818a2252024-06-24 14:48:14 +0100425 auto status = getHal()->getBandwidthAmplitudeMap(&amplitudes);
426 return HalResultFactory::fromStatus<std::vector<float>>(std::move(status), amplitudes);
Lais Andrade92f2af52021-03-22 16:12:50 +0000427}
428
Lais Andrade818a2252024-06-24 14:48:14 +0100429std::shared_ptr<Aidl::IVibrator> AidlHalWrapper::getHal() {
Lais Andradecfd81152020-07-01 09:00:26 +0000430 std::lock_guard<std::mutex> lock(mHandleMutex);
431 return mHandle;
432}
433
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100434// -------------------------------------------------------------------------------------------------
435
Lais Andradecfd81152020-07-01 09:00:26 +0000436template <typename I>
437HalResult<void> HidlHalWrapper<I>::ping() {
Lais Andrade818a2252024-06-24 14:48:14 +0100438 return HalResultFactory::fromReturn(getHal()->ping());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100439}
440
Lais Andradecfd81152020-07-01 09:00:26 +0000441template <typename I>
442void HidlHalWrapper<I>::tryReconnect() {
443 sp<I> newHandle = I::tryGetService();
444 if (newHandle) {
445 std::lock_guard<std::mutex> lock(mHandleMutex);
446 mHandle = std::move(newHandle);
447 }
448}
449
450template <typename I>
451HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
452 const std::function<void()>& completionCallback) {
Lais Andrade818a2252024-06-24 14:48:14 +0100453 auto status = getHal()->on(timeout.count());
454 auto ret = HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000455 if (ret.isOk()) {
456 mCallbackScheduler->schedule(completionCallback, timeout);
457 }
458 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100459}
460
Lais Andradecfd81152020-07-01 09:00:26 +0000461template <typename I>
462HalResult<void> HidlHalWrapper<I>::off() {
Lais Andrade818a2252024-06-24 14:48:14 +0100463 auto status = getHal()->off();
464 return HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100465}
466
Lais Andradecfd81152020-07-01 09:00:26 +0000467template <typename I>
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000468HalResult<void> HidlHalWrapper<I>::setAmplitude(float amplitude) {
469 uint8_t amp = static_cast<uint8_t>(amplitude * std::numeric_limits<uint8_t>::max());
Lais Andrade818a2252024-06-24 14:48:14 +0100470 auto status = getHal()->setAmplitude(amp);
471 return HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100472}
473
Lais Andradecfd81152020-07-01 09:00:26 +0000474template <typename I>
475HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100476 ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
477 return HalResult<void>::unsupported();
478}
479
Lais Andradecfd81152020-07-01 09:00:26 +0000480template <typename I>
481HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100482 ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
483 return HalResult<void>::unsupported();
484}
485
Lais Andradecfd81152020-07-01 09:00:26 +0000486template <typename I>
487HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100488 ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
489 return HalResult<void>::unsupported();
490}
491
Lais Andradecfd81152020-07-01 09:00:26 +0000492template <typename I>
Lais Andradecfd81152020-07-01 09:00:26 +0000493HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
494 hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
Lais Andraded39ff7d2020-05-19 10:42:51 +0000495 Capabilities capabilities =
496 result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
Lais Andrade818a2252024-06-24 14:48:14 +0100497 return HalResultFactory::fromReturn<Capabilities>(std::move(result), capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000498}
499
Lais Andradecfd81152020-07-01 09:00:26 +0000500template <typename I>
501template <typename T>
502HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
503 perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
Lais Andrade10d9dc72020-05-20 12:00:49 +0000504 const std::function<void()>& completionCallback) {
505 V1_0::Status status;
506 int32_t lengthMs;
507 auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
508 status = retStatus;
509 lengthMs = retLengthMs;
510 };
511
512 V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
513 auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
514 milliseconds length = milliseconds(lengthMs);
515
Lais Andrade818a2252024-06-24 14:48:14 +0100516 auto ret = HalResultFactory::fromReturn<milliseconds>(std::move(result), status, length);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000517 if (ret.isOk()) {
518 mCallbackScheduler->schedule(completionCallback, length);
519 }
520
521 return ret;
522}
523
Lais Andradecfd81152020-07-01 09:00:26 +0000524template <typename I>
525sp<I> HidlHalWrapper<I>::getHal() {
526 std::lock_guard<std::mutex> lock(mHandleMutex);
527 return mHandle;
528}
529
530// -------------------------------------------------------------------------------------------------
531
532HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
Lais Andrade10d9dc72020-05-20 12:00:49 +0000533 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andradecfd81152020-07-01 09:00:26 +0000534 if (isStaticCastValid<V1_0::Effect>(effect)) {
535 return performInternal(&V1_0::IVibrator::perform, getHal(),
536 static_cast<V1_0::Effect>(effect), strength, completionCallback);
537 }
538
539 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
540 Aidl::toString(effect).c_str());
541 return HalResult<milliseconds>::unsupported();
Lais Andrade10d9dc72020-05-20 12:00:49 +0000542}
543
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100544// -------------------------------------------------------------------------------------------------
545
Lais Andrade10d9dc72020-05-20 12:00:49 +0000546HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
547 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100548 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000549 return performInternal(&V1_1::IVibrator::perform, getHal(),
550 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100551 }
552 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000553 return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
554 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100555 }
556
557 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
558 Aidl::toString(effect).c_str());
559 return HalResult<milliseconds>::unsupported();
560}
561
562// -------------------------------------------------------------------------------------------------
563
Lais Andrade10d9dc72020-05-20 12:00:49 +0000564HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
565 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100566 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000567 return performInternal(&V1_2::IVibrator::perform, getHal(),
568 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100569 }
570 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000571 return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
572 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100573 }
574 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000575 return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
576 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100577 }
578
579 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
580 Aidl::toString(effect).c_str());
581 return HalResult<milliseconds>::unsupported();
582}
583
584// -------------------------------------------------------------------------------------------------
585
586HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000587 auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
Lais Andrade641248e2024-02-16 17:49:36 +0000588 return HalResultFactory::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100589}
590
Lais Andrade10d9dc72020-05-20 12:00:49 +0000591HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
592 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100593 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000594 return performInternal(&V1_3::IVibrator::perform, getHal(),
595 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100596 }
597 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000598 return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
599 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100600 }
601 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000602 return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
603 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100604 }
605 if (isStaticCastValid<V1_3::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000606 return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
607 static_cast<V1_3::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100608 }
609
610 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
611 Aidl::toString(effect).c_str());
612 return HalResult<milliseconds>::unsupported();
613}
614
Lais Andraded39ff7d2020-05-19 10:42:51 +0000615HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
Lais Andrade08666612020-08-07 16:16:31 +0000616 Capabilities capabilities = Capabilities::NONE;
617
Lais Andradecfd81152020-07-01 09:00:26 +0000618 sp<V1_3::IVibrator> hal = getHal();
619 auto amplitudeResult = hal->supportsAmplitudeControl();
620 if (!amplitudeResult.isOk()) {
Lais Andrade818a2252024-06-24 14:48:14 +0100621 return HalResultFactory::fromReturn<Capabilities>(std::move(amplitudeResult), capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000622 }
623
Lais Andradecfd81152020-07-01 09:00:26 +0000624 auto externalControlResult = hal->supportsExternalControl();
Lais Andradecfd81152020-07-01 09:00:26 +0000625 if (amplitudeResult.withDefault(false)) {
626 capabilities |= Capabilities::AMPLITUDE_CONTROL;
627 }
628 if (externalControlResult.withDefault(false)) {
629 capabilities |= Capabilities::EXTERNAL_CONTROL;
Lais Andrade602ff962020-08-27 12:02:53 +0000630
631 if (amplitudeResult.withDefault(false)) {
632 capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL;
633 }
Lais Andradecfd81152020-07-01 09:00:26 +0000634 }
635
Lais Andrade818a2252024-06-24 14:48:14 +0100636 return HalResultFactory::fromReturn<Capabilities>(std::move(externalControlResult),
637 capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000638}
639
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100640// -------------------------------------------------------------------------------------------------
641
642}; // namespace vibrator
643
644}; // namespace android