Snap for 4826885 from 39aa44f56fe42b186b20305f912d93abf27c801f to pi-release
Change-Id: I6ccd998a22098f2754199855c22e65301005bbd0
diff --git a/host/msm/daemon/chre_daemon.cc b/host/msm/daemon/chre_daemon.cc
index 098d7fa..4194659 100644
--- a/host/msm/daemon/chre_daemon.cc
+++ b/host/msm/daemon/chre_daemon.cc
@@ -98,6 +98,15 @@
void *arg);
#ifdef CHRE_DAEMON_LPMA_ENABLED
+//! The name of the wakelock to use for the CHRE daemon.
+static const char kWakeLockName[] = "chre_daemon";
+
+//! The file descriptor to wake lock.
+static int gWakeLockFd = -1;
+
+//! The file descriptor to wake unlock.
+static int gWakeUnlockFd = -1;
+
struct LpmaEnableThreadData {
pthread_t thread;
pthread_mutex_t mutex;
@@ -269,6 +278,58 @@
#ifdef CHRE_DAEMON_LPMA_ENABLED
/**
+ * Initializes the wakelock file descriptors used to acquire/release wakelocks
+ * for CHRE.
+ */
+static void initWakeLockFds() {
+ const char kWakeLockPath[] = "/sys/power/wake_lock";
+ const char kWakeUnlockPath[] = "/sys/power/wake_unlock";
+
+ bool success = false;
+ if ((gWakeLockFd = open(kWakeLockPath, O_RDWR | O_CLOEXEC)) < 0) {
+ LOGE("Failed to open wake lock file with %s", strerror(errno));
+ } else if ((gWakeUnlockFd = open(kWakeUnlockPath, O_RDWR | O_CLOEXEC)) < 0) {
+ close(gWakeLockFd);
+ LOGE("Failed to open wake unlock file with %s", strerror(errno));
+ } else {
+ success = true;
+ }
+
+ if (!success) {
+ gWakeLockFd = -1;
+ gWakeUnlockFd = -1;
+ }
+}
+
+static void acquireWakeLock() {
+ if (gWakeLockFd < 0) {
+ LOGW("Failing to acquire wakelock due to invalid file descriptor");
+ } else {
+ const size_t len = strlen(kWakeLockName);
+ ssize_t result = write(gWakeLockFd, kWakeLockName, len);
+ if (result < 0) {
+ LOGE("Failed to acquire wakelock with error %s", strerror(errno));
+ } else if (result != static_cast<ssize_t>(len)) {
+ LOGE("Wrote incomplete id to wakelock file descriptor");
+ }
+ }
+}
+
+static void releaseWakeLock() {
+ if (gWakeUnlockFd < 0) {
+ LOGW("Failed to release wakelock due to invalid file descriptor");
+ } else {
+ const size_t len = strlen(kWakeLockName);
+ ssize_t result = write(gWakeUnlockFd, kWakeLockName, len);
+ if (result < 0) {
+ LOGE("Failed to release wakelock with error %s", strerror(errno));
+ } else if (result != static_cast<ssize_t>(len)) {
+ LOGE("Wrote incomplete id to wakeunlock file descriptor");
+ }
+ }
+}
+
+/**
* Sets the target state for LPMA to be enabled. This triggers another thread to
* perform the async operation of enabling or disabling the LPMA use case.
*
@@ -289,7 +350,7 @@
* @return true if LPMA was enabled successfully, false otherwise.
*/
static bool loadLpma(SoundModelHandle *lpmaHandle) {
- LOGD("Loading LMPA");
+ LOGD("Loading LPMA");
ISoundTriggerHw::SoundModel soundModel;
soundModel.type = SoundModelType::GENERIC;
@@ -370,6 +431,7 @@
const useconds_t kInitialRetryDelayUs = 500000;
const int kRetryGrowthFactor = 2;
const int kRetryGrowthLimit = 5; // Terminates at 8s retry interval.
+ const int kRetryWakeLockLimit = 10; // Retry with a wakelock 10 times.
int retryCount = 0;
useconds_t retryDelay = 0;
@@ -380,7 +442,9 @@
if (state->currentLpmaEnabled == state->targetLpmaEnabled) {
retryCount = 0;
retryDelay = 0;
+ releaseWakeLock(); // Allow the system to suspend while waiting.
pthread_cond_wait(&state->cond, &state->mutex);
+ acquireWakeLock(); // Ensure the system stays up while retrying.
} else if ((state->targetLpmaEnabled && loadLpma(&lpmaHandle))
|| (!state->targetLpmaEnabled && unloadLpma(lpmaHandle))) {
state->currentLpmaEnabled = state->targetLpmaEnabled;
@@ -397,7 +461,12 @@
LOGD("Delaying retry %d for %uus", retryCount, retryDelay);
usleep(retryDelay);
+
retryCount++;
+ if (retryCount > kRetryWakeLockLimit) {
+ releaseWakeLock();
+ }
+
pthread_mutex_lock(&state->mutex);
}
@@ -622,6 +691,10 @@
struct reverse_monitor_thread_data reverse_monitor;
::android::chre::SocketServer server;
+#ifdef CHRE_DAEMON_LPMA_ENABLED
+ initWakeLockFds();
+#endif // CHRE_DAEMON_LPMA_ENABLED
+
if (!init_reverse_monitor(&reverse_monitor)) {
LOGE("Couldn't initialize reverse monitor");
#ifdef CHRE_DAEMON_LPMA_ENABLED
diff --git a/platform/slpi/include/chre/platform/slpi/see/see_helper.h b/platform/slpi/include/chre/platform/slpi/see/see_helper.h
index 179691b..6854e8c 100644
--- a/platform/slpi/include/chre/platform/slpi/see/see_helper.h
+++ b/platform/slpi/include/chre/platform/slpi/see/see_helper.h
@@ -138,8 +138,20 @@
* @return true if at least minNumSuids were successfully found
*/
bool findSuidSync(const char *dataType, DynamicVector<sns_std_suid> *suids,
- uint8_t minNumSuids = 1, uint32_t maxRetries = 20,
- Milliseconds retryDelay = Milliseconds(500));
+ uint8_t minNumSuids, uint32_t maxRetries,
+ Milliseconds retryDelay);
+
+ /**
+ * Version of findSuidSync providing default timeout/retry behavior.
+ *
+ * @see findSuidSync
+ */
+ bool findSuidSync(const char *dataType, DynamicVector<sns_std_suid> *suids,
+ uint8_t minNumSuids = 1) {
+ uint32_t maxRetries = (mHaveTimedOutOnSuidLookup) ? 0 : 40;
+ return findSuidSync(dataType, suids, minNumSuids, maxRetries,
+ Milliseconds(250) /* retryDelay */);
+ }
/**
* A synchronous call to obtain the attributes of the specified SUID.
@@ -276,6 +288,9 @@
//! true if we are waiting on a response of a Qsocket request.
bool mWaitingOnResp = false;
+ //! true if we've timed out in findSuidSync at least once
+ bool mHaveTimedOutOnSuidLookup = false;
+
//! The Qsocket response error of the request we just made.
sns_std_error mRespError;
diff --git a/platform/slpi/see/see_helper.cc b/platform/slpi/see/see_helper.cc
index 5b2d217..5484c49 100644
--- a/platform/slpi/see/see_helper.cc
+++ b/platform/slpi/see/see_helper.cc
@@ -1439,6 +1439,9 @@
} while (suids->size() < minNumSuids && trialCount < maxRetries);
success = (suids->size() >= minNumSuids);
+ if (!success) {
+ mHaveTimedOutOnSuidLookup = true;
+ }
if (trialCount > 1) {
LOGD("Waited %" PRIu32 " ms for %s (found: %d)",
static_cast<uint32_t>(trialCount * retryDelay.getMilliseconds()),