summaryrefslogtreecommitdiffstats
path: root/libsuspend
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2012-06-14 12:55:47 -0700
committerColin Cross <ccross@android.com>2012-06-14 15:13:10 -0700
commitf25dd878dfeba87a3c2b868e07cb550061f670b4 (patch)
tree014da632dfcc48834703bd2835e32365a27bb386 /libsuspend
parent66086a586f80e394674eb171d683d0d9677e3abf (diff)
downloadsystem_core-f25dd878dfeba87a3c2b868e07cb550061f670b4.zip
system_core-f25dd878dfeba87a3c2b868e07cb550061f670b4.tar.gz
system_core-f25dd878dfeba87a3c2b868e07cb550061f670b4.tar.bz2
libsuspend: wait for earlysuspend transition to finish
Wait for the early suspend transition to finish to the point where surfaceflinger would previously have synchronized. This is important during screen on, to ensure the display early suspend handlers have completed before surfaceflinger unblanks. Change-Id: I91ac0253d9655c3f1ae3dd7f1a918c279568b23e
Diffstat (limited to 'libsuspend')
-rw-r--r--libsuspend/autosuspend_earlysuspend.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/libsuspend/autosuspend_earlysuspend.c b/libsuspend/autosuspend_earlysuspend.c
index b440128..1df8c6a 100644
--- a/libsuspend/autosuspend_earlysuspend.c
+++ b/libsuspend/autosuspend_earlysuspend.c
@@ -16,6 +16,8 @@
#include <errno.h>
#include <fcntl.h>
+#include <pthread.h>
+#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <sys/types.h>
@@ -31,11 +33,17 @@
#define EARLYSUSPEND_WAIT_FOR_FB_SLEEP "/sys/power/wait_for_fb_sleep"
#define EARLYSUSPEND_WAIT_FOR_FB_WAKE "/sys/power/wait_for_fb_wake"
-
static int sPowerStatefd;
static const char *pwr_state_mem = "mem";
static const char *pwr_state_on = "on";
static pthread_t earlysuspend_thread;
+static pthread_mutex_t earlysuspend_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t earlysuspend_cond = PTHREAD_COND_INITIALIZER;
+static bool wait_for_earlysuspend;
+static enum {
+ EARLYSUSPEND_ON,
+ EARLYSUSPEND_MEM,
+} earlysuspend_state = EARLYSUSPEND_ON;
int wait_for_fb_wake(void)
{
@@ -79,10 +87,19 @@ static void *earlysuspend_thread_func(void *arg)
ALOGE("Failed reading wait_for_fb_sleep, exiting earlysuspend thread\n");
return NULL;
}
+ pthread_mutex_lock(&earlysuspend_mutex);
+ earlysuspend_state = EARLYSUSPEND_MEM;
+ pthread_cond_signal(&earlysuspend_cond);
+ pthread_mutex_unlock(&earlysuspend_mutex);
+
if (wait_for_fb_wake()) {
ALOGE("Failed reading wait_for_fb_wake, exiting earlysuspend thread\n");
return NULL;
}
+ pthread_mutex_lock(&earlysuspend_mutex);
+ earlysuspend_state = EARLYSUSPEND_ON;
+ pthread_cond_signal(&earlysuspend_cond);
+ pthread_mutex_unlock(&earlysuspend_mutex);
}
}
static int autosuspend_earlysuspend_enable(void)
@@ -99,6 +116,14 @@ static int autosuspend_earlysuspend_enable(void)
goto err;
}
+ if (wait_for_earlysuspend) {
+ pthread_mutex_lock(&earlysuspend_mutex);
+ while (earlysuspend_state != EARLYSUSPEND_MEM) {
+ pthread_cond_wait(&earlysuspend_cond, &earlysuspend_mutex);
+ }
+ pthread_mutex_unlock(&earlysuspend_mutex);
+ }
+
ALOGV("autosuspend_earlysuspend_enable done\n");
return 0;
@@ -121,6 +146,14 @@ static int autosuspend_earlysuspend_disable(void)
goto err;
}
+ if (wait_for_earlysuspend) {
+ pthread_mutex_lock(&earlysuspend_mutex);
+ while (earlysuspend_state != EARLYSUSPEND_ON) {
+ pthread_cond_wait(&earlysuspend_cond, &earlysuspend_mutex);
+ }
+ pthread_mutex_unlock(&earlysuspend_mutex);
+ }
+
ALOGV("autosuspend_earlysuspend_disable done\n");
return 0;
@@ -149,12 +182,17 @@ void start_earlysuspend_thread(void)
return;
}
+ wait_for_fb_wake();
+
ALOGI("Starting early suspend unblocker thread\n");
ret = pthread_create(&earlysuspend_thread, NULL, earlysuspend_thread_func, NULL);
if (ret) {
- strerror_r(ret, buf, sizeof(buf));
+ strerror_r(errno, buf, sizeof(buf));
ALOGE("Error creating thread: %s\n", buf);
+ return;
}
+
+ wait_for_earlysuspend = true;
}
struct autosuspend_ops *autosuspend_earlysuspend_init(void)