aboutsummaryrefslogtreecommitdiff
path: root/host/common/st_hal_lpma_handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'host/common/st_hal_lpma_handler.cc')
-rw-r--r--host/common/st_hal_lpma_handler.cc210
1 files changed, 0 insertions, 210 deletions
diff --git a/host/common/st_hal_lpma_handler.cc b/host/common/st_hal_lpma_handler.cc
deleted file mode 100644
index 29e0e51c..00000000
--- a/host/common/st_hal_lpma_handler.cc
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * 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.
- */
-
-#include <cinttypes>
-
-#include "chre_host/st_hal_lpma_handler.h"
-
-namespace android {
-namespace chre {
-
-namespace {
-
-constexpr char kChreWakeLockName[] = "chre_daemon";
-
-void acquireWakeLock() {
- int rc;
- if ((rc = acquire_wake_lock(PARTIAL_WAKE_LOCK, kChreWakeLockName)) != 0) {
- LOGE("Failed to acquire wakelock (err %d)", rc);
- }
-}
-
-void releaseWakeLock() {
- int rc;
- static bool wakeLockInitialRelease = true;
-
- // It's expected to get an error when we first try to release the
- // wakelock
- // as it won't exist unless it was leaked previously - don't output a
- // false warning for this case
- if (((rc = release_wake_lock(kChreWakeLockName)) != 0) &&
- !wakeLockInitialRelease) {
- LOGE("Failed to release wakelock (err %d)", rc);
- }
-
- wakeLockInitialRelease = false;
-}
-
-} // anonymous namespace
-
-StHalLpmaHandler::StHalLpmaHandler(bool allowed) : mIsLpmaAllowed(allowed) {
- auto cb = [&]() { onStHalServiceDeath(); };
- mDeathRecipient = new StHalDeathRecipient(cb);
-}
-
-void StHalLpmaHandler::init() {
- if (mIsLpmaAllowed) {
- mThread = std::thread(&StHalLpmaHandler::StHalLpmaHandlerThreadEntry, this);
- }
-}
-
-void StHalLpmaHandler::enable(bool enabled) {
- if (mIsLpmaAllowed) {
- std::lock_guard<std::mutex> lock(mMutex);
- mTargetLpmaEnabled = enabled;
- mCondVarPredicate = true;
- mCondVar.notify_one();
- } else {
- LOGE("Trying to modify LPMA state when LPMA is disabled");
- }
-}
-
-bool StHalLpmaHandler::load() {
- constexpr uint8_t kUuidNode[] = {0x2E, 0x95, 0xA2, 0x31, 0x3A, 0xEE};
-
- LOGV("Loading LPMA");
-
- ISoundTriggerHw::SoundModel soundModel;
- soundModel.type = SoundModelType::GENERIC;
- soundModel.vendorUuid.timeLow = 0x57CADDB1;
- soundModel.vendorUuid.timeMid = 0xACDB;
- soundModel.vendorUuid.versionAndTimeHigh = 0x4DCE;
- soundModel.vendorUuid.variantAndClockSeqHigh = 0x8CB0;
-
- memcpy(&soundModel.vendorUuid.node[0], kUuidNode, sizeof(kUuidNode));
- soundModel.data.resize(1); // Insert an empty byte to bypass HAL NULL checks.
-
- bool loaded = false;
- checkConnectionToStHalServiceLocked();
- int32_t loadResult;
- Return<void> hidlResult = mStHalService->loadSoundModel(
- soundModel, nullptr /* callback */, 0 /* cookie */,
- [&](int32_t retval, SoundModelHandle handle) {
- loadResult = retval;
- mLpmaHandle = handle;
- });
-
- if (hidlResult.isOk()) {
- if (loadResult == 0) {
- LOGD("Loaded LPMA");
- loaded = true;
- } else {
- LOGE("Failed to load LPMA with %" PRId32, loadResult);
- }
- } else {
- LOGE("Failed to load LPMA due to hidl error %s",
- hidlResult.description().c_str());
- }
-
- return loaded;
-}
-
-void StHalLpmaHandler::unload() {
- checkConnectionToStHalServiceLocked();
- Return<int32_t> hidlResult = mStHalService->unloadSoundModel(mLpmaHandle);
- mLpmaHandle = 0;
-
- if (hidlResult.isOk()) {
- if (hidlResult != 0) {
- LOGE("Failed to unload LPMA with %" PRId32, int32_t(hidlResult));
- }
- } else {
- LOGE("Failed to unload LPMA due to hidl error %s",
- hidlResult.description().c_str());
- }
-}
-
-void StHalLpmaHandler::checkConnectionToStHalServiceLocked() {
- if (mStHalService == nullptr) {
- mStHalService = ISoundTriggerHw::getService();
- if (mStHalService != nullptr) {
- LOGI("Connected to ST HAL service");
- mStHalService->linkToDeath(mDeathRecipient, 0 /* flags */);
- }
- }
-}
-
-bool StHalLpmaHandler::waitOnStHalRequestAndProcess() {
- bool noDelayNeeded = true;
- std::unique_lock<std::mutex> lock(mMutex);
-
- if (mCurrentLpmaEnabled == mTargetLpmaEnabled) {
- mRetryDelay = 0;
- mRetryCount = 0;
- releaseWakeLock(); // Allow the system to suspend while waiting.
- mCondVar.wait(lock, [this] { return mCondVarPredicate; });
- mCondVarPredicate = false;
- acquireWakeLock(); // Ensure the system stays up while retrying.
- } else if (mTargetLpmaEnabled && load()) {
- mCurrentLpmaEnabled = mTargetLpmaEnabled;
- } else if (!mTargetLpmaEnabled) {
- // Regardless of whether the use case fails to unload, set the
- // currentLpmaEnabled to the targetLpmaEnabled. This will allow the next
- // enable request to proceed. After a failure to unload occurs, the
- // supplied handle is invalid and should not be unloaded again.
- unload();
- mCurrentLpmaEnabled = mTargetLpmaEnabled;
- } else {
- noDelayNeeded = false;
- }
-
- return noDelayNeeded;
-}
-
-void StHalLpmaHandler::delay() {
- constexpr useconds_t kInitialRetryDelayUs = 500000;
- constexpr int kRetryGrowthFactor = 2;
- constexpr int kRetryGrowthLimit = 5; // Terminates at 8s retry interval.
- constexpr int kRetryWakeLockLimit = 10; // Retry with a wakelock 10 times.
-
- if (mRetryDelay == 0) {
- mRetryDelay = kInitialRetryDelayUs;
- } else if (mRetryCount < kRetryGrowthLimit) {
- mRetryDelay *= kRetryGrowthFactor;
- }
- usleep(mRetryDelay);
- mRetryCount++;
- if (mRetryCount > kRetryWakeLockLimit) {
- releaseWakeLock();
- }
-}
-
-void StHalLpmaHandler::StHalLpmaHandlerThreadEntry() {
- LOGD("Starting LPMA thread");
-
- while (true) {
- if (!waitOnStHalRequestAndProcess()) {
- // processing an LPMA state update failed, retry after a little while
- delay();
- }
- }
-}
-
-void StHalLpmaHandler::onStHalServiceDeath() {
- LOGE("ST HAL Service Died");
- std::lock_guard<std::mutex> lock(mMutex);
- mStHalService = nullptr;
- if (mTargetLpmaEnabled) {
- // ST HAL has died, so assume that the sound model is no longer active,
- // and trigger a reload of the sound model.
- mCurrentLpmaEnabled = false;
- mCondVarPredicate = true;
- mCondVar.notify_one();
- }
-}
-
-} // namespace chre
-} // namespace android