blob: 3ebf9b6de8bc33e27df96a06d10b62ad0109216a [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
19#include <android/hardware/vibrator/1.3/IVibrator.h>
Lais Andrade9e9fcc92020-04-07 20:13:08 +010020#include <android/hardware/vibrator/IVibrator.h>
21#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
29using android::hardware::vibrator::CompositeEffect;
Lais Andrade07f9c0e2020-08-11 16:22:12 +000030using android::hardware::vibrator::CompositePrimitive;
Lais Andrade9e9fcc92020-04-07 20:13:08 +010031using android::hardware::vibrator::Effect;
32using android::hardware::vibrator::EffectStrength;
33
34using std::chrono::milliseconds;
35
36namespace V1_0 = android::hardware::vibrator::V1_0;
37namespace V1_1 = android::hardware::vibrator::V1_1;
38namespace V1_2 = android::hardware::vibrator::V1_2;
39namespace V1_3 = android::hardware::vibrator::V1_3;
40namespace Aidl = android::hardware::vibrator;
41
42namespace android {
43
44namespace vibrator {
45
46// -------------------------------------------------------------------------------------------------
47
48template <class T>
Lais Andraded39ff7d2020-05-19 10:42:51 +000049HalResult<T> loadCached(const std::function<HalResult<T>()>& loadFn, std::optional<T>& cache) {
50 if (cache.has_value()) {
Lais Andrade10d9dc72020-05-20 12:00:49 +000051 // Return copy of cached value.
52 return HalResult<T>::ok(*cache);
Lais Andraded39ff7d2020-05-19 10:42:51 +000053 }
54 HalResult<T> ret = loadFn();
55 if (ret.isOk()) {
Lais Andrade10d9dc72020-05-20 12:00:49 +000056 // Cache copy of returned value.
Lais Andraded39ff7d2020-05-19 10:42:51 +000057 cache.emplace(ret.value());
58 }
59 return ret;
60}
61
62template <class T>
Lais Andrade9e9fcc92020-04-07 20:13:08 +010063bool isStaticCastValid(Effect effect) {
64 T castEffect = static_cast<T>(effect);
65 auto iter = hardware::hidl_enum_range<T>();
66 return castEffect >= *iter.begin() && castEffect <= *std::prev(iter.end());
67}
68
Lais Andrade9e9fcc92020-04-07 20:13:08 +010069// -------------------------------------------------------------------------------------------------
70
Lais Andrade08666612020-08-07 16:16:31 +000071const constexpr char* STATUS_T_ERROR_MESSAGE_PREFIX = "status_t = ";
72const constexpr char* STATUS_V_1_0_ERROR_MESSAGE_PREFIX =
73 "android::hardware::vibrator::V1_0::Status = ";
74
Lais Andrade9e9fcc92020-04-07 20:13:08 +010075template <typename T>
Lais Andrade9e9fcc92020-04-07 20:13:08 +010076HalResult<T> HalResult<T>::fromStatus(V1_0::Status status, T data) {
77 switch (status) {
78 case V1_0::Status::OK:
79 return HalResult<T>::ok(data);
80 case V1_0::Status::UNSUPPORTED_OPERATION:
81 return HalResult<T>::unsupported();
82 default:
Lais Andrade08666612020-08-07 16:16:31 +000083 return HalResult<T>::failed(STATUS_V_1_0_ERROR_MESSAGE_PREFIX + toString(status));
Lais Andrade9e9fcc92020-04-07 20:13:08 +010084 }
85}
86
87template <typename T>
88template <typename R>
89HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, T data) {
Lais Andrade08666612020-08-07 16:16:31 +000090 return ret.isOk() ? HalResult<T>::ok(data) : HalResult<T>::failed(ret.description());
Lais Andrade9e9fcc92020-04-07 20:13:08 +010091}
92
93template <typename T>
94template <typename R>
95HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, V1_0::Status status, T data) {
Lais Andrade08666612020-08-07 16:16:31 +000096 return ret.isOk() ? HalResult<T>::fromStatus(status, data)
97 : HalResult<T>::failed(ret.description());
Lais Andrade9e9fcc92020-04-07 20:13:08 +010098}
99
100// -------------------------------------------------------------------------------------------------
101
Lais Andrade08666612020-08-07 16:16:31 +0000102HalResult<void> HalResult<void>::fromStatus(status_t status) {
103 if (status == android::OK) {
104 return HalResult<void>::ok();
105 }
106 return HalResult<void>::failed(STATUS_T_ERROR_MESSAGE_PREFIX + statusToString(status));
107}
108
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100109HalResult<void> HalResult<void>::fromStatus(binder::Status status) {
110 if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
111 return HalResult<void>::unsupported();
112 }
113 if (status.isOk()) {
114 return HalResult<void>::ok();
115 }
Lais Andrade08666612020-08-07 16:16:31 +0000116 return HalResult<void>::failed(std::string(status.toString8().c_str()));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100117}
118
119HalResult<void> HalResult<void>::fromStatus(V1_0::Status status) {
120 switch (status) {
121 case V1_0::Status::OK:
122 return HalResult<void>::ok();
123 case V1_0::Status::UNSUPPORTED_OPERATION:
124 return HalResult<void>::unsupported();
125 default:
Lais Andrade08666612020-08-07 16:16:31 +0000126 return HalResult<void>::failed(STATUS_V_1_0_ERROR_MESSAGE_PREFIX + toString(status));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100127 }
128}
129
130template <typename R>
131HalResult<void> HalResult<void>::fromReturn(hardware::Return<R>& ret) {
Lais Andrade08666612020-08-07 16:16:31 +0000132 return ret.isOk() ? HalResult<void>::ok() : HalResult<void>::failed(ret.description());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100133}
134
135// -------------------------------------------------------------------------------------------------
136
Lais Andrade965284b2021-03-19 20:58:15 +0000137Info HalWrapper::getInfo() {
138 getCapabilities();
139 getPrimitiveDurations();
140 std::lock_guard<std::mutex> lock(mInfoMutex);
141 if (mInfoCache.mSupportedEffects.isFailed()) {
142 mInfoCache.mSupportedEffects = getSupportedEffectsInternal();
143 }
144 if (mInfoCache.mResonantFrequency.isFailed()) {
145 mInfoCache.mResonantFrequency = getResonantFrequencyInternal();
146 }
147 if (mInfoCache.mQFactor.isFailed()) {
148 mInfoCache.mQFactor = getQFactorInternal();
149 }
150 return mInfoCache.get();
151}
152
153HalResult<Capabilities> HalWrapper::getCapabilities() {
154 std::lock_guard<std::mutex> lock(mInfoMutex);
155 if (mInfoCache.mCapabilities.isFailed()) {
156 mInfoCache.mCapabilities = getCapabilitiesInternal();
157 }
158 return mInfoCache.mCapabilities;
159}
160
161HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurations() {
162 std::lock_guard<std::mutex> lock(mInfoMutex);
163 if (mInfoCache.mSupportedPrimitives.isFailed()) {
164 mInfoCache.mSupportedPrimitives = getSupportedPrimitivesInternal();
165 if (mInfoCache.mSupportedPrimitives.isUnsupported()) {
166 mInfoCache.mPrimitiveDurations = HalResult<std::vector<milliseconds>>::unsupported();
167 }
168 }
169 if (mInfoCache.mPrimitiveDurations.isFailed() && mInfoCache.mSupportedPrimitives.isOk()) {
170 mInfoCache.mPrimitiveDurations =
171 getPrimitiveDurationsInternal(mInfoCache.mSupportedPrimitives.value());
172 }
173 return mInfoCache.mPrimitiveDurations;
174}
175
176HalResult<std::vector<Effect>> HalWrapper::getSupportedEffectsInternal() {
177 ALOGV("Skipped getSupportedEffects because it's not available in Vibrator HAL");
178 return HalResult<std::vector<Effect>>::unsupported();
179}
180
181HalResult<std::vector<CompositePrimitive>> HalWrapper::getSupportedPrimitivesInternal() {
182 ALOGV("Skipped getSupportedPrimitives because it's not available in Vibrator HAL");
183 return HalResult<std::vector<CompositePrimitive>>::unsupported();
184}
185
186HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurationsInternal(
187 const std::vector<CompositePrimitive>&) {
188 ALOGV("Skipped getPrimitiveDurations because it's not available in Vibrator HAL");
189 return HalResult<std::vector<milliseconds>>::unsupported();
190}
191
192HalResult<float> HalWrapper::getResonantFrequencyInternal() {
193 ALOGV("Skipped getResonantFrequency because it's not available in Vibrator HAL");
194 return HalResult<float>::unsupported();
195}
196
197HalResult<float> HalWrapper::getQFactorInternal() {
198 ALOGV("Skipped getQFactor because it's not available in Vibrator HAL");
199 return HalResult<float>::unsupported();
200}
201
202// -------------------------------------------------------------------------------------------------
203
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100204HalResult<void> AidlHalWrapper::ping() {
Lais Andrade08666612020-08-07 16:16:31 +0000205 return HalResult<void>::fromStatus(IInterface::asBinder(getHal())->pingBinder());
Lais Andradecfd81152020-07-01 09:00:26 +0000206}
207
208void AidlHalWrapper::tryReconnect() {
Lais Andrade98c97032020-11-17 19:23:01 +0000209 auto result = mReconnectFn();
210 if (!result.isOk()) {
211 return;
212 }
213 sp<Aidl::IVibrator> newHandle = result.value();
Lais Andradecfd81152020-07-01 09:00:26 +0000214 if (newHandle) {
215 std::lock_guard<std::mutex> lock(mHandleMutex);
216 mHandle = std::move(newHandle);
217 }
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100218}
219
220HalResult<void> AidlHalWrapper::on(milliseconds timeout,
221 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000222 HalResult<Capabilities> capabilities = getCapabilities();
223 bool supportsCallback = capabilities.isOk() &&
224 static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
225 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
226
Lais Andradecfd81152020-07-01 09:00:26 +0000227 auto ret = HalResult<void>::fromStatus(getHal()->on(timeout.count(), cb));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000228 if (!supportsCallback && ret.isOk()) {
229 mCallbackScheduler->schedule(completionCallback, timeout);
230 }
231
232 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100233}
234
235HalResult<void> AidlHalWrapper::off() {
Lais Andradecfd81152020-07-01 09:00:26 +0000236 return HalResult<void>::fromStatus(getHal()->off());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100237}
238
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000239HalResult<void> AidlHalWrapper::setAmplitude(float amplitude) {
240 return HalResult<void>::fromStatus(getHal()->setAmplitude(amplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100241}
242
243HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000244 return HalResult<void>::fromStatus(getHal()->setExternalControl(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100245}
246
247HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
Lais Andradecfd81152020-07-01 09:00:26 +0000248 return HalResult<void>::fromStatus(getHal()->alwaysOnEnable(id, effect, strength));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100249}
250
251HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
Lais Andradecfd81152020-07-01 09:00:26 +0000252 return HalResult<void>::fromStatus(getHal()->alwaysOnDisable(id));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100253}
254
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100255HalResult<milliseconds> AidlHalWrapper::performEffect(
256 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000257 HalResult<Capabilities> capabilities = getCapabilities();
258 bool supportsCallback = capabilities.isOk() &&
259 static_cast<int32_t>(capabilities.value() & Capabilities::PERFORM_CALLBACK);
260 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
261
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100262 int32_t lengthMs;
Lais Andradecfd81152020-07-01 09:00:26 +0000263 auto result = getHal()->perform(effect, strength, cb, &lengthMs);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000264 milliseconds length = milliseconds(lengthMs);
265
266 auto ret = HalResult<milliseconds>::fromStatus(result, length);
267 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 Andrade9e9fcc92020-04-07 20:13:08 +0100275 const std::vector<CompositeEffect>& primitiveEffects,
276 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 Andrade9e9fcc92020-04-07 20:13:08 +0100278 auto cb = new 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);
282 for (const auto& effect : primitiveEffects) {
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 Andrade965284b2021-03-19 20:58:15 +0000293 return HalResult<milliseconds>::fromStatus(getHal()->compose(primitiveEffects, cb), duration);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100294}
295
Lais Andrade10d9dc72020-05-20 12:00:49 +0000296HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
297 int32_t capabilities = 0;
Lais Andradecfd81152020-07-01 09:00:26 +0000298 auto result = getHal()->getCapabilities(&capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000299 return HalResult<Capabilities>::fromStatus(result, static_cast<Capabilities>(capabilities));
300}
301
302HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
303 std::vector<Effect> supportedEffects;
Lais Andradecfd81152020-07-01 09:00:26 +0000304 auto result = getHal()->getSupportedEffects(&supportedEffects);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000305 return HalResult<std::vector<Effect>>::fromStatus(result, supportedEffects);
306}
307
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000308HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() {
309 std::vector<CompositePrimitive> supportedPrimitives;
310 auto result = getHal()->getSupportedPrimitives(&supportedPrimitives);
311 return HalResult<std::vector<CompositePrimitive>>::fromStatus(result, supportedPrimitives);
312}
313
Lais Andrade965284b2021-03-19 20:58:15 +0000314HalResult<std::vector<milliseconds>> AidlHalWrapper::getPrimitiveDurationsInternal(
315 const std::vector<CompositePrimitive>& supportedPrimitives) {
316 std::vector<milliseconds> durations;
317 constexpr auto primitiveRange = enum_range<CompositePrimitive>();
318 constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
319 durations.resize(primitiveCount);
320
321 for (auto primitive : supportedPrimitives) {
322 auto primitiveIdx = static_cast<size_t>(primitive);
323 if (primitiveIdx >= durations.size()) {
324 // Safety check, should not happen if enum_range is correct.
325 continue;
326 }
327 int32_t duration = 0;
328 auto status = getHal()->getPrimitiveDuration(primitive, &duration);
329 if (!status.isOk()) {
330 return HalResult<std::vector<milliseconds>>::failed(status.toString8().c_str());
331 }
332 durations[primitiveIdx] = milliseconds(duration);
333 }
334
335 return HalResult<std::vector<milliseconds>>::ok(durations);
336}
337
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000338HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() {
339 float f0 = 0;
340 auto result = getHal()->getResonantFrequency(&f0);
341 return HalResult<float>::fromStatus(result, f0);
342}
343
344HalResult<float> AidlHalWrapper::getQFactorInternal() {
345 float qFactor = 0;
346 auto result = getHal()->getQFactor(&qFactor);
347 return HalResult<float>::fromStatus(result, qFactor);
348}
349
Lais Andradecfd81152020-07-01 09:00:26 +0000350sp<Aidl::IVibrator> AidlHalWrapper::getHal() {
351 std::lock_guard<std::mutex> lock(mHandleMutex);
352 return mHandle;
353}
354
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100355// -------------------------------------------------------------------------------------------------
356
Lais Andradecfd81152020-07-01 09:00:26 +0000357template <typename I>
358HalResult<void> HidlHalWrapper<I>::ping() {
359 auto result = getHal()->ping();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100360 return HalResult<void>::fromReturn(result);
361}
362
Lais Andradecfd81152020-07-01 09:00:26 +0000363template <typename I>
364void HidlHalWrapper<I>::tryReconnect() {
365 sp<I> newHandle = I::tryGetService();
366 if (newHandle) {
367 std::lock_guard<std::mutex> lock(mHandleMutex);
368 mHandle = std::move(newHandle);
369 }
370}
371
372template <typename I>
373HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
374 const std::function<void()>& completionCallback) {
375 auto result = getHal()->on(timeout.count());
Lais Andrade10d9dc72020-05-20 12:00:49 +0000376 auto ret = HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
377 if (ret.isOk()) {
378 mCallbackScheduler->schedule(completionCallback, timeout);
379 }
380 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100381}
382
Lais Andradecfd81152020-07-01 09:00:26 +0000383template <typename I>
384HalResult<void> HidlHalWrapper<I>::off() {
385 auto result = getHal()->off();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100386 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
387}
388
Lais Andradecfd81152020-07-01 09:00:26 +0000389template <typename I>
Lais Andrade4e2b2d42021-02-15 20:58:51 +0000390HalResult<void> HidlHalWrapper<I>::setAmplitude(float amplitude) {
391 uint8_t amp = static_cast<uint8_t>(amplitude * std::numeric_limits<uint8_t>::max());
392 auto result = getHal()->setAmplitude(amp);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100393 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
394}
395
Lais Andradecfd81152020-07-01 09:00:26 +0000396template <typename I>
397HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100398 ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
399 return HalResult<void>::unsupported();
400}
401
Lais Andradecfd81152020-07-01 09:00:26 +0000402template <typename I>
403HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100404 ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
405 return HalResult<void>::unsupported();
406}
407
Lais Andradecfd81152020-07-01 09:00:26 +0000408template <typename I>
409HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100410 ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
411 return HalResult<void>::unsupported();
412}
413
Lais Andradecfd81152020-07-01 09:00:26 +0000414template <typename I>
Lais Andrade49b60b12021-02-23 13:27:41 +0000415HalResult<std::chrono::milliseconds> HidlHalWrapper<I>::performComposedEffect(
416 const std::vector<CompositeEffect>&, const std::function<void()>&) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100417 ALOGV("Skipped composed effect because Vibrator HAL AIDL is not available");
Lais Andrade49b60b12021-02-23 13:27:41 +0000418 return HalResult<std::chrono::milliseconds>::unsupported();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100419}
420
Lais Andradecfd81152020-07-01 09:00:26 +0000421template <typename I>
422HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
423 hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
Lais Andraded39ff7d2020-05-19 10:42:51 +0000424 Capabilities capabilities =
425 result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
426 return HalResult<Capabilities>::fromReturn(result, capabilities);
427}
428
Lais Andradecfd81152020-07-01 09:00:26 +0000429template <typename I>
430template <typename T>
431HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
432 perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
Lais Andrade10d9dc72020-05-20 12:00:49 +0000433 const std::function<void()>& completionCallback) {
434 V1_0::Status status;
435 int32_t lengthMs;
436 auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
437 status = retStatus;
438 lengthMs = retLengthMs;
439 };
440
441 V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
442 auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
443 milliseconds length = milliseconds(lengthMs);
444
445 auto ret = HalResult<milliseconds>::fromReturn(result, status, length);
446 if (ret.isOk()) {
447 mCallbackScheduler->schedule(completionCallback, length);
448 }
449
450 return ret;
451}
452
Lais Andradecfd81152020-07-01 09:00:26 +0000453template <typename I>
454sp<I> HidlHalWrapper<I>::getHal() {
455 std::lock_guard<std::mutex> lock(mHandleMutex);
456 return mHandle;
457}
458
459// -------------------------------------------------------------------------------------------------
460
461HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
Lais Andrade10d9dc72020-05-20 12:00:49 +0000462 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andradecfd81152020-07-01 09:00:26 +0000463 if (isStaticCastValid<V1_0::Effect>(effect)) {
464 return performInternal(&V1_0::IVibrator::perform, getHal(),
465 static_cast<V1_0::Effect>(effect), strength, completionCallback);
466 }
467
468 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
469 Aidl::toString(effect).c_str());
470 return HalResult<milliseconds>::unsupported();
Lais Andrade10d9dc72020-05-20 12:00:49 +0000471}
472
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100473// -------------------------------------------------------------------------------------------------
474
Lais Andrade10d9dc72020-05-20 12:00:49 +0000475HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
476 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100477 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000478 return performInternal(&V1_1::IVibrator::perform, getHal(),
479 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100480 }
481 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000482 return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
483 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100484 }
485
486 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
487 Aidl::toString(effect).c_str());
488 return HalResult<milliseconds>::unsupported();
489}
490
491// -------------------------------------------------------------------------------------------------
492
Lais Andrade10d9dc72020-05-20 12:00:49 +0000493HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
494 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100495 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000496 return performInternal(&V1_2::IVibrator::perform, getHal(),
497 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100498 }
499 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000500 return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
501 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100502 }
503 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000504 return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
505 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100506 }
507
508 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
509 Aidl::toString(effect).c_str());
510 return HalResult<milliseconds>::unsupported();
511}
512
513// -------------------------------------------------------------------------------------------------
514
515HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000516 auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100517 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
518}
519
Lais Andrade10d9dc72020-05-20 12:00:49 +0000520HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
521 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100522 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000523 return performInternal(&V1_3::IVibrator::perform, getHal(),
524 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100525 }
526 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000527 return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
528 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100529 }
530 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000531 return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
532 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100533 }
534 if (isStaticCastValid<V1_3::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000535 return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
536 static_cast<V1_3::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100537 }
538
539 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
540 Aidl::toString(effect).c_str());
541 return HalResult<milliseconds>::unsupported();
542}
543
Lais Andraded39ff7d2020-05-19 10:42:51 +0000544HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
Lais Andrade08666612020-08-07 16:16:31 +0000545 Capabilities capabilities = Capabilities::NONE;
546
Lais Andradecfd81152020-07-01 09:00:26 +0000547 sp<V1_3::IVibrator> hal = getHal();
548 auto amplitudeResult = hal->supportsAmplitudeControl();
549 if (!amplitudeResult.isOk()) {
Lais Andrade08666612020-08-07 16:16:31 +0000550 return HalResult<Capabilities>::fromReturn(amplitudeResult, capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000551 }
552
Lais Andradecfd81152020-07-01 09:00:26 +0000553 auto externalControlResult = hal->supportsExternalControl();
Lais Andradecfd81152020-07-01 09:00:26 +0000554 if (amplitudeResult.withDefault(false)) {
555 capabilities |= Capabilities::AMPLITUDE_CONTROL;
556 }
557 if (externalControlResult.withDefault(false)) {
558 capabilities |= Capabilities::EXTERNAL_CONTROL;
Lais Andrade602ff962020-08-27 12:02:53 +0000559
560 if (amplitudeResult.withDefault(false)) {
561 capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL;
562 }
Lais Andradecfd81152020-07-01 09:00:26 +0000563 }
564
565 return HalResult<Capabilities>::fromReturn(externalControlResult, capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000566}
567
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100568// -------------------------------------------------------------------------------------------------
569
570}; // namespace vibrator
571
572}; // namespace android