• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 #ifndef ANDROID_OS_VIBRATORHALWRAPPER_H
18 #define ANDROID_OS_VIBRATORHALWRAPPER_H
19 
20 #include <android-base/thread_annotations.h>
21 #include <android/hardware/vibrator/1.3/IVibrator.h>
22 #include <android/hardware/vibrator/BnVibratorCallback.h>
23 #include <android/hardware/vibrator/IVibrator.h>
24 #include <binder/IServiceManager.h>
25 
26 #include <vibratorservice/VibratorCallbackScheduler.h>
27 
28 namespace android {
29 
30 namespace vibrator {
31 
32 // -------------------------------------------------------------------------------------------------
33 
34 // Result of a call to the Vibrator HAL wrapper, holding data if successful.
35 template <typename T>
36 class HalResult {
37 public:
ok(T value)38     static HalResult<T> ok(T value) { return HalResult(value); }
failed(std::string msg)39     static HalResult<T> failed(std::string msg) {
40         return HalResult(std::move(msg), /* unsupported= */ false);
41     }
unsupported()42     static HalResult<T> unsupported() { return HalResult("", /* unsupported= */ true); }
43 
fromStatus(binder::Status status,T data)44     static HalResult<T> fromStatus(binder::Status status, T data) {
45         if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION ||
46             status.transactionError() == android::UNKNOWN_TRANSACTION) {
47             // UNKNOWN_TRANSACTION means the HAL implementation is an older version, so this is
48             // the same as the operation being unsupported by this HAL. Should not retry.
49             return HalResult<T>::unsupported();
50         }
51         if (status.isOk()) {
52             return HalResult<T>::ok(data);
53         }
54         return HalResult<T>::failed(status.toString8().c_str());
55     }
56     static HalResult<T> fromStatus(hardware::vibrator::V1_0::Status status, T data);
57 
58     template <typename R>
59     static HalResult<T> fromReturn(hardware::Return<R>& ret, T data);
60 
61     template <typename R>
62     static HalResult<T> fromReturn(hardware::Return<R>& ret,
63                                    hardware::vibrator::V1_0::Status status, T data);
64 
65     // This will throw std::bad_optional_access if this result is not ok.
value()66     const T& value() const { return mValue.value(); }
valueOr(T && defaultValue)67     const T valueOr(T&& defaultValue) const { return mValue.value_or(defaultValue); }
isOk()68     bool isOk() const { return !mUnsupported && mValue.has_value(); }
isFailed()69     bool isFailed() const { return !mUnsupported && !mValue.has_value(); }
isUnsupported()70     bool isUnsupported() const { return mUnsupported; }
errorMessage()71     const char* errorMessage() const { return mErrorMessage.c_str(); }
checkAndLogFailure(const char * functionName)72     bool checkAndLogFailure(const char* functionName) const {
73         if (isFailed()) {
74             ALOGE("%s failed: %s", functionName, errorMessage());
75             return true;
76         }
77         return false;
78     }
79 
80 private:
81     std::optional<T> mValue;
82     std::string mErrorMessage;
83     bool mUnsupported;
84 
HalResult(T value)85     explicit HalResult(T value)
86           : mValue(std::make_optional(value)), mErrorMessage(), mUnsupported(false) {}
HalResult(std::string errorMessage,bool unsupported)87     explicit HalResult(std::string errorMessage, bool unsupported)
88           : mValue(), mErrorMessage(std::move(errorMessage)), mUnsupported(unsupported) {}
89 };
90 
91 // Empty result of a call to the Vibrator HAL wrapper.
92 template <>
93 class HalResult<void> {
94 public:
ok()95     static HalResult<void> ok() { return HalResult(); }
failed(std::string msg)96     static HalResult<void> failed(std::string msg) { return HalResult(std::move(msg)); }
unsupported()97     static HalResult<void> unsupported() { return HalResult(/* unsupported= */ true); }
98 
99     static HalResult<void> fromStatus(status_t status);
100     static HalResult<void> fromStatus(binder::Status status);
101     static HalResult<void> fromStatus(hardware::vibrator::V1_0::Status status);
102 
103     template <typename R>
104     static HalResult<void> fromReturn(hardware::Return<R>& ret);
105 
isOk()106     bool isOk() const { return !mUnsupported && !mFailed; }
isFailed()107     bool isFailed() const { return !mUnsupported && mFailed; }
isUnsupported()108     bool isUnsupported() const { return mUnsupported; }
errorMessage()109     const char* errorMessage() const { return mErrorMessage.c_str(); }
checkAndLogFailure(const char * functionName)110     bool checkAndLogFailure(const char* functionName) const {
111         if (isFailed()) {
112             ALOGE("%s failed: %s", functionName, errorMessage());
113             return true;
114         }
115         return false;
116     }
117 
118 private:
119     std::string mErrorMessage;
120     bool mFailed;
121     bool mUnsupported;
122 
123     explicit HalResult(bool unsupported = false)
mErrorMessage()124           : mErrorMessage(), mFailed(false), mUnsupported(unsupported) {}
HalResult(std::string errorMessage)125     explicit HalResult(std::string errorMessage)
126           : mErrorMessage(std::move(errorMessage)), mFailed(true), mUnsupported(false) {}
127 };
128 
129 class HalCallbackWrapper : public hardware::vibrator::BnVibratorCallback {
130 public:
HalCallbackWrapper(std::function<void ()> completionCallback)131     HalCallbackWrapper(std::function<void()> completionCallback)
132           : mCompletionCallback(completionCallback) {}
133 
onComplete()134     binder::Status onComplete() override {
135         mCompletionCallback();
136         return binder::Status::ok();
137     }
138 
139 private:
140     const std::function<void()> mCompletionCallback;
141 };
142 
143 // -------------------------------------------------------------------------------------------------
144 
145 // Vibrator HAL capabilities.
146 enum class Capabilities : int32_t {
147     NONE = 0,
148     ON_CALLBACK = hardware::vibrator::IVibrator::CAP_ON_CALLBACK,
149     PERFORM_CALLBACK = hardware::vibrator::IVibrator::CAP_PERFORM_CALLBACK,
150     AMPLITUDE_CONTROL = hardware::vibrator::IVibrator::CAP_AMPLITUDE_CONTROL,
151     EXTERNAL_CONTROL = hardware::vibrator::IVibrator::CAP_EXTERNAL_CONTROL,
152     EXTERNAL_AMPLITUDE_CONTROL = hardware::vibrator::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL,
153     COMPOSE_EFFECTS = hardware::vibrator::IVibrator::CAP_COMPOSE_EFFECTS,
154     COMPOSE_PWLE_EFFECTS = hardware::vibrator::IVibrator::CAP_COMPOSE_PWLE_EFFECTS,
155     ALWAYS_ON_CONTROL = hardware::vibrator::IVibrator::CAP_ALWAYS_ON_CONTROL,
156 };
157 
158 inline Capabilities operator|(Capabilities lhs, Capabilities rhs) {
159     using underlying = typename std::underlying_type<Capabilities>::type;
160     return static_cast<Capabilities>(static_cast<underlying>(lhs) | static_cast<underlying>(rhs));
161 }
162 
163 inline Capabilities& operator|=(Capabilities& lhs, Capabilities rhs) {
164     return lhs = lhs | rhs;
165 }
166 
167 inline Capabilities operator&(Capabilities lhs, Capabilities rhs) {
168     using underlying = typename std::underlying_type<Capabilities>::type;
169     return static_cast<Capabilities>(static_cast<underlying>(lhs) & static_cast<underlying>(rhs));
170 }
171 
172 inline Capabilities& operator&=(Capabilities& lhs, Capabilities rhs) {
173     return lhs = lhs & rhs;
174 }
175 
176 // -------------------------------------------------------------------------------------------------
177 
178 class Info {
179 public:
180     const HalResult<Capabilities> capabilities;
181     const HalResult<std::vector<hardware::vibrator::Effect>> supportedEffects;
182     const HalResult<std::vector<hardware::vibrator::Braking>> supportedBraking;
183     const HalResult<std::vector<hardware::vibrator::CompositePrimitive>> supportedPrimitives;
184     const HalResult<std::vector<std::chrono::milliseconds>> primitiveDurations;
185     const HalResult<std::chrono::milliseconds> primitiveDelayMax;
186     const HalResult<std::chrono::milliseconds> pwlePrimitiveDurationMax;
187     const HalResult<int32_t> compositionSizeMax;
188     const HalResult<int32_t> pwleSizeMax;
189     const HalResult<float> minFrequency;
190     const HalResult<float> resonantFrequency;
191     const HalResult<float> frequencyResolution;
192     const HalResult<float> qFactor;
193     const HalResult<std::vector<float>> maxAmplitudes;
194 
checkAndLogFailure(const char *)195     bool checkAndLogFailure(const char*) const {
196         return capabilities.checkAndLogFailure("getCapabilities") ||
197                 supportedEffects.checkAndLogFailure("getSupportedEffects") ||
198                 supportedBraking.checkAndLogFailure("getSupportedBraking") ||
199                 supportedPrimitives.checkAndLogFailure("getSupportedPrimitives") ||
200                 primitiveDurations.checkAndLogFailure("getPrimitiveDuration") ||
201                 primitiveDelayMax.checkAndLogFailure("getPrimitiveDelayMax") ||
202                 pwlePrimitiveDurationMax.checkAndLogFailure("getPwlePrimitiveDurationMax") ||
203                 compositionSizeMax.checkAndLogFailure("getCompositionSizeMax") ||
204                 pwleSizeMax.checkAndLogFailure("getPwleSizeMax") ||
205                 minFrequency.checkAndLogFailure("getMinFrequency") ||
206                 resonantFrequency.checkAndLogFailure("getResonantFrequency") ||
207                 frequencyResolution.checkAndLogFailure("getFrequencyResolution") ||
208                 qFactor.checkAndLogFailure("getQFactor") ||
209                 maxAmplitudes.checkAndLogFailure("getMaxAmplitudes");
210     }
211 };
212 
213 class InfoCache {
214 public:
get()215     Info get() {
216         return {mCapabilities,
217                 mSupportedEffects,
218                 mSupportedBraking,
219                 mSupportedPrimitives,
220                 mPrimitiveDurations,
221                 mPrimitiveDelayMax,
222                 mPwlePrimitiveDurationMax,
223                 mCompositionSizeMax,
224                 mPwleSizeMax,
225                 mMinFrequency,
226                 mResonantFrequency,
227                 mFrequencyResolution,
228                 mQFactor,
229                 mMaxAmplitudes};
230     }
231 
232 private:
233     static const constexpr char* MSG = "never loaded";
234     HalResult<Capabilities> mCapabilities = HalResult<Capabilities>::failed(MSG);
235     HalResult<std::vector<hardware::vibrator::Effect>> mSupportedEffects =
236             HalResult<std::vector<hardware::vibrator::Effect>>::failed(MSG);
237     HalResult<std::vector<hardware::vibrator::Braking>> mSupportedBraking =
238             HalResult<std::vector<hardware::vibrator::Braking>>::failed(MSG);
239     HalResult<std::vector<hardware::vibrator::CompositePrimitive>> mSupportedPrimitives =
240             HalResult<std::vector<hardware::vibrator::CompositePrimitive>>::failed(MSG);
241     HalResult<std::vector<std::chrono::milliseconds>> mPrimitiveDurations =
242             HalResult<std::vector<std::chrono::milliseconds>>::failed(MSG);
243     HalResult<std::chrono::milliseconds> mPrimitiveDelayMax =
244             HalResult<std::chrono::milliseconds>::failed(MSG);
245     HalResult<std::chrono::milliseconds> mPwlePrimitiveDurationMax =
246             HalResult<std::chrono::milliseconds>::failed(MSG);
247     HalResult<int32_t> mCompositionSizeMax = HalResult<int>::failed(MSG);
248     HalResult<int32_t> mPwleSizeMax = HalResult<int>::failed(MSG);
249     HalResult<float> mMinFrequency = HalResult<float>::failed(MSG);
250     HalResult<float> mResonantFrequency = HalResult<float>::failed(MSG);
251     HalResult<float> mFrequencyResolution = HalResult<float>::failed(MSG);
252     HalResult<float> mQFactor = HalResult<float>::failed(MSG);
253     HalResult<std::vector<float>> mMaxAmplitudes = HalResult<std::vector<float>>::failed(MSG);
254 
255     friend class HalWrapper;
256 };
257 
258 // Wrapper for Vibrator HAL handlers.
259 class HalWrapper {
260 public:
HalWrapper(std::shared_ptr<CallbackScheduler> scheduler)261     explicit HalWrapper(std::shared_ptr<CallbackScheduler> scheduler)
262           : mCallbackScheduler(std::move(scheduler)) {}
263     virtual ~HalWrapper() = default;
264 
265     /* reloads wrapped HAL service instance without waiting. This can be used to reconnect when the
266      * service restarts, to rapidly retry after a failure.
267      */
268     virtual void tryReconnect() = 0;
269 
270     Info getInfo();
271 
272     virtual HalResult<void> ping() = 0;
273     virtual HalResult<void> on(std::chrono::milliseconds timeout,
274                                const std::function<void()>& completionCallback) = 0;
275     virtual HalResult<void> off() = 0;
276 
277     virtual HalResult<void> setAmplitude(float amplitude) = 0;
278     virtual HalResult<void> setExternalControl(bool enabled) = 0;
279 
280     virtual HalResult<void> alwaysOnEnable(int32_t id, hardware::vibrator::Effect effect,
281                                            hardware::vibrator::EffectStrength strength) = 0;
282     virtual HalResult<void> alwaysOnDisable(int32_t id) = 0;
283 
284     virtual HalResult<std::chrono::milliseconds> performEffect(
285             hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength,
286             const std::function<void()>& completionCallback) = 0;
287 
288     virtual HalResult<std::chrono::milliseconds> performComposedEffect(
289             const std::vector<hardware::vibrator::CompositeEffect>& primitives,
290             const std::function<void()>& completionCallback);
291 
292     virtual HalResult<void> performPwleEffect(
293             const std::vector<hardware::vibrator::PrimitivePwle>& primitives,
294             const std::function<void()>& completionCallback);
295 
296 protected:
297     // Shared pointer to allow CallbackScheduler to outlive this wrapper.
298     const std::shared_ptr<CallbackScheduler> mCallbackScheduler;
299 
300     // Load and cache vibrator info, returning cached result is present.
301     HalResult<Capabilities> getCapabilities();
302     HalResult<std::vector<std::chrono::milliseconds>> getPrimitiveDurations();
303 
304     // Request vibrator info to HAL skipping cache.
305     virtual HalResult<Capabilities> getCapabilitiesInternal() = 0;
306     virtual HalResult<std::vector<hardware::vibrator::Effect>> getSupportedEffectsInternal();
307     virtual HalResult<std::vector<hardware::vibrator::Braking>> getSupportedBrakingInternal();
308     virtual HalResult<std::vector<hardware::vibrator::CompositePrimitive>>
309     getSupportedPrimitivesInternal();
310     virtual HalResult<std::vector<std::chrono::milliseconds>> getPrimitiveDurationsInternal(
311             const std::vector<hardware::vibrator::CompositePrimitive>& supportedPrimitives);
312     virtual HalResult<std::chrono::milliseconds> getPrimitiveDelayMaxInternal();
313     virtual HalResult<std::chrono::milliseconds> getPrimitiveDurationMaxInternal();
314     virtual HalResult<int32_t> getCompositionSizeMaxInternal();
315     virtual HalResult<int32_t> getPwleSizeMaxInternal();
316     virtual HalResult<float> getMinFrequencyInternal();
317     virtual HalResult<float> getResonantFrequencyInternal();
318     virtual HalResult<float> getFrequencyResolutionInternal();
319     virtual HalResult<float> getQFactorInternal();
320     virtual HalResult<std::vector<float>> getMaxAmplitudesInternal();
321 
322 private:
323     std::mutex mInfoMutex;
324     InfoCache mInfoCache GUARDED_BY(mInfoMutex);
325 };
326 
327 // Wrapper for the AIDL Vibrator HAL.
328 class AidlHalWrapper : public HalWrapper {
329 public:
330     AidlHalWrapper(
331             std::shared_ptr<CallbackScheduler> scheduler, sp<hardware::vibrator::IVibrator> handle,
332             std::function<HalResult<sp<hardware::vibrator::IVibrator>>()> reconnectFn =
333                     []() {
334                         return HalResult<sp<hardware::vibrator::IVibrator>>::ok(
335                                 checkVintfService<hardware::vibrator::IVibrator>());
336                     })
HalWrapper(std::move (scheduler))337           : HalWrapper(std::move(scheduler)),
338             mReconnectFn(reconnectFn),
339             mHandle(std::move(handle)) {}
340     virtual ~AidlHalWrapper() = default;
341 
342     HalResult<void> ping() override final;
343     void tryReconnect() override final;
344 
345     HalResult<void> on(std::chrono::milliseconds timeout,
346                        const std::function<void()>& completionCallback) override final;
347     HalResult<void> off() override final;
348 
349     HalResult<void> setAmplitude(float amplitude) override final;
350     HalResult<void> setExternalControl(bool enabled) override final;
351 
352     HalResult<void> alwaysOnEnable(int32_t id, hardware::vibrator::Effect effect,
353                                    hardware::vibrator::EffectStrength strength) override final;
354     HalResult<void> alwaysOnDisable(int32_t id) override final;
355 
356     HalResult<std::chrono::milliseconds> performEffect(
357             hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength,
358             const std::function<void()>& completionCallback) override final;
359 
360     HalResult<std::chrono::milliseconds> performComposedEffect(
361             const std::vector<hardware::vibrator::CompositeEffect>& primitives,
362             const std::function<void()>& completionCallback) override final;
363 
364     HalResult<void> performPwleEffect(
365             const std::vector<hardware::vibrator::PrimitivePwle>& primitives,
366             const std::function<void()>& completionCallback) override final;
367 
368 protected:
369     HalResult<Capabilities> getCapabilitiesInternal() override final;
370     HalResult<std::vector<hardware::vibrator::Effect>> getSupportedEffectsInternal() override final;
371     HalResult<std::vector<hardware::vibrator::Braking>> getSupportedBrakingInternal()
372             override final;
373     HalResult<std::vector<hardware::vibrator::CompositePrimitive>> getSupportedPrimitivesInternal()
374             override final;
375     HalResult<std::vector<std::chrono::milliseconds>> getPrimitiveDurationsInternal(
376             const std::vector<hardware::vibrator::CompositePrimitive>& supportedPrimitives)
377             override final;
378     HalResult<std::chrono::milliseconds> getPrimitiveDelayMaxInternal() override final;
379     HalResult<std::chrono::milliseconds> getPrimitiveDurationMaxInternal() override final;
380     HalResult<int32_t> getCompositionSizeMaxInternal() override final;
381     HalResult<int32_t> getPwleSizeMaxInternal() override final;
382     HalResult<float> getMinFrequencyInternal() override final;
383     HalResult<float> getResonantFrequencyInternal() override final;
384     HalResult<float> getFrequencyResolutionInternal() override final;
385     HalResult<float> getQFactorInternal() override final;
386     HalResult<std::vector<float>> getMaxAmplitudesInternal() override final;
387 
388 private:
389     const std::function<HalResult<sp<hardware::vibrator::IVibrator>>()> mReconnectFn;
390     std::mutex mHandleMutex;
391     sp<hardware::vibrator::IVibrator> mHandle GUARDED_BY(mHandleMutex);
392 
393     sp<hardware::vibrator::IVibrator> getHal();
394 };
395 
396 // Wrapper for the HDIL Vibrator HALs.
397 template <typename I>
398 class HidlHalWrapper : public HalWrapper {
399 public:
HidlHalWrapper(std::shared_ptr<CallbackScheduler> scheduler,sp<I> handle)400     HidlHalWrapper(std::shared_ptr<CallbackScheduler> scheduler, sp<I> handle)
401           : HalWrapper(std::move(scheduler)), mHandle(std::move(handle)) {}
402     virtual ~HidlHalWrapper() = default;
403 
404     HalResult<void> ping() override final;
405     void tryReconnect() override final;
406 
407     HalResult<void> on(std::chrono::milliseconds timeout,
408                        const std::function<void()>& completionCallback) override final;
409     HalResult<void> off() override final;
410 
411     HalResult<void> setAmplitude(float amplitude) override final;
412     virtual HalResult<void> setExternalControl(bool enabled) override;
413 
414     HalResult<void> alwaysOnEnable(int32_t id, hardware::vibrator::Effect effect,
415                                    hardware::vibrator::EffectStrength strength) override final;
416     HalResult<void> alwaysOnDisable(int32_t id) override final;
417 
418 protected:
419     std::mutex mHandleMutex;
420     sp<I> mHandle GUARDED_BY(mHandleMutex);
421 
422     virtual HalResult<Capabilities> getCapabilitiesInternal() override;
423 
424     template <class T>
425     using perform_fn =
426             hardware::Return<void> (I::*)(T, hardware::vibrator::V1_0::EffectStrength,
427                                           hardware::vibrator::V1_0::IVibrator::perform_cb);
428 
429     template <class T>
430     HalResult<std::chrono::milliseconds> performInternal(
431             perform_fn<T> performFn, sp<I> handle, T effect,
432             hardware::vibrator::EffectStrength strength,
433             const std::function<void()>& completionCallback);
434 
435     sp<I> getHal();
436 };
437 
438 // Wrapper for the HDIL Vibrator HAL v1.0.
439 class HidlHalWrapperV1_0 : public HidlHalWrapper<hardware::vibrator::V1_0::IVibrator> {
440 public:
HidlHalWrapperV1_0(std::shared_ptr<CallbackScheduler> scheduler,sp<hardware::vibrator::V1_0::IVibrator> handle)441     HidlHalWrapperV1_0(std::shared_ptr<CallbackScheduler> scheduler,
442                        sp<hardware::vibrator::V1_0::IVibrator> handle)
443           : HidlHalWrapper<hardware::vibrator::V1_0::IVibrator>(std::move(scheduler),
444                                                                 std::move(handle)) {}
445     virtual ~HidlHalWrapperV1_0() = default;
446 
447     HalResult<std::chrono::milliseconds> performEffect(
448             hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength,
449             const std::function<void()>& completionCallback) override final;
450 };
451 
452 // Wrapper for the HDIL Vibrator HAL v1.1.
453 class HidlHalWrapperV1_1 : public HidlHalWrapper<hardware::vibrator::V1_1::IVibrator> {
454 public:
HidlHalWrapperV1_1(std::shared_ptr<CallbackScheduler> scheduler,sp<hardware::vibrator::V1_1::IVibrator> handle)455     HidlHalWrapperV1_1(std::shared_ptr<CallbackScheduler> scheduler,
456                        sp<hardware::vibrator::V1_1::IVibrator> handle)
457           : HidlHalWrapper<hardware::vibrator::V1_1::IVibrator>(std::move(scheduler),
458                                                                 std::move(handle)) {}
459     virtual ~HidlHalWrapperV1_1() = default;
460 
461     HalResult<std::chrono::milliseconds> performEffect(
462             hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength,
463             const std::function<void()>& completionCallback) override final;
464 };
465 
466 // Wrapper for the HDIL Vibrator HAL v1.2.
467 class HidlHalWrapperV1_2 : public HidlHalWrapper<hardware::vibrator::V1_2::IVibrator> {
468 public:
HidlHalWrapperV1_2(std::shared_ptr<CallbackScheduler> scheduler,sp<hardware::vibrator::V1_2::IVibrator> handle)469     HidlHalWrapperV1_2(std::shared_ptr<CallbackScheduler> scheduler,
470                        sp<hardware::vibrator::V1_2::IVibrator> handle)
471           : HidlHalWrapper<hardware::vibrator::V1_2::IVibrator>(std::move(scheduler),
472                                                                 std::move(handle)) {}
473     virtual ~HidlHalWrapperV1_2() = default;
474 
475     HalResult<std::chrono::milliseconds> performEffect(
476             hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength,
477             const std::function<void()>& completionCallback) override final;
478 };
479 
480 // Wrapper for the HDIL Vibrator HAL v1.3.
481 class HidlHalWrapperV1_3 : public HidlHalWrapper<hardware::vibrator::V1_3::IVibrator> {
482 public:
HidlHalWrapperV1_3(std::shared_ptr<CallbackScheduler> scheduler,sp<hardware::vibrator::V1_3::IVibrator> handle)483     HidlHalWrapperV1_3(std::shared_ptr<CallbackScheduler> scheduler,
484                        sp<hardware::vibrator::V1_3::IVibrator> handle)
485           : HidlHalWrapper<hardware::vibrator::V1_3::IVibrator>(std::move(scheduler),
486                                                                 std::move(handle)) {}
487     virtual ~HidlHalWrapperV1_3() = default;
488 
489     HalResult<void> setExternalControl(bool enabled) override final;
490 
491     HalResult<std::chrono::milliseconds> performEffect(
492             hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength,
493             const std::function<void()>& completionCallback) override final;
494 
495 protected:
496     HalResult<Capabilities> getCapabilitiesInternal() override final;
497 };
498 
499 // -------------------------------------------------------------------------------------------------
500 
501 }; // namespace vibrator
502 
503 }; // namespace android
504 
505 #endif // ANDROID_OS_VIBRATORHALWRAPPER_H
506