summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Cross2012-06-07 16:12:54 -0500
committerColin Cross2012-06-07 19:15:17 -0500
commit2146b7f2d7f8e9320d8ec5581c61e14f243ee97c (patch)
treecd0d7d434ae6392710c4a732f4c9e0ad34b8129d /libsuspend
parent6ba76f019040a0445575deb6995cd32ea72903dd (diff)
downloadplatform-system-core-2146b7f2d7f8e9320d8ec5581c61e14f243ee97c.tar.gz
platform-system-core-2146b7f2d7f8e9320d8ec5581c61e14f243ee97c.tar.xz
platform-system-core-2146b7f2d7f8e9320d8ec5581c61e14f243ee97c.zip
libsuspend: always unblock early suspend
SurfaceFlinger and PowerManagerService manage their synchronization without the help of early suspend, and SurfaceFlinger no longer unblocks early suspend. Add a new thread when early suspend is detected that will immediately unblock early suspend. Change-Id: I87ef4984a2ab34cbbb3af8b7762236b9a92dc2ea
Diffstat (limited to 'libsuspend')
-rw-r--r--libsuspend/autosuspend_earlysuspend.c84
1 files changed, 80 insertions, 4 deletions
diff --git a/libsuspend/autosuspend_earlysuspend.c b/libsuspend/autosuspend_earlysuspend.c
index 2c2aa3661..b4401284c 100644
--- a/libsuspend/autosuspend_earlysuspend.c
+++ b/libsuspend/autosuspend_earlysuspend.c
@@ -35,7 +35,56 @@
35static int sPowerStatefd; 35static int sPowerStatefd;
36static const char *pwr_state_mem = "mem"; 36static const char *pwr_state_mem = "mem";
37static const char *pwr_state_on = "on"; 37static const char *pwr_state_on = "on";
38static pthread_t earlysuspend_thread;
38 39
40int wait_for_fb_wake(void)
41{
42 int err = 0;
43 char buf;
44 int fd = open(EARLYSUSPEND_WAIT_FOR_FB_WAKE, O_RDONLY, 0);
45 // if the file doesn't exist, the error will be caught in read() below
46 do {
47 err = read(fd, &buf, 1);
48 } while (err < 0 && errno == EINTR);
49 ALOGE_IF(err < 0,
50 "*** ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno));
51 close(fd);
52 return err < 0 ? err : 0;
53}
54
55static int wait_for_fb_sleep(void)
56{
57 int err = 0;
58 char buf;
59 int fd = open(EARLYSUSPEND_WAIT_FOR_FB_SLEEP, O_RDONLY, 0);
60 // if the file doesn't exist, the error will be caught in read() below
61 do {
62 err = read(fd, &buf, 1);
63 } while (err < 0 && errno == EINTR);
64 ALOGE_IF(err < 0,
65 "*** ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno));
66 close(fd);
67 return err < 0 ? err : 0;
68}
69
70static void *earlysuspend_thread_func(void *arg)
71{
72 char buf[80];
73 char wakeup_count[20];
74 int wakeup_count_len;
75 int ret;
76
77 while (1) {
78 if (wait_for_fb_sleep()) {
79 ALOGE("Failed reading wait_for_fb_sleep, exiting earlysuspend thread\n");
80 return NULL;
81 }
82 if (wait_for_fb_wake()) {
83 ALOGE("Failed reading wait_for_fb_wake, exiting earlysuspend thread\n");
84 return NULL;
85 }
86 }
87}
39static int autosuspend_earlysuspend_enable(void) 88static int autosuspend_earlysuspend_enable(void)
40{ 89{
41 char buf[80]; 90 char buf[80];
@@ -85,29 +134,56 @@ struct autosuspend_ops autosuspend_earlysuspend_ops = {
85 .disable = autosuspend_earlysuspend_disable, 134 .disable = autosuspend_earlysuspend_disable,
86}; 135};
87 136
88struct autosuspend_ops *autosuspend_earlysuspend_init(void) 137void start_earlysuspend_thread(void)
89{ 138{
90 char buf[80]; 139 char buf[80];
91 int ret; 140 int ret;
92 141
93 ret = access(EARLYSUSPEND_WAIT_FOR_FB_SLEEP, F_OK); 142 ret = access(EARLYSUSPEND_WAIT_FOR_FB_SLEEP, F_OK);
94 if (ret < 0) { 143 if (ret < 0) {
95 return NULL; 144 return;
96 } 145 }
97 146
98 ret = access(EARLYSUSPEND_WAIT_FOR_FB_WAKE, F_OK); 147 ret = access(EARLYSUSPEND_WAIT_FOR_FB_WAKE, F_OK);
99 if (ret < 0) { 148 if (ret < 0) {
100 return NULL; 149 return;
101 } 150 }
102 151
152 ALOGI("Starting early suspend unblocker thread\n");
153 ret = pthread_create(&earlysuspend_thread, NULL, earlysuspend_thread_func, NULL);
154 if (ret) {
155 strerror_r(ret, buf, sizeof(buf));
156 ALOGE("Error creating thread: %s\n", buf);
157 }
158}
159
160struct autosuspend_ops *autosuspend_earlysuspend_init(void)
161{
162 char buf[80];
163 int ret;
164
103 sPowerStatefd = open(EARLYSUSPEND_SYS_POWER_STATE, O_RDWR); 165 sPowerStatefd = open(EARLYSUSPEND_SYS_POWER_STATE, O_RDWR);
104 166
105 if (sPowerStatefd < 0) { 167 if (sPowerStatefd < 0) {
106 strerror_r(errno, buf, sizeof(buf)); 168 strerror_r(errno, buf, sizeof(buf));
107 ALOGE("Error opening %s: %s\n", EARLYSUSPEND_SYS_POWER_STATE, buf); 169 ALOGW("Error opening %s: %s\n", EARLYSUSPEND_SYS_POWER_STATE, buf);
108 return NULL; 170 return NULL;
109 } 171 }
110 172
173 ret = write(sPowerStatefd, "on", 2);
174 if (ret < 0) {
175 strerror_r(errno, buf, sizeof(buf));
176 ALOGW("Error writing 'on' to %s: %s\n", EARLYSUSPEND_SYS_POWER_STATE, buf);
177 goto err_write;
178 }
179
111 ALOGI("Selected early suspend\n"); 180 ALOGI("Selected early suspend\n");
181
182 start_earlysuspend_thread();
183
112 return &autosuspend_earlysuspend_ops; 184 return &autosuspend_earlysuspend_ops;
185
186err_write:
187 close(sPowerStatefd);
188 return NULL;
113} 189}