You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
5.0 KiB
149 lines
5.0 KiB
/*
|
|
* 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> connectManagerHal(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), hal);
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
// -------------------------------------------------------------------------------------------------
|
|
|
|
void ManagerHalController::init() {
|
|
std::lock_guard<std::mutex> lock(mConnectedHalMutex);
|
|
if (mConnectedHal == nullptr) {
|
|
mConnectedHal = mConnector(mCallbackScheduler);
|
|
}
|
|
}
|
|
|
|
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
|