Merge lp:~charlesk/powerd/add-hardware-alarms into lp:powerd
- add-hardware-alarms
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Ricardo Salveti |
Approved revision: | 143 |
Merged at revision: | 139 |
Proposed branch: | lp:~charlesk/powerd/add-hardware-alarms |
Merge into: | lp:powerd |
Diff against target: |
658 lines (+439/-12) 9 files modified
CMakeLists.txt (+3/-1) cli/powerd-cli.c (+99/-0) data/com.canonical.powerd.xml (+13/-0) debian/control (+2/-0) src/log.h (+23/-0) src/powerd-internal.h (+8/-1) src/powerd-object.c (+101/-10) src/powerd.cpp (+2/-0) src/wakeup.cpp (+188/-0) |
To merge this branch: | bzr merge lp:~charlesk/powerd/add-hardware-alarms |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ricardo Salveti (community) | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Review via email: mp+231302@code.launchpad.net |
Commit message
Add hardware wakeup support.
Description of the change
Add hardware wakeup support. As discussed in #phablet, the u_hardware_
This adds a little new public API: two methods (requestWakeup() and clearWakeup()) and a broadcast signal (Wakeup).
Also added are wakeup and clear-wakeup commands in powerd-cli.
The wakeup.cpp implementation is fairly straightforward. One point that might be contentious is the new logging functions in log.h. I think they're pretty useful but don't mind removing them if they're too un-powerd-like.
See related MP for indicator-datetime to make use of this: <https:/
PS Jenkins bot (ps-jenkins) wrote : | # |
Ricardo Salveti (rsalveti) wrote : | # |
Code looks fine, just one inline comment for the packaging. Will do some further tests and then approve with the proper feedback.
Charles Kerr (charlesk) : | # |
- 143. By Charles Kerr
-
in debian/control, remove [armhf i386 amd64] arch restrictions for libubuntu-
platform- hardware- api-*
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:143
http://
Executed test runs:
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Ricardo Salveti (rsalveti) wrote : | # |
Looks good, works as expected.
Would be nice for powerd-cli list to also show the current list of the pending wakeup events, but that can be done later on.
Preview Diff
1 | === modified file 'CMakeLists.txt' | |||
2 | --- CMakeLists.txt 2014-05-21 03:17:03 +0000 | |||
3 | +++ CMakeLists.txt 2014-08-19 19:23:22 +0000 | |||
4 | @@ -9,7 +9,7 @@ | |||
5 | 9 | endif() | 9 | endif() |
6 | 10 | 10 | ||
7 | 11 | set(CMAKE_C_FLAGS "-Wall") | 11 | set(CMAKE_C_FLAGS "-Wall") |
9 | 12 | set(CMAKE_CXX_FLAGS "-Wall") | 12 | set(CMAKE_CXX_FLAGS "-Wall -std=c++11") |
10 | 13 | set(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb -g") | 13 | set(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb -g") |
11 | 14 | set(CMAKE_CXX_FLAGS_DEBUG "-O0 -ggdb -g") | 14 | set(CMAKE_CXX_FLAGS_DEBUG "-O0 -ggdb -g") |
12 | 15 | set(CMAKE_C_FLAGS_RELEASE "-O3") | 15 | set(CMAKE_C_FLAGS_RELEASE "-O3") |
13 | @@ -56,6 +56,7 @@ | |||
14 | 56 | src/spline.c | 56 | src/spline.c |
15 | 57 | src/stats.c | 57 | src/stats.c |
16 | 58 | src/util.c | 58 | src/util.c |
17 | 59 | src/wakeup.cpp | ||
18 | 59 | src/${GDBUS_NAME}.c | 60 | src/${GDBUS_NAME}.c |
19 | 60 | ) | 61 | ) |
20 | 61 | 62 | ||
21 | @@ -103,6 +104,7 @@ | |||
22 | 103 | ${GIO_LIBRARIES} | 104 | ${GIO_LIBRARIES} |
23 | 104 | ${GIO-UNIX_LIBRARIES} | 105 | ${GIO-UNIX_LIBRARIES} |
24 | 105 | ${PHABLET_LIBRARIES} | 106 | ${PHABLET_LIBRARIES} |
25 | 107 | "-lubuntu_platform_hardware_api" | ||
26 | 106 | "-lubuntu_application_api" | 108 | "-lubuntu_application_api" |
27 | 107 | "-landroid-properties" | 109 | "-landroid-properties" |
28 | 108 | "-lhardware" | 110 | "-lhardware" |
29 | 109 | 111 | ||
30 | === modified file 'cli/powerd-cli.c' | |||
31 | --- cli/powerd-cli.c 2014-06-18 18:06:10 +0000 | |||
32 | +++ cli/powerd-cli.c 2014-08-19 19:23:22 +0000 | |||
33 | @@ -141,6 +141,55 @@ | |||
34 | 141 | } | 141 | } |
35 | 142 | 142 | ||
36 | 143 | static gboolean | 143 | static gboolean |
37 | 144 | requestWakeup(const char *name, | ||
38 | 145 | uint64_t wakeup_time, | ||
39 | 146 | powerd_cookie_t setme_cookie) | ||
40 | 147 | { | ||
41 | 148 | GVariant *ret; | ||
42 | 149 | GError *error; | ||
43 | 150 | gboolean success; | ||
44 | 151 | |||
45 | 152 | g_return_val_if_fail (setme_cookie != NULL, FALSE); | ||
46 | 153 | |||
47 | 154 | error = NULL; | ||
48 | 155 | ret = g_dbus_proxy_call_sync(powerd_proxy, | ||
49 | 156 | "requestWakeup", | ||
50 | 157 | g_variant_new("(st)", name, wakeup_time), | ||
51 | 158 | G_DBUS_CALL_FLAGS_NONE, | ||
52 | 159 | -1, /* use default timeout */ | ||
53 | 160 | NULL, /* cancellable */ | ||
54 | 161 | &error); | ||
55 | 162 | |||
56 | 163 | if (ret == NULL) { | ||
57 | 164 | cli_warn("%s failed: %s", G_STRFUNC, error->message); | ||
58 | 165 | success = FALSE; | ||
59 | 166 | } | ||
60 | 167 | else if (!g_variant_is_of_type(ret, G_VARIANT_TYPE("(s)"))) { | ||
61 | 168 | char * s = g_variant_print(ret, TRUE); | ||
62 | 169 | cli_warn("Unexpected response: %s", s); | ||
63 | 170 | g_free(s); | ||
64 | 171 | success = FALSE; | ||
65 | 172 | } | ||
66 | 173 | else { | ||
67 | 174 | const char* s = NULL; | ||
68 | 175 | g_variant_get(ret, "(&s)", &s); | ||
69 | 176 | if (strlen(s) != sizeof(powerd_cookie_t) - 1) { | ||
70 | 177 | cli_warn("Returned cookie has incorrect size"); | ||
71 | 178 | success = FALSE; | ||
72 | 179 | } | ||
73 | 180 | else { | ||
74 | 181 | memcpy(setme_cookie, s, sizeof(powerd_cookie_t)); | ||
75 | 182 | cli_debug("Got cookie: %s", setme_cookie); | ||
76 | 183 | success = TRUE; | ||
77 | 184 | } | ||
78 | 185 | } | ||
79 | 186 | |||
80 | 187 | g_clear_error(&error); | ||
81 | 188 | g_clear_pointer(&ret, g_variant_unref); | ||
82 | 189 | return success; | ||
83 | 190 | } | ||
84 | 191 | |||
85 | 192 | static gboolean | ||
86 | 144 | requestDisplayState(int *cookie) | 193 | requestDisplayState(int *cookie) |
87 | 145 | { | 194 | { |
88 | 146 | GVariant *ret = NULL; | 195 | GVariant *ret = NULL; |
89 | @@ -286,6 +335,35 @@ | |||
90 | 286 | } | 335 | } |
91 | 287 | } | 336 | } |
92 | 288 | 337 | ||
93 | 338 | static gboolean | ||
94 | 339 | clearWakeup(const char* cookie_str) | ||
95 | 340 | { | ||
96 | 341 | GVariant *ret; | ||
97 | 342 | GError *error; | ||
98 | 343 | gboolean success; | ||
99 | 344 | |||
100 | 345 | error = NULL; | ||
101 | 346 | ret = g_dbus_proxy_call_sync(powerd_proxy, | ||
102 | 347 | "clearWakeup", | ||
103 | 348 | g_variant_new("(s)", cookie_str), | ||
104 | 349 | G_DBUS_CALL_FLAGS_NONE, | ||
105 | 350 | -1, /* default timeout */ | ||
106 | 351 | NULL, /* cancellable */ | ||
107 | 352 | &error); | ||
108 | 353 | |||
109 | 354 | if (ret == NULL) { | ||
110 | 355 | cli_warn("%s failed: %s", G_STRFUNC, error->message); | ||
111 | 356 | success = FALSE; | ||
112 | 357 | } else { | ||
113 | 358 | cli_debug("%s success", G_STRFUNC); | ||
114 | 359 | success = TRUE; | ||
115 | 360 | } | ||
116 | 361 | |||
117 | 362 | g_clear_error(&error); | ||
118 | 363 | g_clear_pointer(&ret, g_variant_unref); | ||
119 | 364 | return success; | ||
120 | 365 | } | ||
121 | 366 | |||
122 | 289 | gboolean | 367 | gboolean |
123 | 290 | clearSysState(powerd_cookie_t cookie) | 368 | clearSysState(powerd_cookie_t cookie) |
124 | 291 | { | 369 | { |
125 | @@ -618,6 +696,8 @@ | |||
126 | 618 | printf("listen\t- listen for signals from powerd. This runs a\n"\ | 696 | printf("listen\t- listen for signals from powerd. This runs a\n"\ |
127 | 619 | "\t gmainloop and must be manually killed.\n"); | 697 | "\t gmainloop and must be manually killed.\n"); |
128 | 620 | printf("stats\t- print request statistics.\n"); | 698 | printf("stats\t- print request statistics.\n"); |
129 | 699 | printf("wakeup <n>\t- request a hardware wakeup n seconds from now.\n"); | ||
130 | 700 | printf("clear-wakeup <cookie>\t- clear a hardware wakeup request given a cookie.\n"); | ||
131 | 621 | printf("test\t- runs tests.\n"); | 701 | printf("test\t- runs tests.\n"); |
132 | 622 | } | 702 | } |
133 | 623 | 703 | ||
134 | @@ -646,6 +726,8 @@ | |||
135 | 646 | (strcmp(argv[1],"stats")) && | 726 | (strcmp(argv[1],"stats")) && |
136 | 647 | (strcmp(argv[1],"active")) && | 727 | (strcmp(argv[1],"active")) && |
137 | 648 | (strcmp(argv[1],"active-nc")) && | 728 | (strcmp(argv[1],"active-nc")) && |
138 | 729 | (strcmp(argv[1],"wakeup")) && | ||
139 | 730 | (strcmp(argv[1],"clear-wakeup")) && | ||
140 | 649 | (strcmp(argv[1],"test")) && | 731 | (strcmp(argv[1],"test")) && |
141 | 650 | (strcmp(argv[1],"dbusnametest")) && | 732 | (strcmp(argv[1],"dbusnametest")) && |
142 | 651 | (strcmp(argv[1],"listen")) && | 733 | (strcmp(argv[1],"listen")) && |
143 | @@ -751,6 +833,9 @@ | |||
144 | 751 | if (!strcmp(argv[1],"clear-sys")) { | 833 | if (!strcmp(argv[1],"clear-sys")) { |
145 | 752 | clearSysState(argv[2]); | 834 | clearSysState(argv[2]); |
146 | 753 | } | 835 | } |
147 | 836 | else if (!g_strcmp0(argv[1], "clear-wakeup")) { | ||
148 | 837 | clearWakeup(argv[2]); | ||
149 | 838 | } | ||
150 | 754 | else { | 839 | else { |
151 | 755 | // Note: We should never get here due to earlier checks | 840 | // Note: We should never get here due to earlier checks |
152 | 756 | fprintf(stderr,"Invalid option %s\n",argv[1]); | 841 | fprintf(stderr,"Invalid option %s\n",argv[1]); |
153 | @@ -844,6 +929,20 @@ | |||
154 | 844 | exit(-1); | 929 | exit(-1); |
155 | 845 | } | 930 | } |
156 | 846 | setUserBrightness((int)brightness); | 931 | setUserBrightness((int)brightness); |
157 | 932 | } else if (!g_strcmp0(argv[1], "wakeup")) { | ||
158 | 933 | int n_seconds; | ||
159 | 934 | powerd_cookie_t cookie; | ||
160 | 935 | if (argc != 3) { | ||
161 | 936 | usage(argv[0]); | ||
162 | 937 | exit(-1); | ||
163 | 938 | } | ||
164 | 939 | n_seconds = atoi(argv[2]); | ||
165 | 940 | if (n_seconds < 1) { | ||
166 | 941 | fprintf(stderr, "Invalid number of seconds %s\n", argv[2]); | ||
167 | 942 | usage(argv[0]); | ||
168 | 943 | exit(-1); | ||
169 | 944 | } | ||
170 | 945 | requestWakeup(argv[0], time(NULL)+n_seconds, cookie); | ||
171 | 847 | } | 946 | } |
172 | 848 | return 0; | 947 | return 0; |
173 | 849 | } | 948 | } |
174 | 850 | 949 | ||
175 | === modified file 'data/com.canonical.powerd.xml' | |||
176 | --- data/com.canonical.powerd.xml 2014-05-13 22:05:20 +0000 | |||
177 | +++ data/com.canonical.powerd.xml 2014-08-19 19:23:22 +0000 | |||
178 | @@ -14,6 +14,16 @@ | |||
179 | 14 | <arg type="s" name="cookie" direction="in" /> | 14 | <arg type="s" name="cookie" direction="in" /> |
180 | 15 | </method> | 15 | </method> |
181 | 16 | 16 | ||
182 | 17 | <method name="requestWakeup"> | ||
183 | 18 | <arg type="s" name="name" direction="in" /> | ||
184 | 19 | <arg type="t" name="time" direction="in" /> | ||
185 | 20 | <arg type="s" name="cookie" direction="out" /> | ||
186 | 21 | </method> | ||
187 | 22 | |||
188 | 23 | <method name="clearWakeup"> | ||
189 | 24 | <arg type="s" name="cookie" direction="in" /> | ||
190 | 25 | </method> | ||
191 | 26 | |||
192 | 17 | <method name="registerClient"> | 27 | <method name="registerClient"> |
193 | 18 | <arg type="s" name="name" direction="in" /> | 28 | <arg type="s" name="name" direction="in" /> |
194 | 19 | </method> | 29 | </method> |
195 | @@ -55,5 +65,8 @@ | |||
196 | 55 | <arg type="i" name="sysState" direction="out" /> | 65 | <arg type="i" name="sysState" direction="out" /> |
197 | 56 | </signal> | 66 | </signal> |
198 | 57 | 67 | ||
199 | 68 | <signal name="Wakeup"> | ||
200 | 69 | </signal> | ||
201 | 70 | |||
202 | 58 | </interface> | 71 | </interface> |
203 | 59 | </node> | 72 | </node> |
204 | 60 | 73 | ||
205 | === modified file 'debian/control' | |||
206 | --- debian/control 2014-06-13 15:56:20 +0000 | |||
207 | +++ debian/control 2014-08-19 19:23:22 +0000 | |||
208 | @@ -10,6 +10,8 @@ | |||
209 | 10 | python:any, | 10 | python:any, |
210 | 11 | libandroid-properties-dev, | 11 | libandroid-properties-dev, |
211 | 12 | libubuntu-application-api-dev, | 12 | libubuntu-application-api-dev, |
212 | 13 | libubuntu-platform-hardware-api-headers, | ||
213 | 14 | libubuntu-platform-hardware-api-dev, | ||
214 | 13 | libupower-glib-dev, | 15 | libupower-glib-dev, |
215 | 14 | uuid-dev, | 16 | uuid-dev, |
216 | 15 | libhardware-dev (>= 0.1.0+git20131207+e452e83-0ubuntu12), | 17 | libhardware-dev (>= 0.1.0+git20131207+e452e83-0ubuntu12), |
217 | 16 | 18 | ||
218 | === modified file 'src/log.h' | |||
219 | --- src/log.h 2013-07-10 21:28:20 +0000 | |||
220 | +++ src/log.h 2014-08-19 19:23:22 +0000 | |||
221 | @@ -39,6 +39,29 @@ | |||
222 | 39 | __attribute__ ((format (printf, 2, 3))); | 39 | __attribute__ ((format (printf, 2, 3))); |
223 | 40 | void powerd_log_init(void); | 40 | void powerd_log_init(void); |
224 | 41 | 41 | ||
225 | 42 | #define powerd_warn_if_fail(expr) \ | ||
226 | 43 | do { \ | ||
227 | 44 | if (!(expr)) \ | ||
228 | 45 | powerd_warn("%s", #expr); \ | ||
229 | 46 | } while (0) | ||
230 | 47 | |||
231 | 48 | #define powerd_return_if_fail(expr) \ | ||
232 | 49 | do { \ | ||
233 | 50 | if (!(expr)) { \ | ||
234 | 51 | powerd_warn("%s: assertion '%s' failed", __func__, #expr); \ | ||
235 | 52 | return; \ | ||
236 | 53 | } \ | ||
237 | 54 | } while (0) | ||
238 | 55 | |||
239 | 56 | #define powerd_return_val_if_fail(expr,val) \ | ||
240 | 57 | do { \ | ||
241 | 58 | if (!(expr)) { \ | ||
242 | 59 | powerd_warn("%s: assertion '%s' failed", __func__, #expr); \ | ||
243 | 60 | return val; \ | ||
244 | 61 | } \ | ||
245 | 62 | } while (0) | ||
246 | 63 | |||
247 | 64 | |||
248 | 42 | #ifdef __cplusplus | 65 | #ifdef __cplusplus |
249 | 43 | } | 66 | } |
250 | 44 | #endif | 67 | #endif |
251 | 45 | 68 | ||
252 | === modified file 'src/powerd-internal.h' | |||
253 | --- src/powerd-internal.h 2014-07-02 16:24:51 +0000 | |||
254 | +++ src/powerd-internal.h 2014-08-19 19:23:22 +0000 | |||
255 | @@ -19,8 +19,8 @@ | |||
256 | 19 | #ifndef __POWERD_INTERNAL_H__ | 19 | #ifndef __POWERD_INTERNAL_H__ |
257 | 20 | #define __POWERD_INTERNAL_H__ | 20 | #define __POWERD_INTERNAL_H__ |
258 | 21 | 21 | ||
259 | 22 | #include <time.h> /* time_t */ | ||
260 | 22 | #include <uuid/uuid.h> | 23 | #include <uuid/uuid.h> |
261 | 23 | #include <glib.h> | ||
262 | 24 | #include <gio/gio.h> | 24 | #include <gio/gio.h> |
263 | 25 | 25 | ||
264 | 26 | #include "powerd-object.h" | 26 | #include "powerd-object.h" |
265 | @@ -107,6 +107,7 @@ | |||
266 | 107 | enum SysPowerStates current_system_power_state(void); | 107 | enum SysPowerStates current_system_power_state(void); |
267 | 108 | const gchar * state_to_string(int state); | 108 | const gchar * state_to_string(int state); |
268 | 109 | void powerd_sys_state_signal_emit(enum SysPowerStates state); | 109 | void powerd_sys_state_signal_emit(enum SysPowerStates state); |
269 | 110 | void powerd_wakeup_signal_emit(void); | ||
270 | 110 | void clear_sys_state_by_owner(const char *owner); | 111 | void clear_sys_state_by_owner(const char *owner); |
271 | 111 | gboolean powerd_suspend_active(void); | 112 | gboolean powerd_suspend_active(void); |
272 | 112 | 113 | ||
273 | @@ -164,6 +165,12 @@ | |||
274 | 164 | int powerd_ps_init(void); | 165 | int powerd_ps_init(void); |
275 | 165 | void powerd_ps_deinit(void); | 166 | void powerd_ps_deinit(void); |
276 | 166 | 167 | ||
277 | 168 | /* Hardware alarm functions */ | ||
278 | 169 | void wakeup_init(void); | ||
279 | 170 | void wakeup_deinit(void); | ||
280 | 171 | int wakeup_request(const char *name, time_t time, powerd_cookie_t setme_cookie); | ||
281 | 172 | int wakeup_clear(const powerd_cookie_t cookie); | ||
282 | 173 | |||
283 | 167 | /* Client functions */ | 174 | /* Client functions */ |
284 | 168 | int powerd_client_register(const char *dbus_name, const char *name); | 175 | int powerd_client_register(const char *dbus_name, const char *name); |
285 | 169 | void powerd_client_unregister(const char *dbus_name); | 176 | void powerd_client_unregister(const char *dbus_name); |
286 | 170 | 177 | ||
287 | === modified file 'src/powerd-object.c' | |||
288 | --- src/powerd-object.c 2014-07-02 16:24:51 +0000 | |||
289 | +++ src/powerd-object.c 2014-08-19 19:23:22 +0000 | |||
290 | @@ -19,6 +19,7 @@ | |||
291 | 19 | #include <glib.h> | 19 | #include <glib.h> |
292 | 20 | #include <glib-object.h> | 20 | #include <glib-object.h> |
293 | 21 | #include <gio/gio.h> | 21 | #include <gio/gio.h> |
294 | 22 | #include <inttypes.h> | ||
295 | 22 | #include <string.h> | 23 | #include <string.h> |
296 | 23 | #include <stdio.h> | 24 | #include <stdio.h> |
297 | 24 | #include <errno.h> | 25 | #include <errno.h> |
298 | @@ -135,11 +136,69 @@ | |||
299 | 135 | return TRUE; | 136 | return TRUE; |
300 | 136 | } | 137 | } |
301 | 137 | 138 | ||
302 | 139 | static gboolean | ||
303 | 140 | handle_request_wakeup(PowerdSource *obj, | ||
304 | 141 | GDBusMethodInvocation *invocation, | ||
305 | 142 | const char *name, | ||
306 | 143 | uint64_t wakeup_time) | ||
307 | 144 | { | ||
308 | 145 | int err; | ||
309 | 146 | powerd_cookie_t cookie; | ||
310 | 147 | |||
311 | 148 | powerd_debug("handle_requestWakeup from %s - %s, %zu", | ||
312 | 149 | g_dbus_method_invocation_get_sender(invocation), | ||
313 | 150 | name, | ||
314 | 151 | (size_t)wakeup_time); | ||
315 | 152 | |||
316 | 153 | if ((err = wakeup_request(name, wakeup_time, cookie))) | ||
317 | 154 | { | ||
318 | 155 | g_dbus_method_invocation_return_error_literal(invocation, | ||
319 | 156 | G_DBUS_ERROR, | ||
320 | 157 | G_DBUS_ERROR_FAILED, | ||
321 | 158 | strerror(err)); | ||
322 | 159 | } | ||
323 | 160 | else | ||
324 | 161 | { | ||
325 | 162 | g_dbus_method_invocation_return_value(invocation, | ||
326 | 163 | g_variant_new("(s)", cookie)); | ||
327 | 164 | } | ||
328 | 165 | |||
329 | 166 | return TRUE; | ||
330 | 167 | } | ||
331 | 168 | |||
332 | 169 | static gboolean | ||
333 | 170 | handle_clear_wakeup(PowerdSource *obj, | ||
334 | 171 | GDBusMethodInvocation *invocation, | ||
335 | 172 | const char* cookie) | ||
336 | 173 | { | ||
337 | 174 | int err; | ||
338 | 175 | |||
339 | 176 | powerd_debug("handle_clearWakeup from %s, cookie: %s", | ||
340 | 177 | g_dbus_method_invocation_get_sender(invocation), | ||
341 | 178 | cookie); | ||
342 | 179 | |||
343 | 180 | if ((err = wakeup_clear(cookie))) | ||
344 | 181 | { | ||
345 | 182 | g_dbus_method_invocation_return_error_literal(invocation, | ||
346 | 183 | G_DBUS_ERROR, | ||
347 | 184 | G_DBUS_ERROR_FAILED, | ||
348 | 185 | strerror(err)); | ||
349 | 186 | } | ||
350 | 187 | else | ||
351 | 188 | { | ||
352 | 189 | g_dbus_method_invocation_return_value(invocation, NULL); | ||
353 | 190 | } | ||
354 | 191 | |||
355 | 192 | return TRUE; | ||
356 | 193 | } | ||
357 | 194 | |||
358 | 195 | |||
359 | 138 | void | 196 | void |
360 | 139 | powerd_bus_acquired_cb (GDBusConnection *connection, | 197 | powerd_bus_acquired_cb (GDBusConnection *connection, |
361 | 140 | const gchar *name, | 198 | const gchar *name, |
362 | 141 | gpointer user_data) | 199 | gpointer user_data) |
363 | 142 | { | 200 | { |
364 | 201 | GObject * oskel; | ||
365 | 143 | GError *error = NULL; | 202 | GError *error = NULL; |
366 | 144 | 203 | ||
367 | 145 | powerd_debug("Bus acquired (guid %s)", g_dbus_connection_get_guid (connection)); | 204 | powerd_debug("Bus acquired (guid %s)", g_dbus_connection_get_guid (connection)); |
368 | @@ -156,28 +215,35 @@ | |||
369 | 156 | powerd_exit(-1); | 215 | powerd_exit(-1); |
370 | 157 | } | 216 | } |
371 | 158 | 217 | ||
373 | 159 | g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-request-sys-state", | 218 | oskel = G_OBJECT(powerd_source->priv->skel); |
374 | 219 | |||
375 | 220 | g_signal_connect(oskel, "handle-request-sys-state", | ||
376 | 160 | G_CALLBACK(handle_request_sys_state), powerd_source); | 221 | G_CALLBACK(handle_request_sys_state), powerd_source); |
378 | 161 | g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-clear-sys-state", | 222 | g_signal_connect(oskel, "handle-clear-sys-state", |
379 | 162 | G_CALLBACK(handle_clear_sys_state), powerd_source); | 223 | G_CALLBACK(handle_clear_sys_state), powerd_source); |
381 | 163 | g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-list-sys-requests", | 224 | g_signal_connect(oskel, "handle-list-sys-requests", |
382 | 164 | G_CALLBACK(handle_list_sys_requests), powerd_source); | 225 | G_CALLBACK(handle_list_sys_requests), powerd_source); |
383 | 165 | 226 | ||
385 | 166 | g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-register-client", | 227 | g_signal_connect(oskel, "handle-register-client", |
386 | 167 | G_CALLBACK(handle_register_client), powerd_source); | 228 | G_CALLBACK(handle_register_client), powerd_source); |
388 | 168 | g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-unregister-client", | 229 | g_signal_connect(oskel, "handle-unregister-client", |
389 | 169 | G_CALLBACK(handle_unregister_client), powerd_source); | 230 | G_CALLBACK(handle_unregister_client), powerd_source); |
391 | 170 | g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-ack-state-change", | 231 | g_signal_connect(oskel, "handle-ack-state-change", |
392 | 171 | G_CALLBACK(handle_ack_state_change), powerd_source); | 232 | G_CALLBACK(handle_ack_state_change), powerd_source); |
394 | 172 | g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-get-sys-request-stats", | 233 | g_signal_connect(oskel, "handle-get-sys-request-stats", |
395 | 173 | G_CALLBACK(handle_get_sys_request_stats), powerd_source); | 234 | G_CALLBACK(handle_get_sys_request_stats), powerd_source); |
397 | 174 | g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-user-autobrightness-enable", | 235 | g_signal_connect(oskel, "handle-user-autobrightness-enable", |
398 | 175 | G_CALLBACK(handle_user_autobrightness_enable), powerd_source); | 236 | G_CALLBACK(handle_user_autobrightness_enable), powerd_source); |
400 | 176 | g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-get-brightness-params", | 237 | g_signal_connect(oskel, "handle-get-brightness-params", |
401 | 177 | G_CALLBACK(handle_get_brightness_params), powerd_source); | 238 | G_CALLBACK(handle_get_brightness_params), powerd_source); |
403 | 178 | g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-set-user-brightness", | 239 | g_signal_connect(oskel, "handle-set-user-brightness", |
404 | 179 | G_CALLBACK(handle_set_user_brightness), powerd_source); | 240 | G_CALLBACK(handle_set_user_brightness), powerd_source); |
405 | 180 | 241 | ||
406 | 242 | g_signal_connect(oskel, "handle-request-wakeup", | ||
407 | 243 | G_CALLBACK(handle_request_wakeup), powerd_source); | ||
408 | 244 | g_signal_connect(oskel, "handle-clear-wakeup", | ||
409 | 245 | G_CALLBACK(handle_clear_wakeup), powerd_source); | ||
410 | 246 | |||
411 | 181 | powerd_dbus_init_complete(); | 247 | powerd_dbus_init_complete(); |
412 | 182 | } | 248 | } |
413 | 183 | 249 | ||
414 | @@ -224,6 +290,31 @@ | |||
415 | 224 | } | 290 | } |
416 | 225 | 291 | ||
417 | 226 | void | 292 | void |
418 | 293 | powerd_wakeup_signal_emit (void) | ||
419 | 294 | { | ||
420 | 295 | GError *error = NULL; | ||
421 | 296 | |||
422 | 297 | /* Make sure dbus has been set up */ | ||
423 | 298 | if (!powerd_source) | ||
424 | 299 | return; | ||
425 | 300 | |||
426 | 301 | powerd_debug("Emitting wakeup signal"); | ||
427 | 302 | |||
428 | 303 | g_dbus_connection_emit_signal( | ||
429 | 304 | POWERD_SOURCE_GET_PRIVATE(powerd_source)->system_bus, | ||
430 | 305 | NULL, /* destination */ | ||
431 | 306 | "/com/canonical/powerd", | ||
432 | 307 | "com.canonical.powerd", | ||
433 | 308 | "Wakeup", | ||
434 | 309 | NULL, | ||
435 | 310 | &error); | ||
436 | 311 | if (error) { | ||
437 | 312 | powerd_warn("Unable to emit wakeup signal: %s", error->message); | ||
438 | 313 | g_error_free(error); | ||
439 | 314 | } | ||
440 | 315 | } | ||
441 | 316 | |||
442 | 317 | void | ||
443 | 227 | ofono_manager_proxy_connect_cb(GObject *source_object, | 318 | ofono_manager_proxy_connect_cb(GObject *source_object, |
444 | 228 | GAsyncResult *res, | 319 | GAsyncResult *res, |
445 | 229 | gpointer user_data) | 320 | gpointer user_data) |
446 | 230 | 321 | ||
447 | === modified file 'src/powerd.cpp' | |||
448 | --- src/powerd.cpp 2014-08-12 07:23:07 +0000 | |||
449 | +++ src/powerd.cpp 2014-08-19 19:23:22 +0000 | |||
450 | @@ -577,6 +577,7 @@ | |||
451 | 577 | powerd_autobrightness_init(); | 577 | powerd_autobrightness_init(); |
452 | 578 | powerd_sensors_init(); | 578 | powerd_sensors_init(); |
453 | 579 | powerd_ps_init(); | 579 | powerd_ps_init(); |
454 | 580 | wakeup_init(); | ||
455 | 580 | 581 | ||
456 | 581 | main_loop = g_main_loop_new (NULL, FALSE); | 582 | main_loop = g_main_loop_new (NULL, FALSE); |
457 | 582 | signal(SIGTERM, sigterm_quit); | 583 | signal(SIGTERM, sigterm_quit); |
458 | @@ -598,6 +599,7 @@ | |||
459 | 598 | g_bus_unown_name(name_id); | 599 | g_bus_unown_name(name_id); |
460 | 599 | g_main_loop_unref(main_loop); | 600 | g_main_loop_unref(main_loop); |
461 | 600 | 601 | ||
462 | 602 | wakeup_deinit(); | ||
463 | 601 | powerd_ps_deinit(); | 603 | powerd_ps_deinit(); |
464 | 602 | dbus_name_watch_deinit(); | 604 | dbus_name_watch_deinit(); |
465 | 603 | powerd_autobrightness_deinit(); | 605 | powerd_autobrightness_deinit(); |
466 | 604 | 606 | ||
467 | === added file 'src/wakeup.cpp' | |||
468 | --- src/wakeup.cpp 1970-01-01 00:00:00 +0000 | |||
469 | +++ src/wakeup.cpp 2014-08-19 19:23:22 +0000 | |||
470 | @@ -0,0 +1,188 @@ | |||
471 | 1 | /* | ||
472 | 2 | * Copyright 2014 Canonical Ltd. | ||
473 | 3 | * | ||
474 | 4 | * Authors: | ||
475 | 5 | * Charles Kerr: charles.kerr@canonical.com | ||
476 | 6 | * | ||
477 | 7 | * This file is part of powerd. | ||
478 | 8 | * | ||
479 | 9 | * powerd is free software; you can redistribute it and/or modify | ||
480 | 10 | * it under the terms of the GNU General Public License as published by | ||
481 | 11 | * the Free Software Foundation; version 3. | ||
482 | 12 | * | ||
483 | 13 | * powerd is distributed in the hope that it will be useful, | ||
484 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
485 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
486 | 16 | * GNU General Public License for more details. | ||
487 | 17 | * | ||
488 | 18 | * You should have received a copy of the GNU General Public License | ||
489 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
490 | 20 | */ | ||
491 | 21 | |||
492 | 22 | |||
493 | 23 | #include <ctime> | ||
494 | 24 | #include <map> | ||
495 | 25 | #include <memory> // std::unique_ptr | ||
496 | 26 | #include <string> | ||
497 | 27 | #include <thread> | ||
498 | 28 | |||
499 | 29 | #include <glib.h> | ||
500 | 30 | |||
501 | 31 | #include <ubuntu/hardware/alarm.h> | ||
502 | 32 | |||
503 | 33 | #include "powerd-internal.h" | ||
504 | 34 | #include "log.h" | ||
505 | 35 | |||
506 | 36 | namespace | ||
507 | 37 | { | ||
508 | 38 | |||
509 | 39 | struct Request | ||
510 | 40 | { | ||
511 | 41 | std::string name; | ||
512 | 42 | time_t time; | ||
513 | 43 | }; | ||
514 | 44 | |||
515 | 45 | std::map<std::string,Request> requests; | ||
516 | 46 | |||
517 | 47 | UHardwareAlarm hardware_alarm = nullptr; | ||
518 | 48 | |||
519 | 49 | // NB: only the main thread accesses 'worker' | ||
520 | 50 | std::unique_ptr<std::thread> worker; | ||
521 | 51 | |||
522 | 52 | void start_worker_thread(); | ||
523 | 53 | |||
524 | 54 | void set_wakeup_time(time_t wakeup_time, const std::string& name) | ||
525 | 55 | { | ||
526 | 56 | powerd_return_if_fail(hardware_alarm != nullptr); | ||
527 | 57 | powerd_return_if_fail(wakeup_time >= time(nullptr)); | ||
528 | 58 | |||
529 | 59 | struct tm tm; | ||
530 | 60 | char buf[32]; | ||
531 | 61 | localtime_r(&wakeup_time, &tm); | ||
532 | 62 | strftime(buf, sizeof(buf), "%F %T", &tm); | ||
533 | 63 | powerd_debug("setting hardware wakeup time to %s for %s", buf, name.c_str()); | ||
534 | 64 | |||
535 | 65 | struct timespec sleep_interval; | ||
536 | 66 | sleep_interval.tv_sec = wakeup_time; | ||
537 | 67 | sleep_interval.tv_nsec = 0; | ||
538 | 68 | u_hardware_alarm_set_relative_to_with_behavior( | ||
539 | 69 | hardware_alarm, | ||
540 | 70 | U_HARDWARE_ALARM_TIME_REFERENCE_RTC, | ||
541 | 71 | U_HARDWARE_ALARM_SLEEP_BEHAVIOR_WAKEUP_DEVICE, | ||
542 | 72 | &sleep_interval); | ||
543 | 73 | } | ||
544 | 74 | |||
545 | 75 | void reset_alarm_clock() | ||
546 | 76 | { | ||
547 | 77 | // find request that will occur next | ||
548 | 78 | const time_t now = time(nullptr); | ||
549 | 79 | const Request* next = nullptr; | ||
550 | 80 | size_t n_left = 0; | ||
551 | 81 | for (const auto& it : requests) { | ||
552 | 82 | if (now < it.second.time) { | ||
553 | 83 | ++n_left; | ||
554 | 84 | if (!next || (it.second.time < next->time)) | ||
555 | 85 | next = &it.second; | ||
556 | 86 | } | ||
557 | 87 | } | ||
558 | 88 | |||
559 | 89 | if (next != nullptr) | ||
560 | 90 | { | ||
561 | 91 | powerd_debug("%s found %zu remaining wakeup requests", G_STRFUNC, n_left); | ||
562 | 92 | set_wakeup_time(next->time, next->name); | ||
563 | 93 | if (!worker) | ||
564 | 94 | start_worker_thread(); | ||
565 | 95 | } | ||
566 | 96 | else if (worker) // no pending requests... | ||
567 | 97 | { | ||
568 | 98 | powerd_debug("shortening wakeup_time so worker thread will finish soon"); | ||
569 | 99 | set_wakeup_time(time(nullptr)+1, G_STRFUNC); | ||
570 | 100 | } | ||
571 | 101 | } | ||
572 | 102 | |||
573 | 103 | gboolean on_worker_thread_finished(gpointer /*unused*/) | ||
574 | 104 | { | ||
575 | 105 | // tell the world that we woke up | ||
576 | 106 | powerd_wakeup_signal_emit(); | ||
577 | 107 | |||
578 | 108 | // worker thread is done, so clean up our 'worker' variable | ||
579 | 109 | powerd_debug("worker thread is finished working; calling join()"); | ||
580 | 110 | worker->join(); | ||
581 | 111 | worker.reset(); | ||
582 | 112 | powerd_debug("worker thread is destroyed."); | ||
583 | 113 | |||
584 | 114 | reset_alarm_clock(); | ||
585 | 115 | |||
586 | 116 | return G_SOURCE_REMOVE; | ||
587 | 117 | } | ||
588 | 118 | |||
589 | 119 | void threadfunc(UHardwareAlarm hw_alarm) | ||
590 | 120 | { | ||
591 | 121 | // wait for the next alarm | ||
592 | 122 | powerd_debug("calling wait_for_next_alarm"); | ||
593 | 123 | UHardwareAlarmWaitResult wait_result; | ||
594 | 124 | auto rc = u_hardware_alarm_wait_for_next_alarm(hw_alarm, &wait_result); | ||
595 | 125 | powerd_debug("worker thread finished waiting for hw alarm"); | ||
596 | 126 | powerd_warn_if_fail(rc == U_STATUS_SUCCESS); | ||
597 | 127 | u_hardware_alarm_unref(hw_alarm); | ||
598 | 128 | |||
599 | 129 | // kick back to the main loop | ||
600 | 130 | g_idle_add(on_worker_thread_finished, nullptr); | ||
601 | 131 | } | ||
602 | 132 | |||
603 | 133 | void start_worker_thread() | ||
604 | 134 | { | ||
605 | 135 | powerd_return_if_fail(hardware_alarm != nullptr); | ||
606 | 136 | |||
607 | 137 | powerd_debug("starting hardware alarm worker thread"); | ||
608 | 138 | u_hardware_alarm_ref(hardware_alarm); | ||
609 | 139 | worker.reset(new std::thread(threadfunc, hardware_alarm)); | ||
610 | 140 | } | ||
611 | 141 | |||
612 | 142 | } // private impl in unnamed namespace | ||
613 | 143 | |||
614 | 144 | void | ||
615 | 145 | wakeup_init(void) | ||
616 | 146 | { | ||
617 | 147 | hardware_alarm = u_hardware_alarm_create(); | ||
618 | 148 | } | ||
619 | 149 | |||
620 | 150 | void | ||
621 | 151 | wakeup_deinit(void) | ||
622 | 152 | { | ||
623 | 153 | requests.clear(); | ||
624 | 154 | reset_alarm_clock(); | ||
625 | 155 | g_clear_pointer(&hardware_alarm, u_hardware_alarm_unref); | ||
626 | 156 | } | ||
627 | 157 | |||
628 | 158 | int | ||
629 | 159 | wakeup_request(const char* name, time_t wakeup_time, powerd_cookie_t cookie) | ||
630 | 160 | { | ||
631 | 161 | powerd_return_val_if_fail(hardware_alarm, ENOTSUP); | ||
632 | 162 | powerd_return_val_if_fail(wakeup_time > time(nullptr), EINVAL); | ||
633 | 163 | powerd_return_val_if_fail(cookie != NULL, EINVAL); | ||
634 | 164 | |||
635 | 165 | // generate a new uuid string | ||
636 | 166 | uuid_t tmp; | ||
637 | 167 | uuid_generate(tmp); | ||
638 | 168 | uuid_unparse(tmp, cookie); | ||
639 | 169 | |||
640 | 170 | requests[cookie] = { name, wakeup_time }; | ||
641 | 171 | |||
642 | 172 | reset_alarm_clock(); | ||
643 | 173 | return 0; | ||
644 | 174 | } | ||
645 | 175 | |||
646 | 176 | int | ||
647 | 177 | wakeup_clear(const powerd_cookie_t cookie) | ||
648 | 178 | { | ||
649 | 179 | powerd_return_val_if_fail(hardware_alarm, ENOTSUP); | ||
650 | 180 | auto it = requests.find(cookie); | ||
651 | 181 | powerd_return_val_if_fail(it != requests.end(), EINVAL); | ||
652 | 182 | |||
653 | 183 | requests.erase(it); | ||
654 | 184 | |||
655 | 185 | reset_alarm_clock(); | ||
656 | 186 | return 0; | ||
657 | 187 | } | ||
658 | 188 |
PASSED: Continuous integration, rev:142 jenkins. qa.ubuntu. com/job/ powerd- ci/160/ jenkins. qa.ubuntu. com/job/ powerd- utopic- armhf-ci/ 12 jenkins. qa.ubuntu. com/job/ powerd- utopic- armhf-ci/ 12/artifact/ work/output/ *zip*/output. zip
http://
Executed test runs:
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/powerd- ci/160/ rebuild
http://