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()),