blob: 9672644d8d1cfbf397887a358cac9ee1a9875ab9 [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>
20#include <android/hardware/vibrator/BnVibratorCallback.h>
21#include <android/hardware/vibrator/IVibrator.h>
22#include <hardware/vibrator.h>
23
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(binder::Status status, T data) {
77 if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
78 return HalResult<T>::unsupported();
79 }
80 if (status.isOk()) {
81 return HalResult<T>::ok(data);
82 }
Lais Andrade08666612020-08-07 16:16:31 +000083 return HalResult<T>::failed(std::string(status.toString8().c_str()));
Lais Andrade9e9fcc92020-04-07 20:13:08 +010084}
85
86template <typename T>
87HalResult<T> HalResult<T>::fromStatus(V1_0::Status status, T data) {
88 switch (status) {
89 case V1_0::Status::OK:
90 return HalResult<T>::ok(data);
91 case V1_0::Status::UNSUPPORTED_OPERATION:
92 return HalResult<T>::unsupported();
93 default:
Lais Andrade08666612020-08-07 16:16:31 +000094 return HalResult<T>::failed(STATUS_V_1_0_ERROR_MESSAGE_PREFIX + toString(status));
Lais Andrade9e9fcc92020-04-07 20:13:08 +010095 }
96}
97
98template <typename T>
99template <typename R>
100HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, T data) {
Lais Andrade08666612020-08-07 16:16:31 +0000101 return ret.isOk() ? HalResult<T>::ok(data) : HalResult<T>::failed(ret.description());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100102}
103
104template <typename T>
105template <typename R>
106HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, V1_0::Status status, T data) {
Lais Andrade08666612020-08-07 16:16:31 +0000107 return ret.isOk() ? HalResult<T>::fromStatus(status, data)
108 : HalResult<T>::failed(ret.description());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100109}
110
111// -------------------------------------------------------------------------------------------------
112
Lais Andrade08666612020-08-07 16:16:31 +0000113HalResult<void> HalResult<void>::fromStatus(status_t status) {
114 if (status == android::OK) {
115 return HalResult<void>::ok();
116 }
117 return HalResult<void>::failed(STATUS_T_ERROR_MESSAGE_PREFIX + statusToString(status));
118}
119
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100120HalResult<void> HalResult<void>::fromStatus(binder::Status status) {
121 if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
122 return HalResult<void>::unsupported();
123 }
124 if (status.isOk()) {
125 return HalResult<void>::ok();
126 }
Lais Andrade08666612020-08-07 16:16:31 +0000127 return HalResult<void>::failed(std::string(status.toString8().c_str()));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100128}
129
130HalResult<void> HalResult<void>::fromStatus(V1_0::Status status) {
131 switch (status) {
132 case V1_0::Status::OK:
133 return HalResult<void>::ok();
134 case V1_0::Status::UNSUPPORTED_OPERATION:
135 return HalResult<void>::unsupported();
136 default:
Lais Andrade08666612020-08-07 16:16:31 +0000137 return HalResult<void>::failed(STATUS_V_1_0_ERROR_MESSAGE_PREFIX + toString(status));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100138 }
139}
140
141template <typename R>
142HalResult<void> HalResult<void>::fromReturn(hardware::Return<R>& ret) {
Lais Andrade08666612020-08-07 16:16:31 +0000143 return ret.isOk() ? HalResult<void>::ok() : HalResult<void>::failed(ret.description());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100144}
145
146// -------------------------------------------------------------------------------------------------
147
148class HalCallbackWrapper : public Aidl::BnVibratorCallback {
149public:
Lais Andrade10d9dc72020-05-20 12:00:49 +0000150 HalCallbackWrapper(std::function<void()> completionCallback)
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100151 : mCompletionCallback(completionCallback) {}
152
153 binder::Status onComplete() override {
154 mCompletionCallback();
155 return binder::Status::ok();
156 }
157
158private:
159 const std::function<void()> mCompletionCallback;
160};
161
162// -------------------------------------------------------------------------------------------------
163
164HalResult<void> AidlHalWrapper::ping() {
Lais Andrade08666612020-08-07 16:16:31 +0000165 return HalResult<void>::fromStatus(IInterface::asBinder(getHal())->pingBinder());
Lais Andradecfd81152020-07-01 09:00:26 +0000166}
167
168void AidlHalWrapper::tryReconnect() {
169 sp<Aidl::IVibrator> newHandle = checkVintfService<Aidl::IVibrator>();
170 if (newHandle) {
171 std::lock_guard<std::mutex> lock(mHandleMutex);
172 mHandle = std::move(newHandle);
173 }
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100174}
175
176HalResult<void> AidlHalWrapper::on(milliseconds timeout,
177 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000178 HalResult<Capabilities> capabilities = getCapabilities();
179 bool supportsCallback = capabilities.isOk() &&
180 static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
181 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
182
Lais Andradecfd81152020-07-01 09:00:26 +0000183 auto ret = HalResult<void>::fromStatus(getHal()->on(timeout.count(), cb));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000184 if (!supportsCallback && ret.isOk()) {
185 mCallbackScheduler->schedule(completionCallback, timeout);
186 }
187
188 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100189}
190
191HalResult<void> AidlHalWrapper::off() {
Lais Andradecfd81152020-07-01 09:00:26 +0000192 return HalResult<void>::fromStatus(getHal()->off());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100193}
194
195HalResult<void> AidlHalWrapper::setAmplitude(int32_t amplitude) {
196 float convertedAmplitude = static_cast<float>(amplitude) / std::numeric_limits<uint8_t>::max();
Lais Andradecfd81152020-07-01 09:00:26 +0000197 return HalResult<void>::fromStatus(getHal()->setAmplitude(convertedAmplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100198}
199
200HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000201 return HalResult<void>::fromStatus(getHal()->setExternalControl(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100202}
203
204HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
Lais Andradecfd81152020-07-01 09:00:26 +0000205 return HalResult<void>::fromStatus(getHal()->alwaysOnEnable(id, effect, strength));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100206}
207
208HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
Lais Andradecfd81152020-07-01 09:00:26 +0000209 return HalResult<void>::fromStatus(getHal()->alwaysOnDisable(id));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100210}
211
212HalResult<Capabilities> AidlHalWrapper::getCapabilities() {
Lais Andraded39ff7d2020-05-19 10:42:51 +0000213 std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000214 return loadCached<Capabilities>(std::bind(&AidlHalWrapper::getCapabilitiesInternal, this),
215 mCapabilities);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100216}
217
218HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffects() {
Lais Andraded39ff7d2020-05-19 10:42:51 +0000219 std::lock_guard<std::mutex> lock(mSupportedEffectsMutex);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000220 return loadCached<std::vector<Effect>>(std::bind(&AidlHalWrapper::getSupportedEffectsInternal,
221 this),
222 mSupportedEffects);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100223}
224
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000225HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitives() {
226 std::lock_guard<std::mutex> lock(mSupportedPrimitivesMutex);
227 return loadCached<std::vector<
228 CompositePrimitive>>(std::bind(&AidlHalWrapper::getSupportedPrimitivesInternal, this),
229 mSupportedPrimitives);
230}
231
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100232HalResult<milliseconds> AidlHalWrapper::performEffect(
233 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000234 HalResult<Capabilities> capabilities = getCapabilities();
235 bool supportsCallback = capabilities.isOk() &&
236 static_cast<int32_t>(capabilities.value() & Capabilities::PERFORM_CALLBACK);
237 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
238
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100239 int32_t lengthMs;
Lais Andradecfd81152020-07-01 09:00:26 +0000240 auto result = getHal()->perform(effect, strength, cb, &lengthMs);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000241 milliseconds length = milliseconds(lengthMs);
242
243 auto ret = HalResult<milliseconds>::fromStatus(result, length);
244 if (!supportsCallback && ret.isOk()) {
245 mCallbackScheduler->schedule(completionCallback, length);
246 }
247
248 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100249}
250
251HalResult<void> AidlHalWrapper::performComposedEffect(
252 const std::vector<CompositeEffect>& primitiveEffects,
253 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000254 // This method should always support callbacks, so no need to double check.
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100255 auto cb = new HalCallbackWrapper(completionCallback);
Lais Andradecfd81152020-07-01 09:00:26 +0000256 return HalResult<void>::fromStatus(getHal()->compose(primitiveEffects, cb));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100257}
258
Lais Andrade10d9dc72020-05-20 12:00:49 +0000259HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
260 int32_t capabilities = 0;
Lais Andradecfd81152020-07-01 09:00:26 +0000261 auto result = getHal()->getCapabilities(&capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000262 return HalResult<Capabilities>::fromStatus(result, static_cast<Capabilities>(capabilities));
263}
264
265HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
266 std::vector<Effect> supportedEffects;
Lais Andradecfd81152020-07-01 09:00:26 +0000267 auto result = getHal()->getSupportedEffects(&supportedEffects);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000268 return HalResult<std::vector<Effect>>::fromStatus(result, supportedEffects);
269}
270
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000271HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() {
272 std::vector<CompositePrimitive> supportedPrimitives;
273 auto result = getHal()->getSupportedPrimitives(&supportedPrimitives);
274 return HalResult<std::vector<CompositePrimitive>>::fromStatus(result, supportedPrimitives);
275}
276
Lais Andradecfd81152020-07-01 09:00:26 +0000277sp<Aidl::IVibrator> AidlHalWrapper::getHal() {
278 std::lock_guard<std::mutex> lock(mHandleMutex);
279 return mHandle;
280}
281
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100282// -------------------------------------------------------------------------------------------------
283
Lais Andradecfd81152020-07-01 09:00:26 +0000284template <typename I>
285HalResult<void> HidlHalWrapper<I>::ping() {
286 auto result = getHal()->ping();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100287 return HalResult<void>::fromReturn(result);
288}
289
Lais Andradecfd81152020-07-01 09:00:26 +0000290template <typename I>
291void HidlHalWrapper<I>::tryReconnect() {
292 sp<I> newHandle = I::tryGetService();
293 if (newHandle) {
294 std::lock_guard<std::mutex> lock(mHandleMutex);
295 mHandle = std::move(newHandle);
296 }
297}
298
299template <typename I>
300HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
301 const std::function<void()>& completionCallback) {
302 auto result = getHal()->on(timeout.count());
Lais Andrade10d9dc72020-05-20 12:00:49 +0000303 auto ret = HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
304 if (ret.isOk()) {
305 mCallbackScheduler->schedule(completionCallback, timeout);
306 }
307 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100308}
309
Lais Andradecfd81152020-07-01 09:00:26 +0000310template <typename I>
311HalResult<void> HidlHalWrapper<I>::off() {
312 auto result = getHal()->off();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100313 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
314}
315
Lais Andradecfd81152020-07-01 09:00:26 +0000316template <typename I>
317HalResult<void> HidlHalWrapper<I>::setAmplitude(int32_t amplitude) {
318 auto result = getHal()->setAmplitude(static_cast<uint8_t>(amplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100319 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
320}
321
Lais Andradecfd81152020-07-01 09:00:26 +0000322template <typename I>
323HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100324 ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
325 return HalResult<void>::unsupported();
326}
327
Lais Andradecfd81152020-07-01 09:00:26 +0000328template <typename I>
329HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100330 ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
331 return HalResult<void>::unsupported();
332}
333
Lais Andradecfd81152020-07-01 09:00:26 +0000334template <typename I>
335HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100336 ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
337 return HalResult<void>::unsupported();
338}
339
Lais Andradecfd81152020-07-01 09:00:26 +0000340template <typename I>
341HalResult<Capabilities> HidlHalWrapper<I>::getCapabilities() {
Lais Andraded39ff7d2020-05-19 10:42:51 +0000342 std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
Lais Andradecfd81152020-07-01 09:00:26 +0000343 return loadCached<Capabilities>(std::bind(&HidlHalWrapper<I>::getCapabilitiesInternal, this),
Lais Andraded39ff7d2020-05-19 10:42:51 +0000344 mCapabilities);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100345}
346
Lais Andradecfd81152020-07-01 09:00:26 +0000347template <typename I>
348HalResult<std::vector<Effect>> HidlHalWrapper<I>::getSupportedEffects() {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100349 ALOGV("Skipped getSupportedEffects because Vibrator HAL AIDL is not available");
350 return HalResult<std::vector<Effect>>::unsupported();
351}
352
Lais Andradecfd81152020-07-01 09:00:26 +0000353template <typename I>
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000354HalResult<std::vector<CompositePrimitive>> HidlHalWrapper<I>::getSupportedPrimitives() {
355 ALOGV("Skipped getSupportedPrimitives because Vibrator HAL AIDL is not available");
356 return HalResult<std::vector<CompositePrimitive>>::unsupported();
357}
358
359template <typename I>
Lais Andradecfd81152020-07-01 09:00:26 +0000360HalResult<void> HidlHalWrapper<I>::performComposedEffect(const std::vector<CompositeEffect>&,
361 const std::function<void()>&) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100362 ALOGV("Skipped composed effect because Vibrator HAL AIDL is not available");
363 return HalResult<void>::unsupported();
364}
365
Lais Andradecfd81152020-07-01 09:00:26 +0000366template <typename I>
367HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
368 hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
Lais Andraded39ff7d2020-05-19 10:42:51 +0000369 Capabilities capabilities =
370 result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
371 return HalResult<Capabilities>::fromReturn(result, capabilities);
372}
373
Lais Andradecfd81152020-07-01 09:00:26 +0000374template <typename I>
375template <typename T>
376HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
377 perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
Lais Andrade10d9dc72020-05-20 12:00:49 +0000378 const std::function<void()>& completionCallback) {
379 V1_0::Status status;
380 int32_t lengthMs;
381 auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
382 status = retStatus;
383 lengthMs = retLengthMs;
384 };
385
386 V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
387 auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
388 milliseconds length = milliseconds(lengthMs);
389
390 auto ret = HalResult<milliseconds>::fromReturn(result, status, length);
391 if (ret.isOk()) {
392 mCallbackScheduler->schedule(completionCallback, length);
393 }
394
395 return ret;
396}
397
Lais Andradecfd81152020-07-01 09:00:26 +0000398template <typename I>
399sp<I> HidlHalWrapper<I>::getHal() {
400 std::lock_guard<std::mutex> lock(mHandleMutex);
401 return mHandle;
402}
403
404// -------------------------------------------------------------------------------------------------
405
406HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
Lais Andrade10d9dc72020-05-20 12:00:49 +0000407 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andradecfd81152020-07-01 09:00:26 +0000408 if (isStaticCastValid<V1_0::Effect>(effect)) {
409 return performInternal(&V1_0::IVibrator::perform, getHal(),
410 static_cast<V1_0::Effect>(effect), strength, completionCallback);
411 }
412
413 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
414 Aidl::toString(effect).c_str());
415 return HalResult<milliseconds>::unsupported();
Lais Andrade10d9dc72020-05-20 12:00:49 +0000416}
417
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100418// -------------------------------------------------------------------------------------------------
419
Lais Andrade10d9dc72020-05-20 12:00:49 +0000420HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
421 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100422 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000423 return performInternal(&V1_1::IVibrator::perform, getHal(),
424 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100425 }
426 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000427 return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
428 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100429 }
430
431 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
432 Aidl::toString(effect).c_str());
433 return HalResult<milliseconds>::unsupported();
434}
435
436// -------------------------------------------------------------------------------------------------
437
Lais Andrade10d9dc72020-05-20 12:00:49 +0000438HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
439 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100440 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000441 return performInternal(&V1_2::IVibrator::perform, getHal(),
442 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100443 }
444 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000445 return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
446 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100447 }
448 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000449 return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
450 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100451 }
452
453 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
454 Aidl::toString(effect).c_str());
455 return HalResult<milliseconds>::unsupported();
456}
457
458// -------------------------------------------------------------------------------------------------
459
460HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000461 auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100462 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
463}
464
Lais Andrade10d9dc72020-05-20 12:00:49 +0000465HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
466 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100467 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000468 return performInternal(&V1_3::IVibrator::perform, getHal(),
469 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100470 }
471 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000472 return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
473 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100474 }
475 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000476 return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
477 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100478 }
479 if (isStaticCastValid<V1_3::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000480 return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
481 static_cast<V1_3::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100482 }
483
484 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
485 Aidl::toString(effect).c_str());
486 return HalResult<milliseconds>::unsupported();
487}
488
Lais Andraded39ff7d2020-05-19 10:42:51 +0000489HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
Lais Andrade08666612020-08-07 16:16:31 +0000490 Capabilities capabilities = Capabilities::NONE;
491
Lais Andradecfd81152020-07-01 09:00:26 +0000492 sp<V1_3::IVibrator> hal = getHal();
493 auto amplitudeResult = hal->supportsAmplitudeControl();
494 if (!amplitudeResult.isOk()) {
Lais Andrade08666612020-08-07 16:16:31 +0000495 return HalResult<Capabilities>::fromReturn(amplitudeResult, capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000496 }
497
Lais Andradecfd81152020-07-01 09:00:26 +0000498 auto externalControlResult = hal->supportsExternalControl();
Lais Andradecfd81152020-07-01 09:00:26 +0000499 if (amplitudeResult.withDefault(false)) {
500 capabilities |= Capabilities::AMPLITUDE_CONTROL;
501 }
502 if (externalControlResult.withDefault(false)) {
503 capabilities |= Capabilities::EXTERNAL_CONTROL;
Lais Andrade602ff962020-08-27 12:02:53 +0000504
505 if (amplitudeResult.withDefault(false)) {
506 capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL;
507 }
Lais Andradecfd81152020-07-01 09:00:26 +0000508 }
509
510 return HalResult<Capabilities>::fromReturn(externalControlResult, capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000511}
512
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100513// -------------------------------------------------------------------------------------------------
514
515}; // namespace vibrator
516
517}; // namespace android