blob: 3d20fa1273f484a1f20b0bc864434cc6e7f398da [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
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000208HalResult<float> AidlHalWrapper::getResonantFrequency() {
209 std::lock_guard<std::mutex> lock(mResonantFrequencyMutex);
210 return loadCached<float>(std::bind(&AidlHalWrapper::getResonantFrequencyInternal, this),
211 mResonantFrequency);
212}
213
214HalResult<float> AidlHalWrapper::getQFactor() {
215 std::lock_guard<std::mutex> lock(mQFactorMutex);
216 return loadCached<float>(std::bind(&AidlHalWrapper::getQFactorInternal, this), mQFactor);
217}
218
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100219HalResult<milliseconds> AidlHalWrapper::performEffect(
220 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000221 HalResult<Capabilities> capabilities = getCapabilities();
222 bool supportsCallback = capabilities.isOk() &&
223 static_cast<int32_t>(capabilities.value() & Capabilities::PERFORM_CALLBACK);
224 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
225
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100226 int32_t lengthMs;
Lais Andradecfd81152020-07-01 09:00:26 +0000227 auto result = getHal()->perform(effect, strength, cb, &lengthMs);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000228 milliseconds length = milliseconds(lengthMs);
229
230 auto ret = HalResult<milliseconds>::fromStatus(result, length);
231 if (!supportsCallback && ret.isOk()) {
232 mCallbackScheduler->schedule(completionCallback, length);
233 }
234
235 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100236}
237
Lais Andrade49b60b12021-02-23 13:27:41 +0000238HalResult<milliseconds> AidlHalWrapper::performComposedEffect(
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100239 const std::vector<CompositeEffect>& primitiveEffects,
240 const std::function<void()>& completionCallback) {
Lais Andrade10d9dc72020-05-20 12:00:49 +0000241 // This method should always support callbacks, so no need to double check.
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100242 auto cb = new HalCallbackWrapper(completionCallback);
Lais Andrade49b60b12021-02-23 13:27:41 +0000243 milliseconds duration(0);
244 for (const auto& effect : primitiveEffects) {
245 auto durationResult = getPrimitiveDuration(effect.primitive);
246 if (durationResult.isOk()) {
247 duration += durationResult.value();
248 }
249 duration += milliseconds(effect.delayMs);
250 }
251 return HalResult<milliseconds>::fromStatus(getHal()->compose(primitiveEffects, cb), duration);
252}
253
254HalResult<milliseconds> AidlHalWrapper::getPrimitiveDuration(CompositePrimitive primitive) {
255 std::lock_guard<std::mutex> lock(mSupportedPrimitivesMutex);
256 if (mPrimitiveDurations.empty()) {
257 constexpr auto primitiveRange = enum_range<CompositePrimitive>();
258 constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
259 mPrimitiveDurations.resize(primitiveCount);
260 }
261 auto primitiveIdx = static_cast<size_t>(primitive);
262 if (primitiveIdx >= mPrimitiveDurations.size()) {
263 // Safety check, should not happen if enum_range is correct.
264 return HalResult<milliseconds>::unsupported();
265 }
266 auto& cache = mPrimitiveDurations[primitiveIdx];
267 if (cache.has_value()) {
268 return HalResult<milliseconds>::ok(*cache);
269 }
270 int32_t duration;
271 auto result = getHal()->getPrimitiveDuration(primitive, &duration);
272 if (result.isOk()) {
273 // Cache copy of returned value.
274 cache.emplace(duration);
275 }
276 return HalResult<milliseconds>::fromStatus(result, milliseconds(duration));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100277}
278
Lais Andrade10d9dc72020-05-20 12:00:49 +0000279HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
280 int32_t capabilities = 0;
Lais Andradecfd81152020-07-01 09:00:26 +0000281 auto result = getHal()->getCapabilities(&capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000282 return HalResult<Capabilities>::fromStatus(result, static_cast<Capabilities>(capabilities));
283}
284
285HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
286 std::vector<Effect> supportedEffects;
Lais Andradecfd81152020-07-01 09:00:26 +0000287 auto result = getHal()->getSupportedEffects(&supportedEffects);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000288 return HalResult<std::vector<Effect>>::fromStatus(result, supportedEffects);
289}
290
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000291HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() {
292 std::vector<CompositePrimitive> supportedPrimitives;
293 auto result = getHal()->getSupportedPrimitives(&supportedPrimitives);
294 return HalResult<std::vector<CompositePrimitive>>::fromStatus(result, supportedPrimitives);
295}
296
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000297HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() {
298 float f0 = 0;
299 auto result = getHal()->getResonantFrequency(&f0);
300 return HalResult<float>::fromStatus(result, f0);
301}
302
303HalResult<float> AidlHalWrapper::getQFactorInternal() {
304 float qFactor = 0;
305 auto result = getHal()->getQFactor(&qFactor);
306 return HalResult<float>::fromStatus(result, qFactor);
307}
308
Lais Andradecfd81152020-07-01 09:00:26 +0000309sp<Aidl::IVibrator> AidlHalWrapper::getHal() {
310 std::lock_guard<std::mutex> lock(mHandleMutex);
311 return mHandle;
312}
313
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100314// -------------------------------------------------------------------------------------------------
315
Lais Andradecfd81152020-07-01 09:00:26 +0000316template <typename I>
317HalResult<void> HidlHalWrapper<I>::ping() {
318 auto result = getHal()->ping();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100319 return HalResult<void>::fromReturn(result);
320}
321
Lais Andradecfd81152020-07-01 09:00:26 +0000322template <typename I>
323void HidlHalWrapper<I>::tryReconnect() {
324 sp<I> newHandle = I::tryGetService();
325 if (newHandle) {
326 std::lock_guard<std::mutex> lock(mHandleMutex);
327 mHandle = std::move(newHandle);
328 }
329}
330
331template <typename I>
332HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
333 const std::function<void()>& completionCallback) {
334 auto result = getHal()->on(timeout.count());
Lais Andrade10d9dc72020-05-20 12:00:49 +0000335 auto ret = HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
336 if (ret.isOk()) {
337 mCallbackScheduler->schedule(completionCallback, timeout);
338 }
339 return ret;
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100340}
341
Lais Andradecfd81152020-07-01 09:00:26 +0000342template <typename I>
343HalResult<void> HidlHalWrapper<I>::off() {
344 auto result = getHal()->off();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100345 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
346}
347
Lais Andradecfd81152020-07-01 09:00:26 +0000348template <typename I>
349HalResult<void> HidlHalWrapper<I>::setAmplitude(int32_t amplitude) {
350 auto result = getHal()->setAmplitude(static_cast<uint8_t>(amplitude));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100351 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
352}
353
Lais Andradecfd81152020-07-01 09:00:26 +0000354template <typename I>
355HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100356 ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
357 return HalResult<void>::unsupported();
358}
359
Lais Andradecfd81152020-07-01 09:00:26 +0000360template <typename I>
361HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100362 ALOGV("Skipped alwaysOnEnable 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<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100368 ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
369 return HalResult<void>::unsupported();
370}
371
Lais Andradecfd81152020-07-01 09:00:26 +0000372template <typename I>
373HalResult<Capabilities> HidlHalWrapper<I>::getCapabilities() {
Lais Andraded39ff7d2020-05-19 10:42:51 +0000374 std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
Lais Andradecfd81152020-07-01 09:00:26 +0000375 return loadCached<Capabilities>(std::bind(&HidlHalWrapper<I>::getCapabilitiesInternal, this),
Lais Andraded39ff7d2020-05-19 10:42:51 +0000376 mCapabilities);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100377}
378
Lais Andradecfd81152020-07-01 09:00:26 +0000379template <typename I>
380HalResult<std::vector<Effect>> HidlHalWrapper<I>::getSupportedEffects() {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100381 ALOGV("Skipped getSupportedEffects because Vibrator HAL AIDL is not available");
382 return HalResult<std::vector<Effect>>::unsupported();
383}
384
Lais Andradecfd81152020-07-01 09:00:26 +0000385template <typename I>
Lais Andrade07f9c0e2020-08-11 16:22:12 +0000386HalResult<std::vector<CompositePrimitive>> HidlHalWrapper<I>::getSupportedPrimitives() {
387 ALOGV("Skipped getSupportedPrimitives because Vibrator HAL AIDL is not available");
388 return HalResult<std::vector<CompositePrimitive>>::unsupported();
389}
390
391template <typename I>
Michael Wrightba9a6ce2021-02-26 02:55:29 +0000392HalResult<float> HidlHalWrapper<I>::getResonantFrequency() {
393 ALOGV("Skipped getResonantFrequency because Vibrator HAL AIDL is not available");
394 return HalResult<float>::unsupported();
395}
396
397template <typename I>
398HalResult<float> HidlHalWrapper<I>::getQFactor() {
399 ALOGV("Skipped getQFactor because Vibrator HAL AIDL is not available");
400 return HalResult<float>::unsupported();
401}
402
403template <typename I>
Lais Andrade49b60b12021-02-23 13:27:41 +0000404HalResult<std::chrono::milliseconds> HidlHalWrapper<I>::performComposedEffect(
405 const std::vector<CompositeEffect>&, const std::function<void()>&) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100406 ALOGV("Skipped composed effect because Vibrator HAL AIDL is not available");
Lais Andrade49b60b12021-02-23 13:27:41 +0000407 return HalResult<std::chrono::milliseconds>::unsupported();
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100408}
409
Lais Andradecfd81152020-07-01 09:00:26 +0000410template <typename I>
411HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
412 hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
Lais Andraded39ff7d2020-05-19 10:42:51 +0000413 Capabilities capabilities =
414 result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
415 return HalResult<Capabilities>::fromReturn(result, capabilities);
416}
417
Lais Andradecfd81152020-07-01 09:00:26 +0000418template <typename I>
419template <typename T>
420HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
421 perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
Lais Andrade10d9dc72020-05-20 12:00:49 +0000422 const std::function<void()>& completionCallback) {
423 V1_0::Status status;
424 int32_t lengthMs;
425 auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) {
426 status = retStatus;
427 lengthMs = retLengthMs;
428 };
429
430 V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength);
431 auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
432 milliseconds length = milliseconds(lengthMs);
433
434 auto ret = HalResult<milliseconds>::fromReturn(result, status, length);
435 if (ret.isOk()) {
436 mCallbackScheduler->schedule(completionCallback, length);
437 }
438
439 return ret;
440}
441
Lais Andradecfd81152020-07-01 09:00:26 +0000442template <typename I>
443sp<I> HidlHalWrapper<I>::getHal() {
444 std::lock_guard<std::mutex> lock(mHandleMutex);
445 return mHandle;
446}
447
448// -------------------------------------------------------------------------------------------------
449
450HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
Lais Andrade10d9dc72020-05-20 12:00:49 +0000451 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andradecfd81152020-07-01 09:00:26 +0000452 if (isStaticCastValid<V1_0::Effect>(effect)) {
453 return performInternal(&V1_0::IVibrator::perform, getHal(),
454 static_cast<V1_0::Effect>(effect), strength, completionCallback);
455 }
456
457 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
458 Aidl::toString(effect).c_str());
459 return HalResult<milliseconds>::unsupported();
Lais Andrade10d9dc72020-05-20 12:00:49 +0000460}
461
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100462// -------------------------------------------------------------------------------------------------
463
Lais Andrade10d9dc72020-05-20 12:00:49 +0000464HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
465 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100466 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000467 return performInternal(&V1_1::IVibrator::perform, getHal(),
468 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100469 }
470 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000471 return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
472 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100473 }
474
475 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
476 Aidl::toString(effect).c_str());
477 return HalResult<milliseconds>::unsupported();
478}
479
480// -------------------------------------------------------------------------------------------------
481
Lais Andrade10d9dc72020-05-20 12:00:49 +0000482HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
483 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100484 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000485 return performInternal(&V1_2::IVibrator::perform, getHal(),
486 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100487 }
488 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000489 return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
490 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100491 }
492 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000493 return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
494 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100495 }
496
497 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
498 Aidl::toString(effect).c_str());
499 return HalResult<milliseconds>::unsupported();
500}
501
502// -------------------------------------------------------------------------------------------------
503
504HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
Lais Andradecfd81152020-07-01 09:00:26 +0000505 auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100506 return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
507}
508
Lais Andrade10d9dc72020-05-20 12:00:49 +0000509HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
510 Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100511 if (isStaticCastValid<V1_0::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000512 return performInternal(&V1_3::IVibrator::perform, getHal(),
513 static_cast<V1_0::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100514 }
515 if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000516 return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
517 static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100518 }
519 if (isStaticCastValid<V1_2::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000520 return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
521 static_cast<V1_2::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100522 }
523 if (isStaticCastValid<V1_3::Effect>(effect)) {
Lais Andradecfd81152020-07-01 09:00:26 +0000524 return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
525 static_cast<V1_3::Effect>(effect), strength, completionCallback);
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100526 }
527
528 ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
529 Aidl::toString(effect).c_str());
530 return HalResult<milliseconds>::unsupported();
531}
532
Lais Andraded39ff7d2020-05-19 10:42:51 +0000533HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
Lais Andrade08666612020-08-07 16:16:31 +0000534 Capabilities capabilities = Capabilities::NONE;
535
Lais Andradecfd81152020-07-01 09:00:26 +0000536 sp<V1_3::IVibrator> hal = getHal();
537 auto amplitudeResult = hal->supportsAmplitudeControl();
538 if (!amplitudeResult.isOk()) {
Lais Andrade08666612020-08-07 16:16:31 +0000539 return HalResult<Capabilities>::fromReturn(amplitudeResult, capabilities);
Lais Andraded39ff7d2020-05-19 10:42:51 +0000540 }
541
Lais Andradecfd81152020-07-01 09:00:26 +0000542 auto externalControlResult = hal->supportsExternalControl();
Lais Andradecfd81152020-07-01 09:00:26 +0000543 if (amplitudeResult.withDefault(false)) {
544 capabilities |= Capabilities::AMPLITUDE_CONTROL;
545 }
546 if (externalControlResult.withDefault(false)) {
547 capabilities |= Capabilities::EXTERNAL_CONTROL;
Lais Andrade602ff962020-08-27 12:02:53 +0000548
549 if (amplitudeResult.withDefault(false)) {
550 capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL;
551 }
Lais Andradecfd81152020-07-01 09:00:26 +0000552 }
553
554 return HalResult<Capabilities>::fromReturn(externalControlResult, capabilities);
Lais Andrade10d9dc72020-05-20 12:00:49 +0000555}
556
Lais Andrade9e9fcc92020-04-07 20:13:08 +0100557// -------------------------------------------------------------------------------------------------
558
559}; // namespace vibrator
560
561}; // namespace android