Loading services/vibratorservice/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ cc_library_shared { srcs: [ "VibratorCallbackScheduler.cpp", "VibratorHalController.cpp", "VibratorHalWrapper.cpp", ], Loading services/vibratorservice/VibratorHalController.cpp 0 → 100644 +224 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "VibratorHalController" #include <android/hardware/vibrator/1.3/IVibrator.h> #include <android/hardware/vibrator/IVibrator.h> #include <binder/IServiceManager.h> #include <hardware/vibrator.h> #include <utils/Log.h> #include <vibratorservice/VibratorCallbackScheduler.h> #include <vibratorservice/VibratorHalController.h> #include <vibratorservice/VibratorHalWrapper.h> using android::hardware::vibrator::CompositeEffect; using android::hardware::vibrator::Effect; using android::hardware::vibrator::EffectStrength; using std::chrono::milliseconds; namespace V1_0 = android::hardware::vibrator::V1_0; namespace V1_1 = android::hardware::vibrator::V1_1; namespace V1_2 = android::hardware::vibrator::V1_2; namespace V1_3 = android::hardware::vibrator::V1_3; namespace Aidl = android::hardware::vibrator; namespace android { namespace vibrator { // ------------------------------------------------------------------------------------------------- template <typename T> using hal_connect_fn = std::function<sp<T>()>; template <typename T> sp<T> connectToHal(bool* halExists, const hal_connect_fn<T>& connectFn, const char* halName) { if (!*halExists) { return nullptr; } sp<T> hal = connectFn(); if (hal) { ALOGV("Successfully connected to Vibrator HAL %s service.", halName); } else { ALOGV("Vibrator HAL %s service not available.", halName); *halExists = false; } return hal; } sp<Aidl::IVibrator> connectToAidl() { static bool gHalExists = true; static hal_connect_fn<Aidl::IVibrator> connectFn = []() { return waitForVintfService<Aidl::IVibrator>(); }; return connectToHal(&gHalExists, connectFn, "AIDL"); } sp<V1_0::IVibrator> connectToHidl() { static bool gHalExists = true; static hal_connect_fn<V1_0::IVibrator> connectFn = []() { return V1_0::IVibrator::getService(); }; return connectToHal(&gHalExists, connectFn, "v1.0"); } // ------------------------------------------------------------------------------------------------- std::shared_ptr<HalWrapper> HalConnector::connect(std::shared_ptr<CallbackScheduler> scheduler) { sp<Aidl::IVibrator> aidlHal = connectToAidl(); if (aidlHal) { return std::make_shared<AidlHalWrapper>(std::move(scheduler), aidlHal); } sp<V1_0::IVibrator> halV1_0 = connectToHidl(); if (halV1_0 == nullptr) { // No Vibrator HAL service available. return nullptr; } sp<V1_3::IVibrator> halV1_3 = V1_3::IVibrator::castFrom(halV1_0); if (halV1_3) { ALOGV("Successfully converted to Vibrator HAL v1.3 service."); return std::make_shared<HidlHalWrapperV1_3>(std::move(scheduler), halV1_3); } sp<V1_2::IVibrator> halV1_2 = V1_2::IVibrator::castFrom(halV1_0); if (halV1_2) { ALOGV("Successfully converted to Vibrator HAL v1.2 service."); return std::make_shared<HidlHalWrapperV1_2>(std::move(scheduler), halV1_2); } sp<V1_1::IVibrator> halV1_1 = V1_1::IVibrator::castFrom(halV1_0); if (halV1_1) { ALOGV("Successfully converted to Vibrator HAL v1.1 service."); return std::make_shared<HidlHalWrapperV1_1>(std::move(scheduler), halV1_1); } return std::make_shared<HidlHalWrapperV1_0>(std::move(scheduler), halV1_0); } // ------------------------------------------------------------------------------------------------- template <typename T> HalResult<T> HalController::processHalResult(HalResult<T> result, const char* functionName) { if (result.isFailed()) { ALOGE("%s failed: Vibrator HAL not available", functionName); std::lock_guard<std::mutex> lock(mConnectedHalMutex); // Drop HAL handle. This will force future api calls to reconnect. mConnectedHal = nullptr; } return result; } template <typename T> HalResult<T> HalController::apply(HalController::hal_fn<T>& halFn, const char* functionName) { std::shared_ptr<HalWrapper> hal = nullptr; { std::lock_guard<std::mutex> lock(mConnectedHalMutex); if (mConnectedHal == nullptr) { mConnectedHal = mHalConnector->connect(mCallbackScheduler); } hal = mConnectedHal; } if (hal) { return processHalResult(halFn(hal), functionName); } ALOGV("Skipped %s because Vibrator HAL is not available", functionName); return HalResult<T>::unsupported(); } // ------------------------------------------------------------------------------------------------- HalResult<void> HalController::ping() { hal_fn<void> pingFn = [](std::shared_ptr<HalWrapper> hal) { return hal->ping(); }; return apply(pingFn, "ping"); } HalResult<void> HalController::on(milliseconds timeout, const std::function<void()>& completionCallback) { hal_fn<void> onFn = [&](std::shared_ptr<HalWrapper> hal) { return hal->on(timeout, completionCallback); }; return apply(onFn, "on"); } HalResult<void> HalController::off() { hal_fn<void> offFn = [](std::shared_ptr<HalWrapper> hal) { return hal->off(); }; return apply(offFn, "off"); } HalResult<void> HalController::setAmplitude(int32_t amplitude) { hal_fn<void> setAmplitudeFn = [&](std::shared_ptr<HalWrapper> hal) { return hal->setAmplitude(amplitude); }; return apply(setAmplitudeFn, "setAmplitude"); } HalResult<void> HalController::setExternalControl(bool enabled) { hal_fn<void> setExternalControlFn = [&](std::shared_ptr<HalWrapper> hal) { return hal->setExternalControl(enabled); }; return apply(setExternalControlFn, "setExternalControl"); } HalResult<void> HalController::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) { hal_fn<void> alwaysOnEnableFn = [&](std::shared_ptr<HalWrapper> hal) { return hal->alwaysOnEnable(id, effect, strength); }; return apply(alwaysOnEnableFn, "alwaysOnEnable"); } HalResult<void> HalController::alwaysOnDisable(int32_t id) { hal_fn<void> alwaysOnDisableFn = [&](std::shared_ptr<HalWrapper> hal) { return hal->alwaysOnDisable(id); }; return apply(alwaysOnDisableFn, "alwaysOnDisable"); } HalResult<Capabilities> HalController::getCapabilities() { hal_fn<Capabilities> getCapabilitiesFn = [](std::shared_ptr<HalWrapper> hal) { return hal->getCapabilities(); }; return apply(getCapabilitiesFn, "getCapabilities"); } HalResult<std::vector<Effect>> HalController::getSupportedEffects() { hal_fn<std::vector<Effect>> getSupportedEffectsFn = [](std::shared_ptr<HalWrapper> hal) { return hal->getSupportedEffects(); }; return apply(getSupportedEffectsFn, "getSupportedEffects"); } HalResult<milliseconds> HalController::performEffect( Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) { hal_fn<milliseconds> performEffectFn = [&](std::shared_ptr<HalWrapper> hal) { return hal->performEffect(effect, strength, completionCallback); }; return apply(performEffectFn, "performEffect"); } HalResult<void> HalController::performComposedEffect( const std::vector<CompositeEffect>& primitiveEffects, const std::function<void()>& completionCallback) { hal_fn<void> performComposedEffectFn = [&](std::shared_ptr<HalWrapper> hal) { return hal->performComposedEffect(primitiveEffects, completionCallback); }; return apply(performComposedEffectFn, "performComposedEffect"); } }; // namespace vibrator }; // namespace android services/vibratorservice/VibratorHalWrapper.cpp +0 −27 Original line number Diff line number Diff line Loading @@ -67,21 +67,6 @@ bool isStaticCastValid(Effect effect) { // ------------------------------------------------------------------------------------------------- template <typename T> HalResult<T> HalResult<T>::ok(T value) { return HalResult(value); } template <typename T> HalResult<T> HalResult<T>::failed() { return HalResult(/* unsupported= */ false); } template <typename T> HalResult<T> HalResult<T>::unsupported() { return HalResult(/* unsupported= */ true); } template <typename T> HalResult<T> HalResult<T>::fromStatus(binder::Status status, T data) { if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) { Loading Loading @@ -119,18 +104,6 @@ HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, V1_0::Status sta // ------------------------------------------------------------------------------------------------- HalResult<void> HalResult<void>::ok() { return HalResult(); } HalResult<void> HalResult<void>::failed() { return HalResult(/* failed= */ true); } HalResult<void> HalResult<void>::unsupported() { return HalResult(/* failed= */ false, /* unsupported= */ true); } HalResult<void> HalResult<void>::fromStatus(binder::Status status) { if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) { return HalResult<void>::unsupported(); Loading services/vibratorservice/include/vibratorservice/VibratorHalController.h 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_OS_VIBRATORHALCONTROLLER_H #define ANDROID_OS_VIBRATORHALCONTROLLER_H #include <android-base/thread_annotations.h> #include <android/hardware/vibrator/IVibrator.h> #include <vibratorservice/VibratorCallbackScheduler.h> #include <vibratorservice/VibratorHalWrapper.h> namespace android { namespace vibrator { // Handles the connection to he underlying HAL implementation available. class HalConnector { public: HalConnector() = default; virtual ~HalConnector() = default; virtual std::shared_ptr<HalWrapper> connect(std::shared_ptr<CallbackScheduler> scheduler); }; // Controller for Vibrator HAL handle. // This relies on HalConnector to connect to the underlying Vibrator HAL service and reconnects to // it after each failed api call. This also ensures connecting to the service is thread-safe. class HalController : public HalWrapper { public: HalController() : HalController(std::make_unique<HalConnector>(), std::make_shared<CallbackScheduler>()) { } HalController(std::unique_ptr<HalConnector> halConnector, std::shared_ptr<CallbackScheduler> callbackScheduler) : HalWrapper(std::move(callbackScheduler)), mHalConnector(std::move(halConnector)), mConnectedHal(nullptr) {} virtual ~HalController() = default; HalResult<void> ping() final override; HalResult<void> on(std::chrono::milliseconds timeout, const std::function<void()>& completionCallback) final override; HalResult<void> off() final override; HalResult<void> setAmplitude(int32_t amplitude) final override; HalResult<void> setExternalControl(bool enabled) final override; HalResult<void> alwaysOnEnable(int32_t id, hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength) final override; HalResult<void> alwaysOnDisable(int32_t id) final override; HalResult<Capabilities> getCapabilities() final override; HalResult<std::vector<hardware::vibrator::Effect>> getSupportedEffects() final override; HalResult<std::chrono::milliseconds> performEffect( hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength, const std::function<void()>& completionCallback) final override; HalResult<void> performComposedEffect( const std::vector<hardware::vibrator::CompositeEffect>& primitiveEffects, const std::function<void()>& completionCallback) final override; private: std::unique_ptr<HalConnector> mHalConnector; std::mutex mConnectedHalMutex; // Shared pointer to allow local copies to be used by different threads. std::shared_ptr<HalWrapper> mConnectedHal GUARDED_BY(mConnectedHalMutex); template <typename T> HalResult<T> processHalResult(HalResult<T> result, const char* functionName); template <typename T> using hal_fn = std::function<HalResult<T>(std::shared_ptr<HalWrapper>)>; template <typename T> HalResult<T> apply(hal_fn<T>& halFn, const char* functionName); }; }; // namespace vibrator }; // namespace android #endif // ANDROID_OS_VIBRATORHALCONTROLLER_H services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h +14 −15 Original line number Diff line number Diff line Loading @@ -33,9 +33,9 @@ namespace vibrator { template <typename T> class HalResult { public: static HalResult<T> ok(T value); static HalResult<T> failed(); static HalResult<T> unsupported(); static HalResult<T> ok(T value) { return HalResult(value); } static HalResult<T> failed() { return HalResult(/* unsupported= */ false); } static HalResult<T> unsupported() { return HalResult(/* unsupported= */ true); } static HalResult<T> fromStatus(binder::Status status, T data); static HalResult<T> fromStatus(hardware::vibrator::V1_0::Status status, T data); Loading Loading @@ -65,9 +65,11 @@ private: template <> class HalResult<void> { public: static HalResult<void> ok(); static HalResult<void> failed(); static HalResult<void> unsupported(); static HalResult<void> ok() { return HalResult(); } static HalResult<void> failed() { return HalResult(/* failed= */ true); } static HalResult<void> unsupported() { return HalResult(/* failed= */ false, /* unsupported= */ true); } static HalResult<void> fromStatus(binder::Status status); static HalResult<void> fromStatus(hardware::vibrator::V1_0::Status status); Loading Loading @@ -262,9 +264,8 @@ protected: class HidlHalWrapperV1_1 : public HidlHalWrapperV1_0 { public: HidlHalWrapperV1_1(std::shared_ptr<CallbackScheduler> scheduler, sp<hardware::vibrator::V1_0::IVibrator> handleV1_0) : HidlHalWrapperV1_0(std::move(scheduler), handleV1_0), mHandleV1_1(hardware::vibrator::V1_1::IVibrator::castFrom(handleV1_0)) {} sp<hardware::vibrator::V1_1::IVibrator> handle) : HidlHalWrapperV1_0(std::move(scheduler), handle), mHandleV1_1(handle) {} virtual ~HidlHalWrapperV1_1() = default; virtual HalResult<std::chrono::milliseconds> performEffect( Loading @@ -283,9 +284,8 @@ protected: class HidlHalWrapperV1_2 : public HidlHalWrapperV1_1 { public: HidlHalWrapperV1_2(std::shared_ptr<CallbackScheduler> scheduler, sp<hardware::vibrator::V1_0::IVibrator> handleV1_0) : HidlHalWrapperV1_1(std::move(scheduler), handleV1_0), mHandleV1_2(hardware::vibrator::V1_2::IVibrator::castFrom(handleV1_0)) {} sp<hardware::vibrator::V1_2::IVibrator> handle) : HidlHalWrapperV1_1(std::move(scheduler), handle), mHandleV1_2(handle) {} virtual ~HidlHalWrapperV1_2() = default; virtual HalResult<std::chrono::milliseconds> performEffect( Loading @@ -304,9 +304,8 @@ protected: class HidlHalWrapperV1_3 : public HidlHalWrapperV1_2 { public: HidlHalWrapperV1_3(std::shared_ptr<CallbackScheduler> scheduler, sp<hardware::vibrator::V1_0::IVibrator> handleV1_0) : HidlHalWrapperV1_2(std::move(scheduler), handleV1_0), mHandleV1_3(hardware::vibrator::V1_3::IVibrator::castFrom(handleV1_0)) {} sp<hardware::vibrator::V1_3::IVibrator> handle) : HidlHalWrapperV1_2(std::move(scheduler), handle), mHandleV1_3(handle) {} virtual ~HidlHalWrapperV1_3() = default; virtual HalResult<void> setExternalControl(bool enabled) override; Loading Loading
services/vibratorservice/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ cc_library_shared { srcs: [ "VibratorCallbackScheduler.cpp", "VibratorHalController.cpp", "VibratorHalWrapper.cpp", ], Loading
services/vibratorservice/VibratorHalController.cpp 0 → 100644 +224 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "VibratorHalController" #include <android/hardware/vibrator/1.3/IVibrator.h> #include <android/hardware/vibrator/IVibrator.h> #include <binder/IServiceManager.h> #include <hardware/vibrator.h> #include <utils/Log.h> #include <vibratorservice/VibratorCallbackScheduler.h> #include <vibratorservice/VibratorHalController.h> #include <vibratorservice/VibratorHalWrapper.h> using android::hardware::vibrator::CompositeEffect; using android::hardware::vibrator::Effect; using android::hardware::vibrator::EffectStrength; using std::chrono::milliseconds; namespace V1_0 = android::hardware::vibrator::V1_0; namespace V1_1 = android::hardware::vibrator::V1_1; namespace V1_2 = android::hardware::vibrator::V1_2; namespace V1_3 = android::hardware::vibrator::V1_3; namespace Aidl = android::hardware::vibrator; namespace android { namespace vibrator { // ------------------------------------------------------------------------------------------------- template <typename T> using hal_connect_fn = std::function<sp<T>()>; template <typename T> sp<T> connectToHal(bool* halExists, const hal_connect_fn<T>& connectFn, const char* halName) { if (!*halExists) { return nullptr; } sp<T> hal = connectFn(); if (hal) { ALOGV("Successfully connected to Vibrator HAL %s service.", halName); } else { ALOGV("Vibrator HAL %s service not available.", halName); *halExists = false; } return hal; } sp<Aidl::IVibrator> connectToAidl() { static bool gHalExists = true; static hal_connect_fn<Aidl::IVibrator> connectFn = []() { return waitForVintfService<Aidl::IVibrator>(); }; return connectToHal(&gHalExists, connectFn, "AIDL"); } sp<V1_0::IVibrator> connectToHidl() { static bool gHalExists = true; static hal_connect_fn<V1_0::IVibrator> connectFn = []() { return V1_0::IVibrator::getService(); }; return connectToHal(&gHalExists, connectFn, "v1.0"); } // ------------------------------------------------------------------------------------------------- std::shared_ptr<HalWrapper> HalConnector::connect(std::shared_ptr<CallbackScheduler> scheduler) { sp<Aidl::IVibrator> aidlHal = connectToAidl(); if (aidlHal) { return std::make_shared<AidlHalWrapper>(std::move(scheduler), aidlHal); } sp<V1_0::IVibrator> halV1_0 = connectToHidl(); if (halV1_0 == nullptr) { // No Vibrator HAL service available. return nullptr; } sp<V1_3::IVibrator> halV1_3 = V1_3::IVibrator::castFrom(halV1_0); if (halV1_3) { ALOGV("Successfully converted to Vibrator HAL v1.3 service."); return std::make_shared<HidlHalWrapperV1_3>(std::move(scheduler), halV1_3); } sp<V1_2::IVibrator> halV1_2 = V1_2::IVibrator::castFrom(halV1_0); if (halV1_2) { ALOGV("Successfully converted to Vibrator HAL v1.2 service."); return std::make_shared<HidlHalWrapperV1_2>(std::move(scheduler), halV1_2); } sp<V1_1::IVibrator> halV1_1 = V1_1::IVibrator::castFrom(halV1_0); if (halV1_1) { ALOGV("Successfully converted to Vibrator HAL v1.1 service."); return std::make_shared<HidlHalWrapperV1_1>(std::move(scheduler), halV1_1); } return std::make_shared<HidlHalWrapperV1_0>(std::move(scheduler), halV1_0); } // ------------------------------------------------------------------------------------------------- template <typename T> HalResult<T> HalController::processHalResult(HalResult<T> result, const char* functionName) { if (result.isFailed()) { ALOGE("%s failed: Vibrator HAL not available", functionName); std::lock_guard<std::mutex> lock(mConnectedHalMutex); // Drop HAL handle. This will force future api calls to reconnect. mConnectedHal = nullptr; } return result; } template <typename T> HalResult<T> HalController::apply(HalController::hal_fn<T>& halFn, const char* functionName) { std::shared_ptr<HalWrapper> hal = nullptr; { std::lock_guard<std::mutex> lock(mConnectedHalMutex); if (mConnectedHal == nullptr) { mConnectedHal = mHalConnector->connect(mCallbackScheduler); } hal = mConnectedHal; } if (hal) { return processHalResult(halFn(hal), functionName); } ALOGV("Skipped %s because Vibrator HAL is not available", functionName); return HalResult<T>::unsupported(); } // ------------------------------------------------------------------------------------------------- HalResult<void> HalController::ping() { hal_fn<void> pingFn = [](std::shared_ptr<HalWrapper> hal) { return hal->ping(); }; return apply(pingFn, "ping"); } HalResult<void> HalController::on(milliseconds timeout, const std::function<void()>& completionCallback) { hal_fn<void> onFn = [&](std::shared_ptr<HalWrapper> hal) { return hal->on(timeout, completionCallback); }; return apply(onFn, "on"); } HalResult<void> HalController::off() { hal_fn<void> offFn = [](std::shared_ptr<HalWrapper> hal) { return hal->off(); }; return apply(offFn, "off"); } HalResult<void> HalController::setAmplitude(int32_t amplitude) { hal_fn<void> setAmplitudeFn = [&](std::shared_ptr<HalWrapper> hal) { return hal->setAmplitude(amplitude); }; return apply(setAmplitudeFn, "setAmplitude"); } HalResult<void> HalController::setExternalControl(bool enabled) { hal_fn<void> setExternalControlFn = [&](std::shared_ptr<HalWrapper> hal) { return hal->setExternalControl(enabled); }; return apply(setExternalControlFn, "setExternalControl"); } HalResult<void> HalController::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) { hal_fn<void> alwaysOnEnableFn = [&](std::shared_ptr<HalWrapper> hal) { return hal->alwaysOnEnable(id, effect, strength); }; return apply(alwaysOnEnableFn, "alwaysOnEnable"); } HalResult<void> HalController::alwaysOnDisable(int32_t id) { hal_fn<void> alwaysOnDisableFn = [&](std::shared_ptr<HalWrapper> hal) { return hal->alwaysOnDisable(id); }; return apply(alwaysOnDisableFn, "alwaysOnDisable"); } HalResult<Capabilities> HalController::getCapabilities() { hal_fn<Capabilities> getCapabilitiesFn = [](std::shared_ptr<HalWrapper> hal) { return hal->getCapabilities(); }; return apply(getCapabilitiesFn, "getCapabilities"); } HalResult<std::vector<Effect>> HalController::getSupportedEffects() { hal_fn<std::vector<Effect>> getSupportedEffectsFn = [](std::shared_ptr<HalWrapper> hal) { return hal->getSupportedEffects(); }; return apply(getSupportedEffectsFn, "getSupportedEffects"); } HalResult<milliseconds> HalController::performEffect( Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) { hal_fn<milliseconds> performEffectFn = [&](std::shared_ptr<HalWrapper> hal) { return hal->performEffect(effect, strength, completionCallback); }; return apply(performEffectFn, "performEffect"); } HalResult<void> HalController::performComposedEffect( const std::vector<CompositeEffect>& primitiveEffects, const std::function<void()>& completionCallback) { hal_fn<void> performComposedEffectFn = [&](std::shared_ptr<HalWrapper> hal) { return hal->performComposedEffect(primitiveEffects, completionCallback); }; return apply(performComposedEffectFn, "performComposedEffect"); } }; // namespace vibrator }; // namespace android
services/vibratorservice/VibratorHalWrapper.cpp +0 −27 Original line number Diff line number Diff line Loading @@ -67,21 +67,6 @@ bool isStaticCastValid(Effect effect) { // ------------------------------------------------------------------------------------------------- template <typename T> HalResult<T> HalResult<T>::ok(T value) { return HalResult(value); } template <typename T> HalResult<T> HalResult<T>::failed() { return HalResult(/* unsupported= */ false); } template <typename T> HalResult<T> HalResult<T>::unsupported() { return HalResult(/* unsupported= */ true); } template <typename T> HalResult<T> HalResult<T>::fromStatus(binder::Status status, T data) { if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) { Loading Loading @@ -119,18 +104,6 @@ HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, V1_0::Status sta // ------------------------------------------------------------------------------------------------- HalResult<void> HalResult<void>::ok() { return HalResult(); } HalResult<void> HalResult<void>::failed() { return HalResult(/* failed= */ true); } HalResult<void> HalResult<void>::unsupported() { return HalResult(/* failed= */ false, /* unsupported= */ true); } HalResult<void> HalResult<void>::fromStatus(binder::Status status) { if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) { return HalResult<void>::unsupported(); Loading
services/vibratorservice/include/vibratorservice/VibratorHalController.h 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_OS_VIBRATORHALCONTROLLER_H #define ANDROID_OS_VIBRATORHALCONTROLLER_H #include <android-base/thread_annotations.h> #include <android/hardware/vibrator/IVibrator.h> #include <vibratorservice/VibratorCallbackScheduler.h> #include <vibratorservice/VibratorHalWrapper.h> namespace android { namespace vibrator { // Handles the connection to he underlying HAL implementation available. class HalConnector { public: HalConnector() = default; virtual ~HalConnector() = default; virtual std::shared_ptr<HalWrapper> connect(std::shared_ptr<CallbackScheduler> scheduler); }; // Controller for Vibrator HAL handle. // This relies on HalConnector to connect to the underlying Vibrator HAL service and reconnects to // it after each failed api call. This also ensures connecting to the service is thread-safe. class HalController : public HalWrapper { public: HalController() : HalController(std::make_unique<HalConnector>(), std::make_shared<CallbackScheduler>()) { } HalController(std::unique_ptr<HalConnector> halConnector, std::shared_ptr<CallbackScheduler> callbackScheduler) : HalWrapper(std::move(callbackScheduler)), mHalConnector(std::move(halConnector)), mConnectedHal(nullptr) {} virtual ~HalController() = default; HalResult<void> ping() final override; HalResult<void> on(std::chrono::milliseconds timeout, const std::function<void()>& completionCallback) final override; HalResult<void> off() final override; HalResult<void> setAmplitude(int32_t amplitude) final override; HalResult<void> setExternalControl(bool enabled) final override; HalResult<void> alwaysOnEnable(int32_t id, hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength) final override; HalResult<void> alwaysOnDisable(int32_t id) final override; HalResult<Capabilities> getCapabilities() final override; HalResult<std::vector<hardware::vibrator::Effect>> getSupportedEffects() final override; HalResult<std::chrono::milliseconds> performEffect( hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength, const std::function<void()>& completionCallback) final override; HalResult<void> performComposedEffect( const std::vector<hardware::vibrator::CompositeEffect>& primitiveEffects, const std::function<void()>& completionCallback) final override; private: std::unique_ptr<HalConnector> mHalConnector; std::mutex mConnectedHalMutex; // Shared pointer to allow local copies to be used by different threads. std::shared_ptr<HalWrapper> mConnectedHal GUARDED_BY(mConnectedHalMutex); template <typename T> HalResult<T> processHalResult(HalResult<T> result, const char* functionName); template <typename T> using hal_fn = std::function<HalResult<T>(std::shared_ptr<HalWrapper>)>; template <typename T> HalResult<T> apply(hal_fn<T>& halFn, const char* functionName); }; }; // namespace vibrator }; // namespace android #endif // ANDROID_OS_VIBRATORHALCONTROLLER_H
services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h +14 −15 Original line number Diff line number Diff line Loading @@ -33,9 +33,9 @@ namespace vibrator { template <typename T> class HalResult { public: static HalResult<T> ok(T value); static HalResult<T> failed(); static HalResult<T> unsupported(); static HalResult<T> ok(T value) { return HalResult(value); } static HalResult<T> failed() { return HalResult(/* unsupported= */ false); } static HalResult<T> unsupported() { return HalResult(/* unsupported= */ true); } static HalResult<T> fromStatus(binder::Status status, T data); static HalResult<T> fromStatus(hardware::vibrator::V1_0::Status status, T data); Loading Loading @@ -65,9 +65,11 @@ private: template <> class HalResult<void> { public: static HalResult<void> ok(); static HalResult<void> failed(); static HalResult<void> unsupported(); static HalResult<void> ok() { return HalResult(); } static HalResult<void> failed() { return HalResult(/* failed= */ true); } static HalResult<void> unsupported() { return HalResult(/* failed= */ false, /* unsupported= */ true); } static HalResult<void> fromStatus(binder::Status status); static HalResult<void> fromStatus(hardware::vibrator::V1_0::Status status); Loading Loading @@ -262,9 +264,8 @@ protected: class HidlHalWrapperV1_1 : public HidlHalWrapperV1_0 { public: HidlHalWrapperV1_1(std::shared_ptr<CallbackScheduler> scheduler, sp<hardware::vibrator::V1_0::IVibrator> handleV1_0) : HidlHalWrapperV1_0(std::move(scheduler), handleV1_0), mHandleV1_1(hardware::vibrator::V1_1::IVibrator::castFrom(handleV1_0)) {} sp<hardware::vibrator::V1_1::IVibrator> handle) : HidlHalWrapperV1_0(std::move(scheduler), handle), mHandleV1_1(handle) {} virtual ~HidlHalWrapperV1_1() = default; virtual HalResult<std::chrono::milliseconds> performEffect( Loading @@ -283,9 +284,8 @@ protected: class HidlHalWrapperV1_2 : public HidlHalWrapperV1_1 { public: HidlHalWrapperV1_2(std::shared_ptr<CallbackScheduler> scheduler, sp<hardware::vibrator::V1_0::IVibrator> handleV1_0) : HidlHalWrapperV1_1(std::move(scheduler), handleV1_0), mHandleV1_2(hardware::vibrator::V1_2::IVibrator::castFrom(handleV1_0)) {} sp<hardware::vibrator::V1_2::IVibrator> handle) : HidlHalWrapperV1_1(std::move(scheduler), handle), mHandleV1_2(handle) {} virtual ~HidlHalWrapperV1_2() = default; virtual HalResult<std::chrono::milliseconds> performEffect( Loading @@ -304,9 +304,8 @@ protected: class HidlHalWrapperV1_3 : public HidlHalWrapperV1_2 { public: HidlHalWrapperV1_3(std::shared_ptr<CallbackScheduler> scheduler, sp<hardware::vibrator::V1_0::IVibrator> handleV1_0) : HidlHalWrapperV1_2(std::move(scheduler), handleV1_0), mHandleV1_3(hardware::vibrator::V1_3::IVibrator::castFrom(handleV1_0)) {} sp<hardware::vibrator::V1_3::IVibrator> handle) : HidlHalWrapperV1_2(std::move(scheduler), handle), mHandleV1_3(handle) {} virtual ~HidlHalWrapperV1_3() = default; virtual HalResult<void> setExternalControl(bool enabled) override; Loading