blob: abe78f0ef05b119901c19e2c80bf61ae0c9c6ffa [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 Andrade9e9fcc92020-04-07 20:13:08 +010035
36using std::chrono::milliseconds;
37
38namespace V1_0 = android::hardware::vibrator::V1_0;
39namespace V1_1 = android::hardware::vibrator::V1_1;
40namespace V1_2 = android::hardware::vibrator::V1_2;
41namespace V1_3 = android::hardware::vibrator::V1_3;
Lais Andrade818a2252024-06-24 14:48:14 +010042namespace Aidl = aidl::android::hardware::vibrator;
Lais Andrade9e9fcc92020-04-07 20:13:08 +010043
44namespace android {
45
46namespace vibrator {
47
48// -------------------------------------------------------------------------------------------------
49
50template <class T>
51bool isStaticCastValid(Effect effect) {
52 T castEffect = static_cast<T>(effect);
53 auto iter = hardware::hidl_enum_range<T>();
54 return castEffect >= *iter.begin() && castEffect <= *std::prev(iter.end());
55}
56
Lais Andrade9e9fcc92020-04-07 20:13:08 +010057// -------------------------------------------------------------------------------------------------
58
Lais Andrade965284b2021-03-19 20:58:15 +000059Info HalWrapper::getInfo() {
60 getCapabilities();
61 getPrimitiveDurations();
62 std::lock_guard<std::mutex> lock(mInfoMutex);
63 if (mInfoCache.mSupportedEffects.isFailed()) {
64 mInfoCache.mSupportedEffects = getSupportedEffectsInternal();
65 }
Lais Andrade92f2af52021-03-22 16:12:50 +000066 if (mInfoCache.mSupportedBraking.isFailed()) {
67 mInfoCache.mSupportedBraking = getSupportedBrakingInternal();
68 }
Lais Andrade4aa80c92021-06-03 17:20:16 +010069 if (mInfoCache.mPrimitiveDelayMax.isFailed()) {
70 mInfoCache.mPrimitiveDelayMax = getPrimitiveDelayMaxInternal();
71 }
72 if (mInfoCache.mPwlePrimitiveDurationMax.isFailed()) {
73 mInfoCache.mPwlePrimitiveDurationMax = getPrimitiveDurationMaxInternal();
74 }
75 if (mInfoCache.mCompositionSizeMax.isFailed()) {
76 mInfoCache.mCompositionSizeMax = getCompositionSizeMaxInternal();
77 }
78 if (mInfoCache.mPwleSizeMax.isFailed()) {
79 mInfoCache.mPwleSizeMax = getPwleSizeMaxInternal();
80 }
Lais Andrade92f2af52021-03-22 16:12:50 +000081 if (mInfoCache.mMinFrequency.isFailed()) {
82 mInfoCache.mMinFrequency = getMinFrequencyInternal();
83 }
Lais Andrade965284b2021-03-19 20:58:15 +000084 if (mInfoCache.mResonantFrequency.isFailed()) {
85 mInfoCache.mResonantFrequency = getResonantFrequencyInternal();
86 }
Lais Andrade92f2af52021-03-22 16:12:50 +000087 if (mInfoCache.mFrequencyResolution.isFailed()) {
88 mInfoCache.mFrequencyResolution = getFrequencyResolutionInternal();
89 }
Lais Andrade965284b2021-03-19 20:58:15 +000090 if (mInfoCache.mQFactor.isFailed()) {
91 mInfoCache.mQFactor = getQFactorInternal();
92 }
Lais Andrade92f2af52021-03-22 16:12:50 +000093 if (mInfoCache.mMaxAmplitudes.isFailed()) {
94 mInfoCache.mMaxAmplitudes = getMaxAmplitudesInternal();
95 }
Lais Andrade965284b2021-03-19 20:58:15 +000096 return mInfoCache.get();
97}
98
Lais Andrade92f2af52021-03-22 16:12:50 +000099HalResult<milliseconds> HalWrapper::performComposedEffect(const std::vector<CompositeEffect>&,
100 const std::function<void()>&) {
101 ALOGV("Skipped performComposedEffect because it's not available in Vibrator HAL");
102 return HalResult<milliseconds>::unsupported();
103}
104
105HalResult<void> HalWrapper::performPwleEffect(const std::vector<PrimitivePwle>&,
106 const std::function<void()>&) {
107 ALOGV("Skipped performPwleEffect because it's not available in Vibrator HAL");
108 return HalResult<void>::unsupported();
109}
110
Lais Andrade965284b2021-03-19 20:58:15 +0000111HalResult<Capabilities> HalWrapper::getCapabilities() {
112 std::lock_guard<std::mutex> lock(mInfoMutex);
113 if (mInfoCache.mCapabilities.isFailed()) {
114 mInfoCache.mCapabilities = getCapabilitiesInternal();
115 }
116 return mInfoCache.mCapabilities;
117}
118
119HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurations() {
120 std::lock_guard<std::mutex> lock(mInfoMutex);
121 if (mInfoCache.mSupportedPrimitives.isFailed()) {
122 mInfoCache.mSupportedPrimitives = getSupportedPrimitivesInternal();
123 if (mInfoCache.mSupportedPrimitives.isUnsupported()) {
124 mInfoCache.mPrimitiveDurations = HalResult<std::vector<milliseconds>>::unsupported();
125 }
126 }
127 if (mInfoCache.mPrimitiveDurations.isFailed() && mInfoCache.mSupportedPrimitives.isOk()) {
128 mInfoCache.mPrimitiveDurations =
129 getPrimitiveDurationsInternal(mInfoCache.mSupportedPrimitives.value());
130 }
131 return mInfoCache.mPrimitiveDurations;
132}
133
134HalResult<std::vector<Effect>> HalWrapper::getSupportedEffectsInternal() {
135 ALOGV("Skipped getSupportedEffects because it's not available in Vibrator HAL");
136 return HalResult<std::vector<Effect>>::unsupported();
137}
138
Lais Andrade92f2af52021-03-22 16:12:50 +0000139HalResult<std::vector<Braking>> HalWrapper::getSupportedBrakingInternal() {
140 ALOGV("Skipped getSupportedBraking because it's not available in Vibrator HAL");
141 return HalResult<std::vector<Braking>>::unsupported();
142}
143
Lais Andrade965284b2021-03-19 20:58:15 +0000144HalResult<std::vector<CompositePrimitive>> HalWrapper::getSupportedPrimitivesInternal() {
145 ALOGV("Skipped getSupportedPrimitives because it's not available in Vibrator HAL");
146 return HalResult<std::vector<CompositePrimitive>>::unsupported();
147}
148
149HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurationsInternal(
150 const std::vector<CompositePrimitive>&) {
151 ALOGV("Skipped getPrimitiveDurations because it's not available in Vibrator HAL");
152 return HalResult<std::vector<milliseconds>>::unsupported();
153}
154
Lais Andrade4aa80c92021-06-03 17:20:16 +0100155HalResult<milliseconds> HalWrapper::getPrimitiveDelayMaxInternal() {
156 ALOGV("Skipped getPrimitiveDelayMaxInternal because it's not available in Vibrator HAL");
157 return HalResult<milliseconds>::unsupported();
158}
159
160HalResult<milliseconds> HalWrapper::getPrimitiveDurationMaxInternal() {
161 ALOGV("Skipped getPrimitiveDurationMaxInternal because it's not available in Vibrator HAL");
162 return HalResult<milliseconds>::unsupported();
163}
164
165HalResult<int32_t> HalWrapper::getCompositionSizeMaxInternal() {
166 ALOGV("Skipped getCompositionSizeMaxInternal because it's not available in Vibrator HAL");
167 return HalResult<int32_t>::unsupported();
168}
169
170HalResult<int32_t> HalWrapper::getPwleSizeMaxInternal() {
171 ALOGV("Skipped getPwleSizeMaxInternal because it's not available in Vibrator HAL");
172 return HalResult<int32_t>::unsupported();
173}
174
Lais Andrade92f2af52021-03-22 16:12:50 +0000175HalResult<float> HalWrapper::getMinFrequencyInternal() {
176 ALOGV("Skipped getMinFrequency because it's not available in Vibrator HAL");
177 return HalResult<float>::unsupported();
178}
179
Lais Andrade965284b2021-03-19 20:58:15 +0000180HalResult<float> HalWrapper::getResonantFrequencyInternal() {
181 ALOGV("Skipped getResonantFrequency because it's not available in Vibrator HAL");
182 return HalResult<float>::unsupported();
183}
184
Lais Andrade92f2af52021-03-22 16:12:50 +0000185HalResult<float> HalWrapper::getFrequencyResolutionInternal() {
186 ALOGV("Skipped getFrequencyResolution because it's not available in Vibrator HAL");
187 return HalResult<float>::unsupported();
188}
189
Lais Andrade965284b2021-03-19 20:58:15 +0000190HalResult<float> HalWrapper::getQFactorInternal() {
191 ALOGV("Skipped getQFactor because it's not available in Vibrator HAL");
192 return HalResult<float>::unsupported();
193}
194
Lais Andrade92f2af52021-03-22 16:12:50 +0000195HalResult<std::vector<float>> HalWrapper::getMaxAmplitudesInternal() {
196 ALOGV("Skipped getMaxAmplitudes because it's not available in Vibrator HAL");
197 return HalResult<std::vector<float>>::unsupported();
198}
199
Lais Andrade965284b2021-03-19 20:58:15 +0000200// -------------------------------------------------------------------------------------------------
201
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100202HalResult<void> AidlHalWrapper::ping() {
Lais Andrade818a2252024-06-24 14:48:14 +0100203 return HalResultFactory::fromStatus(AIBinder_ping(getHal()->asBinder().get()));
Lais Andradecfd81152020-07-01 09:00:26 +0000204}
205
206void AidlHalWrapper::tryReconnect() {
Lais Andrade98c97032020-11-17 19:23:01 +0000207 auto result = mReconnectFn();
208 if (!result.isOk()) {
209 return;
210 }
Lais Andrade818a2252024-06-24 14:48:14 +0100211 std::shared_ptr<Aidl::IVibrator> newHandle = result.value();
Lais Andradecfd81152020-07-01 09:00:26 +0000212 if (newHandle) {
213 std::lock_guard<std::mutex> lock(mHandleMutex);
214 mHandle = std::move(newHandle);
215 }
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100216}
217
218HalResult<void> AidlHalWrapper::on(milliseconds timeout,
219 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000220 HalResult<Capabilities> capabilities = getCapabilities();
221 bool supportsCallback = capabilities.isOk() &&
222 static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
Lais Andrade818a2252024-06-24 14:48:14 +0100223 auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
224 : nullptr;
Lais Andrade10d9dc72020-05-20 12:00:49 +0000225
Lais Andrade641248e2024-02-16 17:49:36 +0000226 auto ret = HalResultFactory::fromStatus(getHal()->on(timeout.count(), cb));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000227 if (!supportsCallback && ret.isOk()) {
228 mCallbackScheduler->schedule(completionCallback, timeout);
229 }
230
231 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100232}
233
234HalResult<void> AidlHalWrapper::off() {
Lais Andrade641248e2024-02-16 17:49:36 +0000235 return HalResultFactory::fromStatus(getHal()->off());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100236}
237
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000238HalResult<void> AidlHalWrapper::setAmplitude(float amplitude) {
Lais Andrade641248e2024-02-16 17:49:36 +0000239 return HalResultFactory::fromStatus(getHal()->setAmplitude(amplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100240}
241
242HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
Lais Andrade641248e2024-02-16 17:49:36 +0000243 return HalResultFactory::fromStatus(getHal()->setExternalControl(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100244}
245
246HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
Lais Andrade641248e2024-02-16 17:49:36 +0000247 return HalResultFactory::fromStatus(getHal()->alwaysOnEnable(id, effect, strength));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100248}
249
250HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
Lais Andrade641248e2024-02-16 17:49:36 +0000251 return HalResultFactory::fromStatus(getHal()->alwaysOnDisable(id));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100252}
253
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100254HalResult<milliseconds> AidlHalWrapper::performEffect(
255 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000256 HalResult<Capabilities> capabilities = getCapabilities();
257 bool supportsCallback = capabilities.isOk() &&
258 static_cast<int32_t>(capabilities.value() & Capabilities::PERFORM_CALLBACK);
Lais Andrade818a2252024-06-24 14:48:14 +0100259 auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
260 : nullptr;
Lais Andrade10d9dc72020-05-20 12:00:49 +0000261
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100262 int32_t lengthMs;
Lais Andrade818a2252024-06-24 14:48:14 +0100263 auto status = getHal()->perform(effect, strength, cb, &lengthMs);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000264 milliseconds length = milliseconds(lengthMs);
265
Lais Andrade818a2252024-06-24 14:48:14 +0100266 auto ret = HalResultFactory::fromStatus<milliseconds>(std::move(status), length);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000267 if (!supportsCallback && ret.isOk()) {
268 mCallbackScheduler->schedule(completionCallback, length);
269 }
270
271 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100272}
273
Lais Andrade49b60b12021-02-23 13:27:41 +0000274HalResult<milliseconds> AidlHalWrapper::performComposedEffect(
Lais Andrade92f2af52021-03-22 16:12:50 +0000275 const std::vector<CompositeEffect>& primitives,
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100276 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000277 // This method should always support callbacks, so no need to double check.
Lais Andrade818a2252024-06-24 14:48:14 +0100278 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
Lais Andrade965284b2021-03-19 20:58:15 +0000279
280 auto durations = getPrimitiveDurations().valueOr({});
Lais Andrade49b60b12021-02-23 13:27:41 +0000281 milliseconds duration(0);
Lais Andrade92f2af52021-03-22 16:12:50 +0000282 for (const auto& effect : primitives) {
Lais Andrade965284b2021-03-19 20:58:15 +0000283 auto primitiveIdx = static_cast<size_t>(effect.primitive);
284 if (primitiveIdx < durations.size()) {
285 duration += durations[primitiveIdx];
286 } else {
287 // Make sure the returned duration is positive to indicate successful vibration.
288 duration += milliseconds(1);
Lais Andrade49b60b12021-02-23 13:27:41 +0000289 }
290 duration += milliseconds(effect.delayMs);
291 }
Lais Andrade49b60b12021-02-23 13:27:41 +0000292
Lais Andrade641248e2024-02-16 17:49:36 +0000293 return HalResultFactory::fromStatus<milliseconds>(getHal()->compose(primitives, cb), duration);
Lais Andrade92f2af52021-03-22 16:12:50 +0000294}
295
296HalResult<void> AidlHalWrapper::performPwleEffect(const std::vector<PrimitivePwle>& primitives,
297 const std::function<void()>& completionCallback) {
298 // 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 Andrade641248e2024-02-16 17:49:36 +0000300 return HalResultFactory::fromStatus(getHal()->composePwle(primitives, cb));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100301}
302
Lais Andrade10d9dc72020-05-20 12:00:49 +0000303HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
Lais Andrade818a2252024-06-24 14:48:14 +0100304 int32_t cap = 0;
305 auto status = getHal()->getCapabilities(&cap);
306 auto capabilities = static_cast<Capabilities>(cap);
307 return HalResultFactory::fromStatus<Capabilities>(std::move(status), capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000308}
309
310HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
311 std::vector<Effect> supportedEffects;
Lais Andrade818a2252024-06-24 14:48:14 +0100312 auto status = getHal()->getSupportedEffects(&supportedEffects);
313 return HalResultFactory::fromStatus<std::vector<Effect>>(std::move(status), supportedEffects);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000314}
315
Lais Andrade92f2af52021-03-22 16:12:50 +0000316HalResult<std::vector<Braking>> AidlHalWrapper::getSupportedBrakingInternal() {
317 std::vector<Braking> supportedBraking;
Lais Andrade818a2252024-06-24 14:48:14 +0100318 auto status = getHal()->getSupportedBraking(&supportedBraking);
319 return HalResultFactory::fromStatus<std::vector<Braking>>(std::move(status), supportedBraking);
Lais Andrade92f2af52021-03-22 16:12:50 +0000320}
321
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000322HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() {
323 std::vector<CompositePrimitive> supportedPrimitives;
Lais Andrade818a2252024-06-24 14:48:14 +0100324 auto status = getHal()->getSupportedPrimitives(&supportedPrimitives);
325 return HalResultFactory::fromStatus<std::vector<CompositePrimitive>>(std::move(status),
Lais Andrade641248e2024-02-16 17:49:36 +0000326 supportedPrimitives);
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000327}
328
Lais Andrade965284b2021-03-19 20:58:15 +0000329HalResult<std::vector<milliseconds>> AidlHalWrapper::getPrimitiveDurationsInternal(
330 const std::vector<CompositePrimitive>& supportedPrimitives) {
331 std::vector<milliseconds> durations;
Lais Andrade818a2252024-06-24 14:48:14 +0100332 constexpr auto primitiveRange = ndk::enum_range<CompositePrimitive>();
Lais Andrade965284b2021-03-19 20:58:15 +0000333 constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
334 durations.resize(primitiveCount);
335
336 for (auto primitive : supportedPrimitives) {
337 auto primitiveIdx = static_cast<size_t>(primitive);
338 if (primitiveIdx >= durations.size()) {
339 // Safety check, should not happen if enum_range is correct.
Lais Andrade4928bfd2021-08-25 18:21:12 +0100340 ALOGE("Supported primitive %zu is outside range [0,%zu), skipping load duration",
341 primitiveIdx, durations.size());
Lais Andrade965284b2021-03-19 20:58:15 +0000342 continue;
343 }
344 int32_t duration = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100345 auto status = getHal()->getPrimitiveDuration(primitive, &duration);
346 auto halResult = HalResultFactory::fromStatus<int32_t>(std::move(status), duration);
Lais Andrade4928bfd2021-08-25 18:21:12 +0100347 if (halResult.isUnsupported()) {
348 // Should not happen, supported primitives should always support requesting duration.
349 ALOGE("Supported primitive %zu returned unsupported for getPrimitiveDuration",
350 primitiveIdx);
351 }
352 if (halResult.isFailed()) {
353 // Fail entire request if one request has failed.
Lais Andrade818a2252024-06-24 14:48:14 +0100354 return HalResult<std::vector<milliseconds>>::failed(status.getMessage());
Lais Andrade965284b2021-03-19 20:58:15 +0000355 }
356 durations[primitiveIdx] = milliseconds(duration);
357 }
358
359 return HalResult<std::vector<milliseconds>>::ok(durations);
360}
361
Lais Andrade4aa80c92021-06-03 17:20:16 +0100362HalResult<milliseconds> AidlHalWrapper::getPrimitiveDelayMaxInternal() {
363 int32_t delay = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100364 auto status = getHal()->getCompositionDelayMax(&delay);
365 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(delay));
Lais Andrade4aa80c92021-06-03 17:20:16 +0100366}
367
368HalResult<milliseconds> AidlHalWrapper::getPrimitiveDurationMaxInternal() {
369 int32_t delay = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100370 auto status = getHal()->getPwlePrimitiveDurationMax(&delay);
371 return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(delay));
Lais Andrade4aa80c92021-06-03 17:20:16 +0100372}
373
374HalResult<int32_t> AidlHalWrapper::getCompositionSizeMaxInternal() {
375 int32_t size = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100376 auto status = getHal()->getCompositionSizeMax(&size);
377 return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
Lais Andrade4aa80c92021-06-03 17:20:16 +0100378}
379
380HalResult<int32_t> AidlHalWrapper::getPwleSizeMaxInternal() {
381 int32_t size = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100382 auto status = getHal()->getPwleCompositionSizeMax(&size);
383 return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
Lais Andrade4aa80c92021-06-03 17:20:16 +0100384}
385
Lais Andrade92f2af52021-03-22 16:12:50 +0000386HalResult<float> AidlHalWrapper::getMinFrequencyInternal() {
387 float minFrequency = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100388 auto status = getHal()->getFrequencyMinimum(&minFrequency);
389 return HalResultFactory::fromStatus<float>(std::move(status), minFrequency);
Lais Andrade92f2af52021-03-22 16:12:50 +0000390}
391
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000392HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() {
393 float f0 = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100394 auto status = getHal()->getResonantFrequency(&f0);
395 return HalResultFactory::fromStatus<float>(std::move(status), f0);
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000396}
397
Lais Andrade92f2af52021-03-22 16:12:50 +0000398HalResult<float> AidlHalWrapper::getFrequencyResolutionInternal() {
399 float frequencyResolution = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100400 auto status = getHal()->getFrequencyResolution(&frequencyResolution);
401 return HalResultFactory::fromStatus<float>(std::move(status), frequencyResolution);
Lais Andrade92f2af52021-03-22 16:12:50 +0000402}
403
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000404HalResult<float> AidlHalWrapper::getQFactorInternal() {
405 float qFactor = 0;
Lais Andrade818a2252024-06-24 14:48:14 +0100406 auto status = getHal()->getQFactor(&qFactor);
407 return HalResultFactory::fromStatus<float>(std::move(status), qFactor);
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000408}
409
Lais Andrade92f2af52021-03-22 16:12:50 +0000410HalResult<std::vector<float>> AidlHalWrapper::getMaxAmplitudesInternal() {
411 std::vector<float> amplitudes;
Lais Andrade818a2252024-06-24 14:48:14 +0100412 auto status = getHal()->getBandwidthAmplitudeMap(&amplitudes);
413 return HalResultFactory::fromStatus<std::vector<float>>(std::move(status), amplitudes);
Lais Andrade92f2af52021-03-22 16:12:50 +0000414}
415
Lais Andrade818a2252024-06-24 14:48:14 +0100416std::shared_ptr<Aidl::IVibrator> AidlHalWrapper::getHal() {
Lais Andradecfd81152020-07-01 09:00:26 +0000417 std::lock_guard<std::mutex> lock(mHandleMutex);
418 return mHandle;
419}
420
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100421// -------------------------------------------------------------------------------------------------
422
Lais Andradecfd81152020-07-01 09:00:26 +0000423template <typename I>
424HalResult<void> HidlHalWrapper<I>::ping() {
Lais Andrade818a2252024-06-24 14:48:14 +0100425 return HalResultFactory::fromReturn(getHal()->ping());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100426}
427
Lais Andradecfd81152020-07-01 09:00:26 +0000428template <typename I>
429void HidlHalWrapper<I>::tryReconnect() {
430 sp<I> newHandle = I::tryGetService();
431 if (newHandle) {
432 std::lock_guard<std::mutex> lock(mHandleMutex);
433 mHandle = std::move(newHandle);
434 }
435}
436
437template <typename I>
438HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
439 const std::function<void()>& completionCallback) {
Lais Andrade818a2252024-06-24 14:48:14 +0100440 auto status = getHal()->on(timeout.count());
441 auto ret = HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000442 if (ret.isOk()) {
443 mCallbackScheduler->schedule(completionCallback, timeout);
444 }
445 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100446}
447
Lais Andradecfd81152020-07-01 09:00:26 +0000448template <typename I>
449HalResult<void> HidlHalWrapper<I>::off() {
Lais Andrade818a2252024-06-24 14:48:14 +0100450 auto status = getHal()->off();
451 return HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100452}
453
Lais Andradecfd81152020-07-01 09:00:26 +0000454template <typename I>
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000455HalResult<void> HidlHalWrapper<I>::setAmplitude(float amplitude) {
456 uint8_t amp = static_cast<uint8_t>(amplitude * std::numeric_limits<uint8_t>::max());
Lais Andrade818a2252024-06-24 14:48:14 +0100457 auto status = getHal()->setAmplitude(amp);
458 return HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100459}
460
Lais Andradecfd81152020-07-01 09:00:26 +0000461template <typename I>
462HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100463 ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
464 return HalResult<void>::unsupported();
465}
466
Lais Andradecfd81152020-07-01 09:00:26 +0000467template <typename I>
468HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100469 ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
470 return HalResult<void>::unsupported();
471}
472
Lais Andradecfd81152020-07-01 09:00:26 +0000473template <typename I>
474HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100475 ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
476 return HalResult<void>::unsupported();
477}
478
Lais Andradecfd81152020-07-01 09:00:26 +0000479template <typename I>
Lais Andradecfd81152020-07-01 09:00:26 +0000480HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
481 hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
Lais Andraded39ff7d2020-05-19 10:42:51 +0000482 Capabilities capabilities =
483 result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
Lais Andrade818a2252024-06-24 14:48:14 +0100484 return HalResultFactory::fromReturn<Capabilities>(std::move(result), capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000485}
486
Lais Andradecfd81152020-07-01 09:00:26 +0000487template <typename I>
488template <typename T>
489HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
490 perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
Lais Andrade10d9dc72020-05-20 12:00:49 +0000491 const std::function<void()>& completionCallback) {
492 V1_0::Status status;
493 int32_t lengthMs;
494 auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
495 status = retStatus;
496 lengthMs = retLengthMs;
497 };
498
499 V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
500 auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
501 milliseconds length = milliseconds(lengthMs);
502
Lais Andrade818a2252024-06-24 14:48:14 +0100503 auto ret = HalResultFactory::fromReturn<milliseconds>(std::move(result), status, length);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000504 if (ret.isOk()) {
505 mCallbackScheduler->schedule(completionCallback, length);
506 }
507
508 return ret;
509}
510
Lais Andradecfd81152020-07-01 09:00:26 +0000511template <typename I>
512sp<I> HidlHalWrapper<I>::getHal() {
513 std::lock_guard<std::mutex> lock(mHandleMutex);
514 return mHandle;
515}
516
517// -------------------------------------------------------------------------------------------------
518
519HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
Lais Andrade10d9dc72020-05-20 12:00:49 +0000520 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andradecfd81152020-07-01 09:00:26 +0000521 if (isStaticCastValid<V1_0::Effect>(effect)) {
522 return performInternal(&V1_0::IVibrator::perform, getHal(),
523 static_cast<V1_0::Effect>(effect), strength, completionCallback);
524 }
525
526 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
527 Aidl::toString(effect).c_str());
528 return HalResult<milliseconds>::unsupported();
Lais Andrade10d9dc72020-05-20 12:00:49 +0000529}
530
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100531// -------------------------------------------------------------------------------------------------
532
Lais Andrade10d9dc72020-05-20 12:00:49 +0000533HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
534 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100535 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000536 return performInternal(&V1_1::IVibrator::perform, getHal(),
537 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100538 }
539 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000540 return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
541 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100542 }
543
544 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
545 Aidl::toString(effect).c_str());
546 return HalResult<milliseconds>::unsupported();
547}
548
549// -------------------------------------------------------------------------------------------------
550
Lais Andrade10d9dc72020-05-20 12:00:49 +0000551HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
552 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100553 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000554 return performInternal(&V1_2::IVibrator::perform, getHal(),
555 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100556 }
557 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000558 return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
559 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100560 }
561 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000562 return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
563 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100564 }
565
566 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
567 Aidl::toString(effect).c_str());
568 return HalResult<milliseconds>::unsupported();
569}
570
571// -------------------------------------------------------------------------------------------------
572
573HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000574 auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
Lais Andrade641248e2024-02-16 17:49:36 +0000575 return HalResultFactory::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100576}
577
Lais Andrade10d9dc72020-05-20 12:00:49 +0000578HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
579 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100580 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000581 return performInternal(&V1_3::IVibrator::perform, getHal(),
582 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100583 }
584 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000585 return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
586 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100587 }
588 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000589 return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
590 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100591 }
592 if (isStaticCastValid<V1_3::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000593 return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
594 static_cast<V1_3::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100595 }
596
597 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
598 Aidl::toString(effect).c_str());
599 return HalResult<milliseconds>::unsupported();
600}
601
Lais Andraded39ff7d2020-05-19 10:42:51 +0000602HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
Lais Andrade08666612020-08-07 16:16:31 +0000603 Capabilities capabilities = Capabilities::NONE;
604
Lais Andradecfd81152020-07-01 09:00:26 +0000605 sp<V1_3::IVibrator> hal = getHal();
606 auto amplitudeResult = hal->supportsAmplitudeControl();
607 if (!amplitudeResult.isOk()) {
Lais Andrade818a2252024-06-24 14:48:14 +0100608 return HalResultFactory::fromReturn<Capabilities>(std::move(amplitudeResult), capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000609 }
610
Lais Andradecfd81152020-07-01 09:00:26 +0000611 auto externalControlResult = hal->supportsExternalControl();
Lais Andradecfd81152020-07-01 09:00:26 +0000612 if (amplitudeResult.withDefault(false)) {
613 capabilities |= Capabilities::AMPLITUDE_CONTROL;
614 }
615 if (externalControlResult.withDefault(false)) {
616 capabilities |= Capabilities::EXTERNAL_CONTROL;
Lais Andrade602ff962020-08-27 12:02:53 +0000617
618 if (amplitudeResult.withDefault(false)) {
619 capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL;
620 }
Lais Andradecfd81152020-07-01 09:00:26 +0000621 }
622
Lais Andrade818a2252024-06-24 14:48:14 +0100623 return HalResultFactory::fromReturn<Capabilities>(std::move(externalControlResult),
624 capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000625}
626
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100627// -------------------------------------------------------------------------------------------------
628
629}; // namespace vibrator
630
631}; // namespace android