Loading services/vibratorservice/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ cc_library_shared { "libhidlbase", "liblog", "libutils", "android.hardware.vibrator-cpp", "android.hardware.vibrator-unstable-cpp", "android.hardware.vibrator@1.0", "android.hardware.vibrator@1.1", "android.hardware.vibrator@1.2", Loading services/vibratorservice/VibratorHalWrapper.cpp +5 −29 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ #define LOG_TAG "VibratorHalWrapper" #include <android/hardware/vibrator/1.3/IVibrator.h> #include <android/hardware/vibrator/BnVibratorCallback.h> #include <android/hardware/vibrator/IVibrator.h> #include <hardware/vibrator.h> Loading Loading @@ -72,17 +71,6 @@ const constexpr char* STATUS_T_ERROR_MESSAGE_PREFIX = "status_t = "; const constexpr char* STATUS_V_1_0_ERROR_MESSAGE_PREFIX = "android::hardware::vibrator::V1_0::Status = "; template <typename T> HalResult<T> HalResult<T>::fromStatus(binder::Status status, T data) { if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) { return HalResult<T>::unsupported(); } if (status.isOk()) { return HalResult<T>::ok(data); } return HalResult<T>::failed(std::string(status.toString8().c_str())); } template <typename T> HalResult<T> HalResult<T>::fromStatus(V1_0::Status status, T data) { switch (status) { Loading Loading @@ -145,28 +133,16 @@ HalResult<void> HalResult<void>::fromReturn(hardware::Return<R>& ret) { // ------------------------------------------------------------------------------------------------- class HalCallbackWrapper : public Aidl::BnVibratorCallback { public: HalCallbackWrapper(std::function<void()> completionCallback) : mCompletionCallback(completionCallback) {} binder::Status onComplete() override { mCompletionCallback(); return binder::Status::ok(); } private: const std::function<void()> mCompletionCallback; }; // ------------------------------------------------------------------------------------------------- HalResult<void> AidlHalWrapper::ping() { return HalResult<void>::fromStatus(IInterface::asBinder(getHal())->pingBinder()); } void AidlHalWrapper::tryReconnect() { sp<Aidl::IVibrator> newHandle = checkVintfService<Aidl::IVibrator>(); auto result = mReconnectFn(); if (!result.isOk()) { return; } sp<Aidl::IVibrator> newHandle = result.value(); if (newHandle) { std::lock_guard<std::mutex> lock(mHandleMutex); mHandle = std::move(newHandle); Loading services/vibratorservice/VibratorManagerHalWrapper.cpp +137 −1 Original line number Diff line number Diff line Loading @@ -20,11 +20,14 @@ #include <vibratorservice/VibratorManagerHalWrapper.h> namespace Aidl = android::hardware::vibrator; namespace android { namespace vibrator { constexpr int32_t SINGLE_VIBRATOR_ID = 0; const constexpr char* MISSING_VIBRATOR_MESSAGE_PREFIX = "No vibrator with id="; HalResult<void> LegacyManagerHalWrapper::ping() { return mController->ping(); Loading @@ -34,6 +37,10 @@ void LegacyManagerHalWrapper::tryReconnect() { mController->tryReconnect(); } HalResult<ManagerCapabilities> LegacyManagerHalWrapper::getCapabilities() { return HalResult<ManagerCapabilities>::ok(ManagerCapabilities::NONE); } HalResult<std::vector<int32_t>> LegacyManagerHalWrapper::getVibratorIds() { if (mController->init()) { return HalResult<std::vector<int32_t>>::ok(std::vector<int32_t>(1, SINGLE_VIBRATOR_ID)); Loading @@ -47,7 +54,7 @@ HalResult<std::shared_ptr<HalController>> LegacyManagerHalWrapper::getVibrator(i return HalResult<std::shared_ptr<HalController>>::ok(mController); } // Controller.init did not connect to any vibrator HAL service, so the device has no vibrator. return HalResult<std::shared_ptr<HalController>>::failed("No vibrator with id = " + return HalResult<std::shared_ptr<HalController>>::failed(MISSING_VIBRATOR_MESSAGE_PREFIX + std::to_string(id)); } Loading @@ -63,6 +70,135 @@ HalResult<void> LegacyManagerHalWrapper::cancelSynced() { return HalResult<void>::unsupported(); } // ------------------------------------------------------------------------------------------------- std::shared_ptr<HalWrapper> AidlManagerHalWrapper::ManagedHalConnector::connect( std::shared_ptr<CallbackScheduler> callbackScheduler) { std::function<HalResult<sp<Aidl::IVibrator>>()> reconnectFn = [&]() { sp<Aidl::IVibrator> vibrator; auto result = this->mManager->getHal()->getVibrator(this->mVibratorId, &vibrator); return HalResult<sp<Aidl::IVibrator>>::fromStatus(result, vibrator); }; auto result = reconnectFn(); if (!result.isOk()) { return nullptr; } auto vibrator = result.value(); if (!vibrator) { return nullptr; } return std::move(std::make_unique<AidlHalWrapper>(std::move(callbackScheduler), std::move(vibrator), reconnectFn)); } HalResult<void> AidlManagerHalWrapper::ping() { return HalResult<void>::fromStatus(IInterface::asBinder(getHal())->pingBinder()); } void AidlManagerHalWrapper::tryReconnect() { sp<Aidl::IVibratorManager> newHandle = checkVintfService<Aidl::IVibratorManager>(); if (newHandle) { std::lock_guard<std::mutex> lock(mHandleMutex); mHandle = std::move(newHandle); } } HalResult<ManagerCapabilities> AidlManagerHalWrapper::getCapabilities() { std::lock_guard<std::mutex> lock(mCapabilitiesMutex); if (mCapabilities.has_value()) { // Return copy of cached value. return HalResult<ManagerCapabilities>::ok(*mCapabilities); } int32_t cap = 0; auto result = getHal()->getCapabilities(&cap); auto ret = HalResult<ManagerCapabilities>::fromStatus(result, static_cast<ManagerCapabilities>(cap)); if (ret.isOk()) { // Cache copy of returned value. mCapabilities.emplace(ret.value()); } return ret; } HalResult<std::vector<int32_t>> AidlManagerHalWrapper::getVibratorIds() { std::lock_guard<std::mutex> lock(mVibratorsMutex); if (mVibratorIds.has_value()) { // Return copy of cached values. return HalResult<std::vector<int32_t>>::ok(*mVibratorIds); } std::vector<int32_t> ids; auto result = getHal()->getVibratorIds(&ids); auto ret = HalResult<std::vector<int32_t>>::fromStatus(result, ids); if (ret.isOk()) { // Cache copy of returned value and the individual controllers. mVibratorIds.emplace(ret.value()); for (auto& id : ids) { auto connector = std::make_unique<ManagedHalConnector>(this, id); auto controller = std::make_unique<HalController>(std::move(connector), mCallbackScheduler); mVibrators[id] = std::move(controller); } } return ret; } HalResult<std::shared_ptr<HalController>> AidlManagerHalWrapper::getVibrator(int32_t id) { // Make sure we cache vibrator ids and initialize the individual controllers. getVibratorIds(); std::lock_guard<std::mutex> lock(mVibratorsMutex); auto it = mVibrators.find(id); if (it != mVibrators.end()) { return HalResult<std::shared_ptr<HalController>>::ok(it->second); } return HalResult<std::shared_ptr<HalController>>::failed(MISSING_VIBRATOR_MESSAGE_PREFIX + std::to_string(id)); } HalResult<void> AidlManagerHalWrapper::prepareSynced(const std::vector<int32_t>& ids) { auto ret = HalResult<void>::fromStatus(getHal()->prepareSynced(ids)); if (ret.isOk()) { // Force reload of all vibrator controllers that were prepared for a sync operation here. // This will trigger calls to getVibrator(id) on each controller, so they can use the // latest service provided by this manager. std::lock_guard<std::mutex> lock(mVibratorsMutex); for (auto& id : ids) { auto it = mVibrators.find(id); if (it != mVibrators.end()) { it->second->tryReconnect(); } } } return ret; } HalResult<void> AidlManagerHalWrapper::triggerSynced( const std::function<void()>& completionCallback) { HalResult<ManagerCapabilities> capabilities = getCapabilities(); bool supportsCallback = capabilities.isOk() && static_cast<int32_t>(capabilities.value() & ManagerCapabilities::TRIGGER_CALLBACK); auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr; return HalResult<void>::fromStatus(getHal()->triggerSynced(cb)); } HalResult<void> AidlManagerHalWrapper::cancelSynced() { auto ret = HalResult<void>::fromStatus(getHal()->cancelSynced()); if (ret.isOk()) { // Force reload of all vibrator controllers that were prepared for a sync operation before. // This will trigger calls to getVibrator(id) on each controller, so they can use the // latest service provided by this manager. std::lock_guard<std::mutex> lock(mVibratorsMutex); for (auto& entry : mVibrators) { entry.second->tryReconnect(); } } return ret; } sp<Aidl::IVibratorManager> AidlManagerHalWrapper::getHal() { std::lock_guard<std::mutex> lock(mHandleMutex); return mHandle; } }; // namespace vibrator }; // namespace android services/vibratorservice/benchmarks/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ cc_benchmark { "liblog", "libutils", "libvibratorservice", "android.hardware.vibrator-cpp", "android.hardware.vibrator-unstable-cpp", "android.hardware.vibrator@1.0", "android.hardware.vibrator@1.1", "android.hardware.vibrator@1.2", Loading services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h +35 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <android-base/thread_annotations.h> #include <android/hardware/vibrator/1.3/IVibrator.h> #include <android/hardware/vibrator/BnVibratorCallback.h> #include <android/hardware/vibrator/IVibrator.h> #include <binder/IServiceManager.h> Loading @@ -40,7 +41,15 @@ public: } static HalResult<T> unsupported() { return HalResult("", /* unsupported= */ true); } static HalResult<T> fromStatus(binder::Status status, T data); static HalResult<T> fromStatus(binder::Status status, T data) { if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) { return HalResult<T>::unsupported(); } if (status.isOk()) { return HalResult<T>::ok(data); } return HalResult<T>::failed(std::string(status.toString8().c_str())); } static HalResult<T> fromStatus(hardware::vibrator::V1_0::Status status, T data); template <typename R> Loading Loading @@ -99,6 +108,20 @@ private: : mErrorMessage(std::move(errorMessage)), mFailed(true), mUnsupported(false) {} }; class HalCallbackWrapper : public hardware::vibrator::BnVibratorCallback { public: HalCallbackWrapper(std::function<void()> completionCallback) : mCompletionCallback(completionCallback) {} binder::Status onComplete() override { mCompletionCallback(); return binder::Status::ok(); } private: const std::function<void()> mCompletionCallback; }; // ------------------------------------------------------------------------------------------------- // Vibrator HAL capabilities. Loading Loading @@ -178,9 +201,16 @@ protected: // Wrapper for the AIDL Vibrator HAL. class AidlHalWrapper : public HalWrapper { public: AidlHalWrapper(std::shared_ptr<CallbackScheduler> scheduler, sp<hardware::vibrator::IVibrator> handle) : HalWrapper(std::move(scheduler)), mHandle(std::move(handle)) {} AidlHalWrapper( std::shared_ptr<CallbackScheduler> scheduler, sp<hardware::vibrator::IVibrator> handle, std::function<HalResult<sp<hardware::vibrator::IVibrator>>()> reconnectFn = []() { return HalResult<sp<hardware::vibrator::IVibrator>>::ok( checkVintfService<hardware::vibrator::IVibrator>()); }) : HalWrapper(std::move(scheduler)), mReconnectFn(reconnectFn), mHandle(std::move(handle)) {} virtual ~AidlHalWrapper() = default; HalResult<void> ping() override final; Loading Loading @@ -211,6 +241,7 @@ public: const std::function<void()>& completionCallback) override final; private: const std::function<HalResult<sp<hardware::vibrator::IVibrator>>()> mReconnectFn; std::mutex mHandleMutex; std::mutex mCapabilitiesMutex; std::mutex mSupportedEffectsMutex; Loading Loading
services/vibratorservice/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ cc_library_shared { "libhidlbase", "liblog", "libutils", "android.hardware.vibrator-cpp", "android.hardware.vibrator-unstable-cpp", "android.hardware.vibrator@1.0", "android.hardware.vibrator@1.1", "android.hardware.vibrator@1.2", Loading
services/vibratorservice/VibratorHalWrapper.cpp +5 −29 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ #define LOG_TAG "VibratorHalWrapper" #include <android/hardware/vibrator/1.3/IVibrator.h> #include <android/hardware/vibrator/BnVibratorCallback.h> #include <android/hardware/vibrator/IVibrator.h> #include <hardware/vibrator.h> Loading Loading @@ -72,17 +71,6 @@ const constexpr char* STATUS_T_ERROR_MESSAGE_PREFIX = "status_t = "; const constexpr char* STATUS_V_1_0_ERROR_MESSAGE_PREFIX = "android::hardware::vibrator::V1_0::Status = "; template <typename T> HalResult<T> HalResult<T>::fromStatus(binder::Status status, T data) { if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) { return HalResult<T>::unsupported(); } if (status.isOk()) { return HalResult<T>::ok(data); } return HalResult<T>::failed(std::string(status.toString8().c_str())); } template <typename T> HalResult<T> HalResult<T>::fromStatus(V1_0::Status status, T data) { switch (status) { Loading Loading @@ -145,28 +133,16 @@ HalResult<void> HalResult<void>::fromReturn(hardware::Return<R>& ret) { // ------------------------------------------------------------------------------------------------- class HalCallbackWrapper : public Aidl::BnVibratorCallback { public: HalCallbackWrapper(std::function<void()> completionCallback) : mCompletionCallback(completionCallback) {} binder::Status onComplete() override { mCompletionCallback(); return binder::Status::ok(); } private: const std::function<void()> mCompletionCallback; }; // ------------------------------------------------------------------------------------------------- HalResult<void> AidlHalWrapper::ping() { return HalResult<void>::fromStatus(IInterface::asBinder(getHal())->pingBinder()); } void AidlHalWrapper::tryReconnect() { sp<Aidl::IVibrator> newHandle = checkVintfService<Aidl::IVibrator>(); auto result = mReconnectFn(); if (!result.isOk()) { return; } sp<Aidl::IVibrator> newHandle = result.value(); if (newHandle) { std::lock_guard<std::mutex> lock(mHandleMutex); mHandle = std::move(newHandle); Loading
services/vibratorservice/VibratorManagerHalWrapper.cpp +137 −1 Original line number Diff line number Diff line Loading @@ -20,11 +20,14 @@ #include <vibratorservice/VibratorManagerHalWrapper.h> namespace Aidl = android::hardware::vibrator; namespace android { namespace vibrator { constexpr int32_t SINGLE_VIBRATOR_ID = 0; const constexpr char* MISSING_VIBRATOR_MESSAGE_PREFIX = "No vibrator with id="; HalResult<void> LegacyManagerHalWrapper::ping() { return mController->ping(); Loading @@ -34,6 +37,10 @@ void LegacyManagerHalWrapper::tryReconnect() { mController->tryReconnect(); } HalResult<ManagerCapabilities> LegacyManagerHalWrapper::getCapabilities() { return HalResult<ManagerCapabilities>::ok(ManagerCapabilities::NONE); } HalResult<std::vector<int32_t>> LegacyManagerHalWrapper::getVibratorIds() { if (mController->init()) { return HalResult<std::vector<int32_t>>::ok(std::vector<int32_t>(1, SINGLE_VIBRATOR_ID)); Loading @@ -47,7 +54,7 @@ HalResult<std::shared_ptr<HalController>> LegacyManagerHalWrapper::getVibrator(i return HalResult<std::shared_ptr<HalController>>::ok(mController); } // Controller.init did not connect to any vibrator HAL service, so the device has no vibrator. return HalResult<std::shared_ptr<HalController>>::failed("No vibrator with id = " + return HalResult<std::shared_ptr<HalController>>::failed(MISSING_VIBRATOR_MESSAGE_PREFIX + std::to_string(id)); } Loading @@ -63,6 +70,135 @@ HalResult<void> LegacyManagerHalWrapper::cancelSynced() { return HalResult<void>::unsupported(); } // ------------------------------------------------------------------------------------------------- std::shared_ptr<HalWrapper> AidlManagerHalWrapper::ManagedHalConnector::connect( std::shared_ptr<CallbackScheduler> callbackScheduler) { std::function<HalResult<sp<Aidl::IVibrator>>()> reconnectFn = [&]() { sp<Aidl::IVibrator> vibrator; auto result = this->mManager->getHal()->getVibrator(this->mVibratorId, &vibrator); return HalResult<sp<Aidl::IVibrator>>::fromStatus(result, vibrator); }; auto result = reconnectFn(); if (!result.isOk()) { return nullptr; } auto vibrator = result.value(); if (!vibrator) { return nullptr; } return std::move(std::make_unique<AidlHalWrapper>(std::move(callbackScheduler), std::move(vibrator), reconnectFn)); } HalResult<void> AidlManagerHalWrapper::ping() { return HalResult<void>::fromStatus(IInterface::asBinder(getHal())->pingBinder()); } void AidlManagerHalWrapper::tryReconnect() { sp<Aidl::IVibratorManager> newHandle = checkVintfService<Aidl::IVibratorManager>(); if (newHandle) { std::lock_guard<std::mutex> lock(mHandleMutex); mHandle = std::move(newHandle); } } HalResult<ManagerCapabilities> AidlManagerHalWrapper::getCapabilities() { std::lock_guard<std::mutex> lock(mCapabilitiesMutex); if (mCapabilities.has_value()) { // Return copy of cached value. return HalResult<ManagerCapabilities>::ok(*mCapabilities); } int32_t cap = 0; auto result = getHal()->getCapabilities(&cap); auto ret = HalResult<ManagerCapabilities>::fromStatus(result, static_cast<ManagerCapabilities>(cap)); if (ret.isOk()) { // Cache copy of returned value. mCapabilities.emplace(ret.value()); } return ret; } HalResult<std::vector<int32_t>> AidlManagerHalWrapper::getVibratorIds() { std::lock_guard<std::mutex> lock(mVibratorsMutex); if (mVibratorIds.has_value()) { // Return copy of cached values. return HalResult<std::vector<int32_t>>::ok(*mVibratorIds); } std::vector<int32_t> ids; auto result = getHal()->getVibratorIds(&ids); auto ret = HalResult<std::vector<int32_t>>::fromStatus(result, ids); if (ret.isOk()) { // Cache copy of returned value and the individual controllers. mVibratorIds.emplace(ret.value()); for (auto& id : ids) { auto connector = std::make_unique<ManagedHalConnector>(this, id); auto controller = std::make_unique<HalController>(std::move(connector), mCallbackScheduler); mVibrators[id] = std::move(controller); } } return ret; } HalResult<std::shared_ptr<HalController>> AidlManagerHalWrapper::getVibrator(int32_t id) { // Make sure we cache vibrator ids and initialize the individual controllers. getVibratorIds(); std::lock_guard<std::mutex> lock(mVibratorsMutex); auto it = mVibrators.find(id); if (it != mVibrators.end()) { return HalResult<std::shared_ptr<HalController>>::ok(it->second); } return HalResult<std::shared_ptr<HalController>>::failed(MISSING_VIBRATOR_MESSAGE_PREFIX + std::to_string(id)); } HalResult<void> AidlManagerHalWrapper::prepareSynced(const std::vector<int32_t>& ids) { auto ret = HalResult<void>::fromStatus(getHal()->prepareSynced(ids)); if (ret.isOk()) { // Force reload of all vibrator controllers that were prepared for a sync operation here. // This will trigger calls to getVibrator(id) on each controller, so they can use the // latest service provided by this manager. std::lock_guard<std::mutex> lock(mVibratorsMutex); for (auto& id : ids) { auto it = mVibrators.find(id); if (it != mVibrators.end()) { it->second->tryReconnect(); } } } return ret; } HalResult<void> AidlManagerHalWrapper::triggerSynced( const std::function<void()>& completionCallback) { HalResult<ManagerCapabilities> capabilities = getCapabilities(); bool supportsCallback = capabilities.isOk() && static_cast<int32_t>(capabilities.value() & ManagerCapabilities::TRIGGER_CALLBACK); auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr; return HalResult<void>::fromStatus(getHal()->triggerSynced(cb)); } HalResult<void> AidlManagerHalWrapper::cancelSynced() { auto ret = HalResult<void>::fromStatus(getHal()->cancelSynced()); if (ret.isOk()) { // Force reload of all vibrator controllers that were prepared for a sync operation before. // This will trigger calls to getVibrator(id) on each controller, so they can use the // latest service provided by this manager. std::lock_guard<std::mutex> lock(mVibratorsMutex); for (auto& entry : mVibrators) { entry.second->tryReconnect(); } } return ret; } sp<Aidl::IVibratorManager> AidlManagerHalWrapper::getHal() { std::lock_guard<std::mutex> lock(mHandleMutex); return mHandle; } }; // namespace vibrator }; // namespace android
services/vibratorservice/benchmarks/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ cc_benchmark { "liblog", "libutils", "libvibratorservice", "android.hardware.vibrator-cpp", "android.hardware.vibrator-unstable-cpp", "android.hardware.vibrator@1.0", "android.hardware.vibrator@1.1", "android.hardware.vibrator@1.2", Loading
services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h +35 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <android-base/thread_annotations.h> #include <android/hardware/vibrator/1.3/IVibrator.h> #include <android/hardware/vibrator/BnVibratorCallback.h> #include <android/hardware/vibrator/IVibrator.h> #include <binder/IServiceManager.h> Loading @@ -40,7 +41,15 @@ public: } static HalResult<T> unsupported() { return HalResult("", /* unsupported= */ true); } static HalResult<T> fromStatus(binder::Status status, T data); static HalResult<T> fromStatus(binder::Status status, T data) { if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) { return HalResult<T>::unsupported(); } if (status.isOk()) { return HalResult<T>::ok(data); } return HalResult<T>::failed(std::string(status.toString8().c_str())); } static HalResult<T> fromStatus(hardware::vibrator::V1_0::Status status, T data); template <typename R> Loading Loading @@ -99,6 +108,20 @@ private: : mErrorMessage(std::move(errorMessage)), mFailed(true), mUnsupported(false) {} }; class HalCallbackWrapper : public hardware::vibrator::BnVibratorCallback { public: HalCallbackWrapper(std::function<void()> completionCallback) : mCompletionCallback(completionCallback) {} binder::Status onComplete() override { mCompletionCallback(); return binder::Status::ok(); } private: const std::function<void()> mCompletionCallback; }; // ------------------------------------------------------------------------------------------------- // Vibrator HAL capabilities. Loading Loading @@ -178,9 +201,16 @@ protected: // Wrapper for the AIDL Vibrator HAL. class AidlHalWrapper : public HalWrapper { public: AidlHalWrapper(std::shared_ptr<CallbackScheduler> scheduler, sp<hardware::vibrator::IVibrator> handle) : HalWrapper(std::move(scheduler)), mHandle(std::move(handle)) {} AidlHalWrapper( std::shared_ptr<CallbackScheduler> scheduler, sp<hardware::vibrator::IVibrator> handle, std::function<HalResult<sp<hardware::vibrator::IVibrator>>()> reconnectFn = []() { return HalResult<sp<hardware::vibrator::IVibrator>>::ok( checkVintfService<hardware::vibrator::IVibrator>()); }) : HalWrapper(std::move(scheduler)), mReconnectFn(reconnectFn), mHandle(std::move(handle)) {} virtual ~AidlHalWrapper() = default; HalResult<void> ping() override final; Loading Loading @@ -211,6 +241,7 @@ public: const std::function<void()>& completionCallback) override final; private: const std::function<HalResult<sp<hardware::vibrator::IVibrator>>()> mReconnectFn; std::mutex mHandleMutex; std::mutex mCapabilitiesMutex; std::mutex mSupportedEffectsMutex; Loading