blob: 6faab38c51a6bc6bc5cf1835e2c27d4defcef552 [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>
22
23#include <utils/Log.h>
24
Lais Andrade10d9dc72020-05-20 12:00:49 +000025#include <vibratorservice/VibratorCallbackScheduler.h>
Lais Andrade9e9fcc92020-04-07 20:13:08 +010026#include <vibratorservice/VibratorHalWrapper.h>
27
28using android::hardware::vibrator::CompositeEffect;
Lais Andrade07f9c0e2020-08-11 16:22:12 +000029using android::hardware::vibrator::CompositePrimitive;
Lais Andrade9e9fcc92020-04-07 20:13:08 +010030using android::hardware::vibrator::Effect;
31using android::hardware::vibrator::EffectStrength;
32
33using std::chrono::milliseconds;
34
35namespace V1_0 = android::hardware::vibrator::V1_0;
36namespace V1_1 = android::hardware::vibrator::V1_1;
37namespace V1_2 = android::hardware::vibrator::V1_2;
38namespace V1_3 = android::hardware::vibrator::V1_3;
39namespace Aidl = android::hardware::vibrator;
40
41namespace android {
42
43namespace vibrator {
44
45// -------------------------------------------------------------------------------------------------
46
47template <class T>
Lais Andraded39ff7d2020-05-19 10:42:51 +000048HalResult<T> loadCached(const std::function<HalResult<T>()>& loadFn, std::optional<T>& cache) {
49 if (cache.has_value()) {
Lais Andrade10d9dc72020-05-20 12:00:49 +000050 // Return copy of cached value.
51 return HalResult<T>::ok(*cache);
Lais Andraded39ff7d2020-05-19 10:42:51 +000052 }
53 HalResult<T> ret = loadFn();
54 if (ret.isOk()) {
Lais Andrade10d9dc72020-05-20 12:00:49 +000055 // Cache copy of returned value.
Lais Andraded39ff7d2020-05-19 10:42:51 +000056 cache.emplace(ret.value());
57 }
58 return ret;
59}
60
61template <class T>
Lais Andrade9e9fcc92020-04-07 20:13:08 +010062bool isStaticCastValid(Effect effect) {
63 T castEffect = static_cast<T>(effect);
64 auto iter = hardware::hidl_enum_range<T>();
65 return castEffect >= *iter.begin() && castEffect <= *std::prev(iter.end());
66}
67
Lais Andrade9e9fcc92020-04-07 20:13:08 +010068// -------------------------------------------------------------------------------------------------
69
Lais Andrade08666612020-08-07 16:16:31 +000070const constexpr char* STATUS_T_ERROR_MESSAGE_PREFIX = "status_t = ";
71const constexpr char* STATUS_V_1_0_ERROR_MESSAGE_PREFIX =
72 "android::hardware::vibrator::V1_0::Status = ";
73
Lais Andrade9e9fcc92020-04-07 20:13:08 +010074template <typename T>
Lais Andrade9e9fcc92020-04-07 20:13:08 +010075HalResult<T> HalResult<T>::fromStatus(V1_0::Status status, T data) {
76 switch (status) {
77 case V1_0::Status::OK:
78 return HalResult<T>::ok(data);
79 case V1_0::Status::UNSUPPORTED_OPERATION:
80 return HalResult<T>::unsupported();
81 default:
Lais Andrade08666612020-08-07 16:16:31 +000082 return HalResult<T>::failed(STATUS_V_1_0_ERROR_MESSAGE_PREFIX + toString(status));
Lais Andrade9e9fcc92020-04-07 20:13:08 +010083 }
84}
85
86template <typename T>
87template <typename R>
88HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, T data) {
Lais Andrade08666612020-08-07 16:16:31 +000089 return ret.isOk() ? HalResult<T>::ok(data) : HalResult<T>::failed(ret.description());
Lais Andrade9e9fcc92020-04-07 20:13:08 +010090}
91
92template <typename T>
93template <typename R>
94HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, V1_0::Status status, T data) {
Lais Andrade08666612020-08-07 16:16:31 +000095 return ret.isOk() ? HalResult<T>::fromStatus(status, data)
96 : HalResult<T>::failed(ret.description());
Lais Andrade9e9fcc92020-04-07 20:13:08 +010097}
98
99// -------------------------------------------------------------------------------------------------
100
Lais Andrade08666612020-08-07 16:16:31 +0000101HalResult<void> HalResult<void>::fromStatus(status_t status) {
102 if (status == android::OK) {
103 return HalResult<void>::ok();
104 }
105 return HalResult<void>::failed(STATUS_T_ERROR_MESSAGE_PREFIX + statusToString(status));
106}
107
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100108HalResult<void> HalResult<void>::fromStatus(binder::Status status) {
109 if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
110 return HalResult<void>::unsupported();
111 }
112 if (status.isOk()) {
113 return HalResult<void>::ok();
114 }
Lais Andrade08666612020-08-07 16:16:31 +0000115 return HalResult<void>::failed(std::string(status.toString8().c_str()));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100116}
117
118HalResult<void> HalResult<void>::fromStatus(V1_0::Status status) {
119 switch (status) {
120 case V1_0::Status::OK:
121 return HalResult<void>::ok();
122 case V1_0::Status::UNSUPPORTED_OPERATION:
123 return HalResult<void>::unsupported();
124 default:
Lais Andrade08666612020-08-07 16:16:31 +0000125 return HalResult<void>::failed(STATUS_V_1_0_ERROR_MESSAGE_PREFIX + toString(status));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100126 }
127}
128
129template <typename R>
130HalResult<void> HalResult<void>::fromReturn(hardware::Return<R>& ret) {
Lais Andrade08666612020-08-07 16:16:31 +0000131 return ret.isOk() ? HalResult<void>::ok() : HalResult<void>::failed(ret.description());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100132}
133
134// -------------------------------------------------------------------------------------------------
135
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100136HalResult<void> AidlHalWrapper::ping() {
Lais Andrade08666612020-08-07 16:16:31 +0000137 return HalResult<void>::fromStatus(IInterface::asBinder(getHal())->pingBinder());
Lais Andradecfd81152020-07-01 09:00:26 +0000138}
139
140void AidlHalWrapper::tryReconnect() {
Lais Andrade98c97032020-11-17 19:23:01 +0000141 auto result = mReconnectFn();
142 if (!result.isOk()) {
143 return;
144 }
145 sp<Aidl::IVibrator> newHandle = result.value();
Lais Andradecfd81152020-07-01 09:00:26 +0000146 if (newHandle) {
147 std::lock_guard<std::mutex> lock(mHandleMutex);
148 mHandle = std::move(newHandle);
149 }
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100150}
151
152HalResult<void> AidlHalWrapper::on(milliseconds timeout,
153 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000154 HalResult<Capabilities> capabilities = getCapabilities();
155 bool supportsCallback = capabilities.isOk() &&
156 static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
157 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
158
Lais Andradecfd81152020-07-01 09:00:26 +0000159 auto ret = HalResult<void>::fromStatus(getHal()->on(timeout.count(), cb));
Lais Andrade10d9dc72020-05-20 12:00:49 +0000160 if (!supportsCallback && ret.isOk()) {
161 mCallbackScheduler->schedule(completionCallback, timeout);
162 }
163
164 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100165}
166
167HalResult<void> AidlHalWrapper::off() {
Lais Andradecfd81152020-07-01 09:00:26 +0000168 return HalResult<void>::fromStatus(getHal()->off());
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100169}
170
171HalResult<void> AidlHalWrapper::setAmplitude(int32_t amplitude) {
172 float convertedAmplitude = static_cast<float>(amplitude) / std::numeric_limits<uint8_t>::max();
Lais Andradecfd81152020-07-01 09:00:26 +0000173 return HalResult<void>::fromStatus(getHal()->setAmplitude(convertedAmplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100174}
175
176HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000177 return HalResult<void>::fromStatus(getHal()->setExternalControl(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100178}
179
180HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
Lais Andradecfd81152020-07-01 09:00:26 +0000181 return HalResult<void>::fromStatus(getHal()->alwaysOnEnable(id, effect, strength));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100182}
183
184HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
Lais Andradecfd81152020-07-01 09:00:26 +0000185 return HalResult<void>::fromStatus(getHal()->alwaysOnDisable(id));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100186}
187
188HalResult<Capabilities> AidlHalWrapper::getCapabilities() {
Lais Andraded39ff7d2020-05-19 10:42:51 +0000189 std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000190 return loadCached<Capabilities>(std::bind(&AidlHalWrapper::getCapabilitiesInternal, this),
191 mCapabilities);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100192}
193
194HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffects() {
Lais Andraded39ff7d2020-05-19 10:42:51 +0000195 std::lock_guard<std::mutex> lock(mSupportedEffectsMutex);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000196 return loadCached<std::vector<Effect>>(std::bind(&AidlHalWrapper::getSupportedEffectsInternal,
197 this),
198 mSupportedEffects);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100199}
200
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000201HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitives() {
202 std::lock_guard<std::mutex> lock(mSupportedPrimitivesMutex);
203 return loadCached<std::vector<
204 CompositePrimitive>>(std::bind(&AidlHalWrapper::getSupportedPrimitivesInternal, this),
205 mSupportedPrimitives);
206}
207
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100208HalResult<milliseconds> AidlHalWrapper::performEffect(
209 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000210 HalResult<Capabilities> capabilities = getCapabilities();
211 bool supportsCallback = capabilities.isOk() &&
212 static_cast<int32_t>(capabilities.value() & Capabilities::PERFORM_CALLBACK);
213 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
214
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100215 int32_t lengthMs;
Lais Andradecfd81152020-07-01 09:00:26 +0000216 auto result = getHal()->perform(effect, strength, cb, &lengthMs);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000217 milliseconds length = milliseconds(lengthMs);
218
219 auto ret = HalResult<milliseconds>::fromStatus(result, length);
220 if (!supportsCallback && ret.isOk()) {
221 mCallbackScheduler->schedule(completionCallback, length);
222 }
223
224 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100225}
226
Lais Andrade49b60b12021-02-23 13:27:41 +0000227HalResult<milliseconds> AidlHalWrapper::performComposedEffect(
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100228 const std::vector<CompositeEffect>& primitiveEffects,
229 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000230 // This method should always support callbacks, so no need to double check.
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100231 auto cb = new HalCallbackWrapper(completionCallback);
Lais Andrade49b60b12021-02-23 13:27:41 +0000232 milliseconds duration(0);
233 for (const auto& effect : primitiveEffects) {
234 auto durationResult = getPrimitiveDuration(effect.primitive);
235 if (durationResult.isOk()) {
236 duration += durationResult.value();
237 }
238 duration += milliseconds(effect.delayMs);
239 }
240 return HalResult<milliseconds>::fromStatus(getHal()->compose(primitiveEffects, cb), duration);
241}
242
243HalResult<milliseconds> AidlHalWrapper::getPrimitiveDuration(CompositePrimitive primitive) {
244 std::lock_guard<std::mutex> lock(mSupportedPrimitivesMutex);
245 if (mPrimitiveDurations.empty()) {
246 constexpr auto primitiveRange = enum_range<CompositePrimitive>();
247 constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
248 mPrimitiveDurations.resize(primitiveCount);
249 }
250 auto primitiveIdx = static_cast<size_t>(primitive);
251 if (primitiveIdx >= mPrimitiveDurations.size()) {
252 // Safety check, should not happen if enum_range is correct.
253 return HalResult<milliseconds>::unsupported();
254 }
255 auto& cache = mPrimitiveDurations[primitiveIdx];
256 if (cache.has_value()) {
257 return HalResult<milliseconds>::ok(*cache);
258 }
259 int32_t duration;
260 auto result = getHal()->getPrimitiveDuration(primitive, &duration);
261 if (result.isOk()) {
262 // Cache copy of returned value.
263 cache.emplace(duration);
264 }
265 return HalResult<milliseconds>::fromStatus(result, milliseconds(duration));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100266}
267
Lais Andrade10d9dc72020-05-20 12:00:49 +0000268HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
269 int32_t capabilities = 0;
Lais Andradecfd81152020-07-01 09:00:26 +0000270 auto result = getHal()->getCapabilities(&capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000271 return HalResult<Capabilities>::fromStatus(result, static_cast<Capabilities>(capabilities));
272}
273
274HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
275 std::vector<Effect> supportedEffects;
Lais Andradecfd81152020-07-01 09:00:26 +0000276 auto result = getHal()->getSupportedEffects(&supportedEffects);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000277 return HalResult<std::vector<Effect>>::fromStatus(result, supportedEffects);
278}
279
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000280HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() {
281 std::vector<CompositePrimitive> supportedPrimitives;
282 auto result = getHal()->getSupportedPrimitives(&supportedPrimitives);
283 return HalResult<std::vector<CompositePrimitive>>::fromStatus(result, supportedPrimitives);
284}
285
Lais Andradecfd81152020-07-01 09:00:26 +0000286sp<Aidl::IVibrator> AidlHalWrapper::getHal() {
287 std::lock_guard<std::mutex> lock(mHandleMutex);
288 return mHandle;
289}
290
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100291// -------------------------------------------------------------------------------------------------
292
Lais Andradecfd81152020-07-01 09:00:26 +0000293template <typename I>
294HalResult<void> HidlHalWrapper<I>::ping() {
295 auto result = getHal()->ping();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100296 return HalResult<void>::fromReturn(result);
297}
298
Lais Andradecfd81152020-07-01 09:00:26 +0000299template <typename I>
300void HidlHalWrapper<I>::tryReconnect() {
301 sp<I> newHandle = I::tryGetService();
302 if (newHandle) {
303 std::lock_guard<std::mutex> lock(mHandleMutex);
304 mHandle = std::move(newHandle);
305 }
306}
307
308template <typename I>
309HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
310 const std::function<void()>& completionCallback) {
311 auto result = getHal()->on(timeout.count());
Lais Andrade10d9dc72020-05-20 12:00:49 +0000312 auto ret = HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
313 if (ret.isOk()) {
314 mCallbackScheduler->schedule(completionCallback, timeout);
315 }
316 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100317}
318
Lais Andradecfd81152020-07-01 09:00:26 +0000319template <typename I>
320HalResult<void> HidlHalWrapper<I>::off() {
321 auto result = getHal()->off();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100322 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
323}
324
Lais Andradecfd81152020-07-01 09:00:26 +0000325template <typename I>
326HalResult<void> HidlHalWrapper<I>::setAmplitude(int32_t amplitude) {
327 auto result = getHal()->setAmplitude(static_cast<uint8_t>(amplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100328 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
329}
330
Lais Andradecfd81152020-07-01 09:00:26 +0000331template <typename I>
332HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100333 ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
334 return HalResult<void>::unsupported();
335}
336
Lais Andradecfd81152020-07-01 09:00:26 +0000337template <typename I>
338HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100339 ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
340 return HalResult<void>::unsupported();
341}
342
Lais Andradecfd81152020-07-01 09:00:26 +0000343template <typename I>
344HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100345 ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
346 return HalResult<void>::unsupported();
347}
348
Lais Andradecfd81152020-07-01 09:00:26 +0000349template <typename I>
350HalResult<Capabilities> HidlHalWrapper<I>::getCapabilities() {
Lais Andraded39ff7d2020-05-19 10:42:51 +0000351 std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
Lais Andradecfd81152020-07-01 09:00:26 +0000352 return loadCached<Capabilities>(std::bind(&HidlHalWrapper<I>::getCapabilitiesInternal, this),
Lais Andraded39ff7d2020-05-19 10:42:51 +0000353 mCapabilities);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100354}
355
Lais Andradecfd81152020-07-01 09:00:26 +0000356template <typename I>
357HalResult<std::vector<Effect>> HidlHalWrapper<I>::getSupportedEffects() {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100358 ALOGV("Skipped getSupportedEffects because Vibrator HAL AIDL is not available");
359 return HalResult<std::vector<Effect>>::unsupported();
360}
361
Lais Andradecfd81152020-07-01 09:00:26 +0000362template <typename I>
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000363HalResult<std::vector<CompositePrimitive>> HidlHalWrapper<I>::getSupportedPrimitives() {
364 ALOGV("Skipped getSupportedPrimitives because Vibrator HAL AIDL is not available");
365 return HalResult<std::vector<CompositePrimitive>>::unsupported();
366}
367
368template <typename I>
Lais Andrade49b60b12021-02-23 13:27:41 +0000369HalResult<std::chrono::milliseconds> HidlHalWrapper<I>::performComposedEffect(
370 const std::vector<CompositeEffect>&, const std::function<void()>&) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100371 ALOGV("Skipped composed effect because Vibrator HAL AIDL is not available");
Lais Andrade49b60b12021-02-23 13:27:41 +0000372 return HalResult<std::chrono::milliseconds>::unsupported();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100373}
374
Lais Andradecfd81152020-07-01 09:00:26 +0000375template <typename I>
376HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
377 hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
Lais Andraded39ff7d2020-05-19 10:42:51 +0000378 Capabilities capabilities =
379 result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
380 return HalResult<Capabilities>::fromReturn(result, capabilities);
381}
382
Lais Andradecfd81152020-07-01 09:00:26 +0000383template <typename I>
384template <typename T>
385HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
386 perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
Lais Andrade10d9dc72020-05-20 12:00:49 +0000387 const std::function<void()>& completionCallback) {
388 V1_0::Status status;
389 int32_t lengthMs;
390 auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
391 status = retStatus;
392 lengthMs = retLengthMs;
393 };
394
395 V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
396 auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
397 milliseconds length = milliseconds(lengthMs);
398
399 auto ret = HalResult<milliseconds>::fromReturn(result, status, length);
400 if (ret.isOk()) {
401 mCallbackScheduler->schedule(completionCallback, length);
402 }
403
404 return ret;
405}
406
Lais Andradecfd81152020-07-01 09:00:26 +0000407template <typename I>
408sp<I> HidlHalWrapper<I>::getHal() {
409 std::lock_guard<std::mutex> lock(mHandleMutex);
410 return mHandle;
411}
412
413// -------------------------------------------------------------------------------------------------
414
415HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
Lais Andrade10d9dc72020-05-20 12:00:49 +0000416 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andradecfd81152020-07-01 09:00:26 +0000417 if (isStaticCastValid<V1_0::Effect>(effect)) {
418 return performInternal(&V1_0::IVibrator::perform, getHal(),
419 static_cast<V1_0::Effect>(effect), strength, completionCallback);
420 }
421
422 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
423 Aidl::toString(effect).c_str());
424 return HalResult<milliseconds>::unsupported();
Lais Andrade10d9dc72020-05-20 12:00:49 +0000425}
426
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100427// -------------------------------------------------------------------------------------------------
428
Lais Andrade10d9dc72020-05-20 12:00:49 +0000429HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
430 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100431 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000432 return performInternal(&V1_1::IVibrator::perform, getHal(),
433 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100434 }
435 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000436 return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
437 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100438 }
439
440 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
441 Aidl::toString(effect).c_str());
442 return HalResult<milliseconds>::unsupported();
443}
444
445// -------------------------------------------------------------------------------------------------
446
Lais Andrade10d9dc72020-05-20 12:00:49 +0000447HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
448 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100449 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000450 return performInternal(&V1_2::IVibrator::perform, getHal(),
451 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100452 }
453 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000454 return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
455 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100456 }
457 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000458 return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
459 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100460 }
461
462 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
463 Aidl::toString(effect).c_str());
464 return HalResult<milliseconds>::unsupported();
465}
466
467// -------------------------------------------------------------------------------------------------
468
469HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000470 auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100471 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
472}
473
Lais Andrade10d9dc72020-05-20 12:00:49 +0000474HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
475 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100476 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000477 return performInternal(&V1_3::IVibrator::perform, getHal(),
478 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100479 }
480 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000481 return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
482 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100483 }
484 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000485 return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
486 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100487 }
488 if (isStaticCastValid<V1_3::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000489 return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
490 static_cast<V1_3::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100491 }
492
493 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
494 Aidl::toString(effect).c_str());
495 return HalResult<milliseconds>::unsupported();
496}
497
Lais Andraded39ff7d2020-05-19 10:42:51 +0000498HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
Lais Andrade08666612020-08-07 16:16:31 +0000499 Capabilities capabilities = Capabilities::NONE;
500
Lais Andradecfd81152020-07-01 09:00:26 +0000501 sp<V1_3::IVibrator> hal = getHal();
502 auto amplitudeResult = hal->supportsAmplitudeControl();
503 if (!amplitudeResult.isOk()) {
Lais Andrade08666612020-08-07 16:16:31 +0000504 return HalResult<Capabilities>::fromReturn(amplitudeResult, capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000505 }
506
Lais Andradecfd81152020-07-01 09:00:26 +0000507 auto externalControlResult = hal->supportsExternalControl();
Lais Andradecfd81152020-07-01 09:00:26 +0000508 if (amplitudeResult.withDefault(false)) {
509 capabilities |= Capabilities::AMPLITUDE_CONTROL;
510 }
511 if (externalControlResult.withDefault(false)) {
512 capabilities |= Capabilities::EXTERNAL_CONTROL;
Lais Andrade602ff962020-08-27 12:02:53 +0000513
514 if (amplitudeResult.withDefault(false)) {
515 capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL;
516 }
Lais Andradecfd81152020-07-01 09:00:26 +0000517 }
518
519 return HalResult<Capabilities>::fromReturn(externalControlResult, capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000520}
521
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100522// -------------------------------------------------------------------------------------------------
523
524}; // namespace vibrator
525
526}; // namespace android