Loading services/vibratorservice/VibratorHalController.cpp +4 −4 Original line number Diff line number Diff line Loading @@ -46,7 +46,7 @@ namespace vibrator { // ------------------------------------------------------------------------------------------------- std::shared_ptr<HalWrapper> HalConnector::connect(std::shared_ptr<CallbackScheduler> scheduler) { std::shared_ptr<HalWrapper> connectHal(std::shared_ptr<CallbackScheduler> scheduler) { static bool gHalExists = true; if (!gHalExists) { // We already tried to connect to all of the vibrator HAL versions and none was available. Loading Loading @@ -106,7 +106,7 @@ HalResult<T> HalController::apply(HalController::hal_fn<T>& halFn, const char* f std::lock_guard<std::mutex> lock(mConnectedHalMutex); if (mConnectedHal == nullptr) { // Init was never called, so connect to HAL for the first time during this call. mConnectedHal = mHalConnector->connect(mCallbackScheduler); mConnectedHal = mConnector(mCallbackScheduler); if (mConnectedHal == nullptr) { ALOGV("Skipped %s because Vibrator HAL is not available", functionName); Loading @@ -129,7 +129,7 @@ HalResult<T> HalController::apply(HalController::hal_fn<T>& halFn, const char* f bool HalController::init() { std::lock_guard<std::mutex> lock(mConnectedHalMutex); if (mConnectedHal == nullptr) { mConnectedHal = mHalConnector->connect(mCallbackScheduler); mConnectedHal = mConnector(mCallbackScheduler); } return mConnectedHal != nullptr; } Loading @@ -142,7 +142,7 @@ HalResult<void> HalController::ping() { void HalController::tryReconnect() { std::lock_guard<std::mutex> lock(mConnectedHalMutex); if (mConnectedHal == nullptr) { mConnectedHal = mHalConnector->connect(mCallbackScheduler); mConnectedHal = mConnector(mCallbackScheduler); } else { mConnectedHal->tryReconnect(); } Loading services/vibratorservice/VibratorManagerHalController.cpp 0 → 100644 +149 −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 "VibratorManagerHalController" #include <utils/Log.h> #include <vibratorservice/VibratorManagerHalController.h> namespace Aidl = android::hardware::vibrator; namespace android { namespace vibrator { std::shared_ptr<ManagerHalWrapper> connectHal(std::shared_ptr<CallbackScheduler> scheduler) { static bool gHalExists = true; if (gHalExists) { sp<Aidl::IVibratorManager> hal = waitForVintfService<Aidl::IVibratorManager>(); if (hal) { ALOGV("Successfully connected to VibratorManager HAL AIDL service."); return std::make_shared<AidlManagerHalWrapper>(std::move(scheduler), aidlHal); } } gHalExists = false; return std::make_shared<LegacyManagerHalWrapper>(); } static constexpr int MAX_RETRIES = 1; template <typename T> HalResult<T> ManagerHalController::processHalResult(HalResult<T> result, const char* functionName) { if (result.isFailed()) { ALOGE("%s failed: %s", functionName, result.errorMessage()); std::lock_guard<std::mutex> lock(mConnectedHalMutex); mConnectedHal->tryReconnect(); } return result; } template <typename T> HalResult<T> ManagerHalController::apply(ManagerHalController::hal_fn<T>& halFn, const char* functionName) { std::shared_ptr<ManagerHalWrapper> hal = nullptr; { std::lock_guard<std::mutex> lock(mConnectedHalMutex); if (mConnectedHal == nullptr) { // Init was never called, so connect to HAL for the first time during this call. mConnectedHal = mConnector(mCallbackScheduler); if (mConnectedHal == nullptr) { ALOGV("Skipped %s because VibratorManager HAL is not available", functionName); return HalResult<T>::unsupported(); } } hal = mConnectedHal; } HalResult<T> ret = processHalResult(halFn(hal), functionName); for (int i = 0; i < MAX_RETRIES && ret.isFailed(); i++) { ret = processHalResult(halFn(hal), functionName); } return ret; } // ------------------------------------------------------------------------------------------------- bool ManagerHalController::init() { std::lock_guard<std::mutex> lock(mConnectedHalMutex); if (mConnectedHal == nullptr) { mConnectedHal = mConnector(mCallbackScheduler); } return mConnectedHal != nullptr; } HalResult<void> ManagerHalController::ping() { hal_fn<void> pingFn = [](std::shared_ptr<ManagerHalWrapper> hal) { return hal->ping(); }; return apply(pingFn, "ping"); } void ManagerHalController::tryReconnect() { std::lock_guard<std::mutex> lock(mConnectedHalMutex); if (mConnectedHal == nullptr) { mConnectedHal = mConnector(mCallbackScheduler); } else { mConnectedHal->tryReconnect(); } } HalResult<ManagerCapabilities> ManagerHalController::getCapabilities() { hal_fn<ManagerCapabilities> getCapabilitiesFn = [](std::shared_ptr<ManagerHalWrapper> hal) { return hal->getCapabilities(); }; return apply(getCapabilitiesFn, "getCapabilities"); } HalResult<std::vector<int32_t>> ManagerHalController::getVibratorIds() { hal_fn<std::vector<int32_t>> getVibratorIdsFn = [](std::shared_ptr<ManagerHalWrapper> hal) { return hal->getVibratorIds(); }; return apply(getVibratorIdsFn, "getVibratorIds"); } HalResult<std::shared_ptr<HalController>> ManagerHalController::getVibrator(int32_t id) { hal_fn<std::shared_ptr<HalController>> getVibratorFn = [&](std::shared_ptr<ManagerHalWrapper> hal) { return hal->getVibrator(id); }; return apply(getVibratorFn, "getVibrator"); } HalResult<void> ManagerHalController::prepareSynced(const std::vector<int32_t>& ids) { hal_fn<void> prepareSyncedFn = [&](std::shared_ptr<ManagerHalWrapper> hal) { return hal->prepareSynced(ids); }; return apply(prepareSyncedFn, "prepareSynced"); } HalResult<void> ManagerHalController::triggerSynced( const std::function<void()>& completionCallback) { hal_fn<void> triggerSyncedFn = [&](std::shared_ptr<ManagerHalWrapper> hal) { return hal->triggerSynced(completionCallback); }; return apply(triggerSyncedFn, "triggerSynced"); } HalResult<void> ManagerHalController::cancelSynced() { hal_fn<void> cancelSyncedFn = [](std::shared_ptr<ManagerHalWrapper> hal) { return hal->cancelSynced(); }; return apply(cancelSyncedFn, "cancelSynced"); } }; // namespace vibrator }; // namespace android services/vibratorservice/VibratorManagerHalWrapper.cpp +8 −7 Original line number Diff line number Diff line Loading @@ -72,11 +72,11 @@ HalResult<void> LegacyManagerHalWrapper::cancelSynced() { // ------------------------------------------------------------------------------------------------- std::shared_ptr<HalWrapper> AidlManagerHalWrapper::ManagedHalConnector::connect( std::shared_ptr<CallbackScheduler> callbackScheduler) { std::function<HalResult<sp<Aidl::IVibrator>>()> reconnectFn = [&]() { std::shared_ptr<HalWrapper> AidlManagerHalWrapper::connectToVibrator( int32_t vibratorId, 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); auto result = this->getHal()->getVibrator(vibratorId, &vibrator); return HalResult<sp<Aidl::IVibrator>>::fromStatus(result, vibrator); }; auto result = reconnectFn(); Loading Loading @@ -133,9 +133,10 @@ HalResult<std::vector<int32_t>> AidlManagerHalWrapper::getVibratorIds() { // 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); HalController::Connector connector = [&, id](auto scheduler) { return this->connectToVibrator(id, scheduler); }; auto controller = std::make_unique<HalController>(mCallbackScheduler, connector); mVibrators[id] = std::move(controller); } } Loading services/vibratorservice/include/vibratorservice/VibratorHalController.h +10 −17 Original line number Diff line number Diff line Loading @@ -27,27 +27,20 @@ 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); }; std::shared_ptr<HalWrapper> connectHal(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. // This relies on a given Connector to connect to the underlying Vibrator HAL service and reconnects // 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) using Connector = std::function<std::shared_ptr<HalWrapper>(std::shared_ptr<CallbackScheduler>)>; HalController() : HalController(std::make_shared<CallbackScheduler>(), &connectHal) {} HalController(std::shared_ptr<CallbackScheduler> callbackScheduler, Connector connector) : HalWrapper(std::move(callbackScheduler)), mHalConnector(std::move(halConnector)), mConnector(connector), mConnectedHal(nullptr) {} virtual ~HalController() = default; Loading Loading @@ -89,7 +82,7 @@ public: const std::function<void()>& completionCallback) final override; private: std::unique_ptr<HalConnector> mHalConnector; Connector mConnector; std::mutex mConnectedHalMutex; // Shared pointer to allow local copies to be used by different threads. std::shared_ptr<HalWrapper> mConnectedHal GUARDED_BY(mConnectedHalMutex); Loading services/vibratorservice/include/vibratorservice/VibratorManagerHalController.h 0 → 100644 +85 −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_VIBRATOR_MANAGER_HAL_CONTROLLER_H #define ANDROID_OS_VIBRATOR_MANAGER_HAL_CONTROLLER_H #include <android/hardware/vibrator/IVibratorManager.h> #include <vibratorservice/VibratorHalController.h> #include <unordered_map> namespace android { namespace vibrator { std::shared_ptr<ManagerHalWrapper> connectManagerHal(std::shared_ptr<CallbackScheduler> scheduler); // Controller for VibratorManager HAL handle. class ManagerHalController : public ManagerHalWrapper { public: using Connector = std::function<std::shared_ptr<ManagerHalWrapper>(std::shared_ptr<CallbackScheduler>)>; ManagerHalController() : ManagerHalController(std::make_shared<CallbackScheduler>(), &connectManagerHal) {} ManagerHalController(std::shared_ptr<CallbackScheduler> callbackScheduler, Connector connector) : mConnector(connector), mConnectedHal(nullptr) {} virtual ~ManagerHalController() = default; /* Connects to the HAL service, possibly waiting for the registered service to * become available. This will automatically be called at the first API usage if it was not * manually called beforehand. Calling this manually during the setup phase can avoid slowing * the first API call later on. This will fallback to a legacy manager implementation if the * service is not available. */ virtual void init(); /* reloads HAL service instance without waiting. This relies on the HAL found by init() * to rapidly reconnect to the specific HAL service, or defers to init() if it was never called. */ void tryReconnect() override final; HalResult<void> ping() override final; HalResult<ManagerCapabilities> getCapabilities() override final; HalResult<std::vector<int32_t>> getVibratorIds() override final; HalResult<std::shared_ptr<HalController>> getVibrator(int32_t id) override final; HalResult<void> prepareSynced(const std::vector<int32_t>& ids) override final; HalResult<void> triggerSynced(const std::function<void()>& completionCallback) override final; HalResult<void> cancelSynced() override final; private: Connector mConnector; 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<ManagerHalWrapper>)>; template <typename T> HalResult<T> apply(hal_fn<T>& halFn, const char* functionName); }; }; // namespace vibrator }; // namespace android #endif // ANDROID_OS_VIBRATOR_MANAGER_HAL_CONTROLLER_H Loading
services/vibratorservice/VibratorHalController.cpp +4 −4 Original line number Diff line number Diff line Loading @@ -46,7 +46,7 @@ namespace vibrator { // ------------------------------------------------------------------------------------------------- std::shared_ptr<HalWrapper> HalConnector::connect(std::shared_ptr<CallbackScheduler> scheduler) { std::shared_ptr<HalWrapper> connectHal(std::shared_ptr<CallbackScheduler> scheduler) { static bool gHalExists = true; if (!gHalExists) { // We already tried to connect to all of the vibrator HAL versions and none was available. Loading Loading @@ -106,7 +106,7 @@ HalResult<T> HalController::apply(HalController::hal_fn<T>& halFn, const char* f std::lock_guard<std::mutex> lock(mConnectedHalMutex); if (mConnectedHal == nullptr) { // Init was never called, so connect to HAL for the first time during this call. mConnectedHal = mHalConnector->connect(mCallbackScheduler); mConnectedHal = mConnector(mCallbackScheduler); if (mConnectedHal == nullptr) { ALOGV("Skipped %s because Vibrator HAL is not available", functionName); Loading @@ -129,7 +129,7 @@ HalResult<T> HalController::apply(HalController::hal_fn<T>& halFn, const char* f bool HalController::init() { std::lock_guard<std::mutex> lock(mConnectedHalMutex); if (mConnectedHal == nullptr) { mConnectedHal = mHalConnector->connect(mCallbackScheduler); mConnectedHal = mConnector(mCallbackScheduler); } return mConnectedHal != nullptr; } Loading @@ -142,7 +142,7 @@ HalResult<void> HalController::ping() { void HalController::tryReconnect() { std::lock_guard<std::mutex> lock(mConnectedHalMutex); if (mConnectedHal == nullptr) { mConnectedHal = mHalConnector->connect(mCallbackScheduler); mConnectedHal = mConnector(mCallbackScheduler); } else { mConnectedHal->tryReconnect(); } Loading
services/vibratorservice/VibratorManagerHalController.cpp 0 → 100644 +149 −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 "VibratorManagerHalController" #include <utils/Log.h> #include <vibratorservice/VibratorManagerHalController.h> namespace Aidl = android::hardware::vibrator; namespace android { namespace vibrator { std::shared_ptr<ManagerHalWrapper> connectHal(std::shared_ptr<CallbackScheduler> scheduler) { static bool gHalExists = true; if (gHalExists) { sp<Aidl::IVibratorManager> hal = waitForVintfService<Aidl::IVibratorManager>(); if (hal) { ALOGV("Successfully connected to VibratorManager HAL AIDL service."); return std::make_shared<AidlManagerHalWrapper>(std::move(scheduler), aidlHal); } } gHalExists = false; return std::make_shared<LegacyManagerHalWrapper>(); } static constexpr int MAX_RETRIES = 1; template <typename T> HalResult<T> ManagerHalController::processHalResult(HalResult<T> result, const char* functionName) { if (result.isFailed()) { ALOGE("%s failed: %s", functionName, result.errorMessage()); std::lock_guard<std::mutex> lock(mConnectedHalMutex); mConnectedHal->tryReconnect(); } return result; } template <typename T> HalResult<T> ManagerHalController::apply(ManagerHalController::hal_fn<T>& halFn, const char* functionName) { std::shared_ptr<ManagerHalWrapper> hal = nullptr; { std::lock_guard<std::mutex> lock(mConnectedHalMutex); if (mConnectedHal == nullptr) { // Init was never called, so connect to HAL for the first time during this call. mConnectedHal = mConnector(mCallbackScheduler); if (mConnectedHal == nullptr) { ALOGV("Skipped %s because VibratorManager HAL is not available", functionName); return HalResult<T>::unsupported(); } } hal = mConnectedHal; } HalResult<T> ret = processHalResult(halFn(hal), functionName); for (int i = 0; i < MAX_RETRIES && ret.isFailed(); i++) { ret = processHalResult(halFn(hal), functionName); } return ret; } // ------------------------------------------------------------------------------------------------- bool ManagerHalController::init() { std::lock_guard<std::mutex> lock(mConnectedHalMutex); if (mConnectedHal == nullptr) { mConnectedHal = mConnector(mCallbackScheduler); } return mConnectedHal != nullptr; } HalResult<void> ManagerHalController::ping() { hal_fn<void> pingFn = [](std::shared_ptr<ManagerHalWrapper> hal) { return hal->ping(); }; return apply(pingFn, "ping"); } void ManagerHalController::tryReconnect() { std::lock_guard<std::mutex> lock(mConnectedHalMutex); if (mConnectedHal == nullptr) { mConnectedHal = mConnector(mCallbackScheduler); } else { mConnectedHal->tryReconnect(); } } HalResult<ManagerCapabilities> ManagerHalController::getCapabilities() { hal_fn<ManagerCapabilities> getCapabilitiesFn = [](std::shared_ptr<ManagerHalWrapper> hal) { return hal->getCapabilities(); }; return apply(getCapabilitiesFn, "getCapabilities"); } HalResult<std::vector<int32_t>> ManagerHalController::getVibratorIds() { hal_fn<std::vector<int32_t>> getVibratorIdsFn = [](std::shared_ptr<ManagerHalWrapper> hal) { return hal->getVibratorIds(); }; return apply(getVibratorIdsFn, "getVibratorIds"); } HalResult<std::shared_ptr<HalController>> ManagerHalController::getVibrator(int32_t id) { hal_fn<std::shared_ptr<HalController>> getVibratorFn = [&](std::shared_ptr<ManagerHalWrapper> hal) { return hal->getVibrator(id); }; return apply(getVibratorFn, "getVibrator"); } HalResult<void> ManagerHalController::prepareSynced(const std::vector<int32_t>& ids) { hal_fn<void> prepareSyncedFn = [&](std::shared_ptr<ManagerHalWrapper> hal) { return hal->prepareSynced(ids); }; return apply(prepareSyncedFn, "prepareSynced"); } HalResult<void> ManagerHalController::triggerSynced( const std::function<void()>& completionCallback) { hal_fn<void> triggerSyncedFn = [&](std::shared_ptr<ManagerHalWrapper> hal) { return hal->triggerSynced(completionCallback); }; return apply(triggerSyncedFn, "triggerSynced"); } HalResult<void> ManagerHalController::cancelSynced() { hal_fn<void> cancelSyncedFn = [](std::shared_ptr<ManagerHalWrapper> hal) { return hal->cancelSynced(); }; return apply(cancelSyncedFn, "cancelSynced"); } }; // namespace vibrator }; // namespace android
services/vibratorservice/VibratorManagerHalWrapper.cpp +8 −7 Original line number Diff line number Diff line Loading @@ -72,11 +72,11 @@ HalResult<void> LegacyManagerHalWrapper::cancelSynced() { // ------------------------------------------------------------------------------------------------- std::shared_ptr<HalWrapper> AidlManagerHalWrapper::ManagedHalConnector::connect( std::shared_ptr<CallbackScheduler> callbackScheduler) { std::function<HalResult<sp<Aidl::IVibrator>>()> reconnectFn = [&]() { std::shared_ptr<HalWrapper> AidlManagerHalWrapper::connectToVibrator( int32_t vibratorId, 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); auto result = this->getHal()->getVibrator(vibratorId, &vibrator); return HalResult<sp<Aidl::IVibrator>>::fromStatus(result, vibrator); }; auto result = reconnectFn(); Loading Loading @@ -133,9 +133,10 @@ HalResult<std::vector<int32_t>> AidlManagerHalWrapper::getVibratorIds() { // 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); HalController::Connector connector = [&, id](auto scheduler) { return this->connectToVibrator(id, scheduler); }; auto controller = std::make_unique<HalController>(mCallbackScheduler, connector); mVibrators[id] = std::move(controller); } } Loading
services/vibratorservice/include/vibratorservice/VibratorHalController.h +10 −17 Original line number Diff line number Diff line Loading @@ -27,27 +27,20 @@ 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); }; std::shared_ptr<HalWrapper> connectHal(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. // This relies on a given Connector to connect to the underlying Vibrator HAL service and reconnects // 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) using Connector = std::function<std::shared_ptr<HalWrapper>(std::shared_ptr<CallbackScheduler>)>; HalController() : HalController(std::make_shared<CallbackScheduler>(), &connectHal) {} HalController(std::shared_ptr<CallbackScheduler> callbackScheduler, Connector connector) : HalWrapper(std::move(callbackScheduler)), mHalConnector(std::move(halConnector)), mConnector(connector), mConnectedHal(nullptr) {} virtual ~HalController() = default; Loading Loading @@ -89,7 +82,7 @@ public: const std::function<void()>& completionCallback) final override; private: std::unique_ptr<HalConnector> mHalConnector; Connector mConnector; std::mutex mConnectedHalMutex; // Shared pointer to allow local copies to be used by different threads. std::shared_ptr<HalWrapper> mConnectedHal GUARDED_BY(mConnectedHalMutex); Loading
services/vibratorservice/include/vibratorservice/VibratorManagerHalController.h 0 → 100644 +85 −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_VIBRATOR_MANAGER_HAL_CONTROLLER_H #define ANDROID_OS_VIBRATOR_MANAGER_HAL_CONTROLLER_H #include <android/hardware/vibrator/IVibratorManager.h> #include <vibratorservice/VibratorHalController.h> #include <unordered_map> namespace android { namespace vibrator { std::shared_ptr<ManagerHalWrapper> connectManagerHal(std::shared_ptr<CallbackScheduler> scheduler); // Controller for VibratorManager HAL handle. class ManagerHalController : public ManagerHalWrapper { public: using Connector = std::function<std::shared_ptr<ManagerHalWrapper>(std::shared_ptr<CallbackScheduler>)>; ManagerHalController() : ManagerHalController(std::make_shared<CallbackScheduler>(), &connectManagerHal) {} ManagerHalController(std::shared_ptr<CallbackScheduler> callbackScheduler, Connector connector) : mConnector(connector), mConnectedHal(nullptr) {} virtual ~ManagerHalController() = default; /* Connects to the HAL service, possibly waiting for the registered service to * become available. This will automatically be called at the first API usage if it was not * manually called beforehand. Calling this manually during the setup phase can avoid slowing * the first API call later on. This will fallback to a legacy manager implementation if the * service is not available. */ virtual void init(); /* reloads HAL service instance without waiting. This relies on the HAL found by init() * to rapidly reconnect to the specific HAL service, or defers to init() if it was never called. */ void tryReconnect() override final; HalResult<void> ping() override final; HalResult<ManagerCapabilities> getCapabilities() override final; HalResult<std::vector<int32_t>> getVibratorIds() override final; HalResult<std::shared_ptr<HalController>> getVibrator(int32_t id) override final; HalResult<void> prepareSynced(const std::vector<int32_t>& ids) override final; HalResult<void> triggerSynced(const std::function<void()>& completionCallback) override final; HalResult<void> cancelSynced() override final; private: Connector mConnector; 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<ManagerHalWrapper>)>; template <typename T> HalResult<T> apply(hal_fn<T>& halFn, const char* functionName); }; }; // namespace vibrator }; // namespace android #endif // ANDROID_OS_VIBRATOR_MANAGER_HAL_CONTROLLER_H