Merge lp:~sforshee/powerd/backlight-settings into lp:powerd

Proposed by Seth Forshee
Status: Merged
Approved by: Michael Frey
Approved revision: 113
Merged at revision: 107
Proposed branch: lp:~sforshee/powerd/backlight-settings
Merge into: lp:powerd
Diff against target: 1178 lines (+419/-429)
12 files modified
CMakeLists.txt (+0/-4)
cli/powerd-cli.c (+109/-1)
data/com.canonical.powerd.xml (+17/-2)
data/device_configs/config-default.xml (+12/-0)
data/device_configs/config-mako.xml (+8/-0)
debian/changelog (+15/-0)
debian/control (+0/-1)
src/autobrightness.c (+5/-0)
src/backlight.c (+115/-309)
src/display.c (+115/-106)
src/powerd-internal.h (+11/-0)
src/powerd-object.c (+12/-6)
To merge this branch: bzr merge lp:~sforshee/powerd/backlight-settings
Reviewer Review Type Date Requested Status
Michael Frey (community) Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+187290@code.launchpad.net

Commit message

* Add dbus interfaces to allow getting brightness parameters and changing brightness settings
* Add powerd-cli support for these new dbus interfaces
* Change backlight code to use Android HAL for changing brightness, making it compatible with more devices
* Disable autobrightness on startup until user setting is supplied
* Fix build warning
* Eliminate short delay before changing screen brightness when going from a dim or off state to bright with autobrightness enabled (LP: #1221672)

Description of the change

* Add dbus interfaces to allow getting brightness parameters and changing brightness settings
* Add powerd-cli support for these new dbus interfaces
* Change backlight code to use Android HAL for changing brightness, making it compatible with more devices
* Disable autobrightness on startup until user setting is supplied
* Fix build warning
* Eliminate short delay before changing screen brightness when going from a dim or off state to bright with autobrightness enabled (LP: #1221672)

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:110
http://jenkins.qa.ubuntu.com/job/powerd-ci/120/
Executed test runs:
    None: http://jenkins.qa.ubuntu.com/job/powerd-saucy-armhf-ci/74/console

Click here to trigger a rebuild:
http://s-jenkins:8080/job/powerd-ci/120/rebuild

review: Needs Fixing (continuous-integration)
111. By Seth Forshee

Merge with master

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
112. By Seth Forshee

Merge with trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
113. By Seth Forshee

Merge with trunk

Also fix up some dependencies and hybris backlight integration
due to external changes since this code was written.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michael Frey (mfrey) wrote :

tested works great. Now need to reflect new API in settings.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2014-01-03 15:07:52 +0000
3+++ CMakeLists.txt 2014-01-14 03:16:31 +0000
4@@ -26,7 +26,6 @@
5 pkg_check_modules(GLIB glib-2.0)
6 pkg_check_modules(GIO gio-2.0)
7 pkg_check_modules(GIO-UNIX gio-unix-2.0)
8-pkg_check_modules(LIBUDEV libudev)
9 pkg_check_modules(UPOWER_GLIB upower-glib)
10 pkg_check_modules(UUID uuid)
11
12@@ -67,7 +66,6 @@
13 ${GLIB_LIBRARY_DIRS}
14 ${GIO_LIBRARY_DIRS}
15 ${GIO-UNIX_LIBRARY_DIRS}
16- ${LIBUDEV_LIBRARY_DIRS}
17 ${UPOWER_GLIB_LIBRARY_DIRS}
18 ${UUID_LIBRARY_DIRS}
19 )
20@@ -77,7 +75,6 @@
21 ${GLIB_INCLUDE_DIRS}
22 ${GIO_INCLUDE_DIRS}
23 ${GIO-UNIX_INCLUDE_DIRS}
24- ${LIBUDEV_INCLUDE_DIRS}
25 ${UPOWER_GLIB_INCLUDE_DIRS}
26 ${UUID_INCLUDE_DIRS}
27 ${PROJECT_SOURCE_DIR}/libsuspend
28@@ -119,7 +116,6 @@
29 "-lubuntu_application_api"
30 "-landroid-properties"
31 "-lhardware"
32- ${LIBUDEV_LIBRARIES}
33 ${UPOWER_GLIB_LIBRARIES}
34 ${UUID_LIBRARIES}
35 )
36
37=== modified file 'cli/powerd-cli.c'
38--- cli/powerd-cli.c 2013-08-12 14:32:56 +0000
39+++ cli/powerd-cli.c 2014-01-14 03:16:31 +0000
40@@ -21,6 +21,8 @@
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
44+#include <errno.h>
45+#include <limits.h>
46 #include <unistd.h>
47 #include <inttypes.h>
48 #include <sys/types.h>
49@@ -895,6 +897,65 @@
50 }
51
52 static void
53+setUserAutobrightness(gboolean enable)
54+{
55+ GVariant *ret = NULL;
56+ GError *error = NULL;
57+
58+ ret = g_dbus_proxy_call_sync(powerd_proxy,
59+ "userAutobrightnessEnable",
60+ g_variant_new("(b)", enable),
61+ G_DBUS_CALL_FLAGS_NONE,
62+ -1, NULL, &error);
63+ if (!ret) {
64+ cli_warn("userAutobrightnessEnable failed: %s", error->message);
65+ g_error_free(error);
66+ } else {
67+ g_variant_unref(ret);
68+ }
69+}
70+
71+static gboolean
72+getBrightnessParams(int *min, int *max, int *dflt, gboolean *ab_supported)
73+{
74+ GVariant *ret = NULL;
75+ GError *error = NULL;
76+
77+ ret = g_dbus_proxy_call_sync(powerd_proxy,
78+ "getBrightnessParams",
79+ NULL,
80+ G_DBUS_CALL_FLAGS_NONE,
81+ -1, NULL, &error);
82+ if (!ret) {
83+ cli_warn("getBrightnessParams failed: %s", error->message);
84+ g_error_free(error);
85+ return FALSE;
86+ }
87+
88+ g_variant_get(ret, "((iiib))", min, max, dflt, ab_supported);
89+ g_variant_unref(ret);
90+ return TRUE;
91+}
92+
93+static void setUserBrightness(int brightness)
94+{
95+ GVariant *ret = NULL;
96+ GError *error = NULL;
97+
98+ ret = g_dbus_proxy_call_sync(powerd_proxy,
99+ "setUserBrightness",
100+ g_variant_new("(i)", brightness),
101+ G_DBUS_CALL_FLAGS_NONE,
102+ -1, NULL, &error);
103+ if (!ret) {
104+ cli_warn("setUserBrightness failed: %s", error->message);
105+ g_error_free(error);
106+ } else {
107+ g_variant_unref(ret);
108+ }
109+}
110+
111+static void
112 usage(const char *progname)
113 {
114 printf("\n\n%s Options:\n",progname);
115@@ -903,6 +964,9 @@
116 printf("active-nc - same as active, but relies on powerd to cleanup\n"\
117 "\tthe request. This is only for testing and will immediately"\
118 "exit, causing the request to be dropped.\n");
119+ printf("autobrightness <enable|disable> - enable or disable autobrightness\n");
120+ printf("brightness <brightness> - set user screen brightness\n");
121+ printf("brightness-params - get brightness parameters (min, max, etc.)\n");
122 printf("clear-sys <cookie> - clear a System state request given a cookie\n");
123 printf("clear-disp <cookie> - clear a Display state request given a cookie\n");
124 printf("client-test - test powerd registration / ack API\n");
125@@ -955,7 +1019,10 @@
126 (strcmp(argv[1],"help")) &&
127 (strcmp(argv[1],"clear-disp")) &&
128 (strcmp(argv[1],"clear-sys")) &&
129- (strcmp(argv[1],"client-test"))) {
130+ (strcmp(argv[1],"client-test")) &&
131+ (strcmp(argv[1], "autobrightness")) &&
132+ (strcmp(argv[1], "brightness-params")) &&
133+ (strcmp(argv[1], "brightness"))) {
134 fprintf(stderr,"Invalid option %s\n",argv[1]);
135 usage(argv[0]);
136 return -1;
137@@ -1108,6 +1175,47 @@
138 }
139 else if (!strcmp(argv[1], "client-test")) {
140 powerd_cli_client_test(powerd_proxy);
141+ } else if (!strcmp(argv[1], "autobrightness")) {
142+ gboolean enable;
143+ if (argc != 3) {
144+ usage(argv[0]);
145+ exit(-1);
146+ }
147+ if (!strcmp(argv[2], "enable")) {
148+ enable = TRUE;
149+ } else if (!strcmp(argv[2], "disable")) {
150+ enable = FALSE;
151+ } else {
152+ fprintf(stderr, "Invalid autobrightness state\n");
153+ usage(argv[0]);
154+ exit(-1);
155+ }
156+ setUserAutobrightness(enable);
157+ } else if (!strcmp(argv[1], "brightness-params")) {
158+ int min, max, dflt, ab;
159+ if (getBrightnessParams(&min, &max, &dflt, &ab)) {
160+ printf("Minimum Brightness: %d\n"
161+ "Maximum Brightness: %d\n"
162+ "Default Brightness: %d\n"
163+ "Autobrightness: %ssupported\n",
164+ min, max, dflt, ab ? "" : "not ");
165+ }
166+ } else if (!strcmp(argv[1], "brightness")) {
167+ long brightness;
168+ char *endp;
169+ if (argc != 3) {
170+ usage(argv[0]);
171+ exit(-1);
172+ }
173+ errno = 0;
174+ brightness = strtol(argv[2], &endp, 10);
175+ if (errno == ERANGE || *endp != '\0' ||
176+ brightness < 0 || brightness > INT_MAX) {
177+ fprintf(stderr, "Invalid brightness %s\n", argv[2]);
178+ usage(argv[0]);
179+ exit(-1);
180+ }
181+ setUserBrightness((int)brightness);
182 }
183 return 0;
184 }
185
186=== modified file 'data/com.canonical.powerd.xml'
187--- data/com.canonical.powerd.xml 2013-08-12 02:46:09 +0000
188+++ data/com.canonical.powerd.xml 2014-01-14 03:16:31 +0000
189@@ -27,6 +27,10 @@
190 <arg type="u" name="flags" direction="in" />
191 </method>
192
193+ <method name="clearDisplayState">
194+ <arg type="s" name="cookie" direction="in" />
195+ </method>
196+
197 <method name="registerClient">
198 <arg type="s" name="name" direction="in" />
199 </method>
200@@ -39,8 +43,19 @@
201 <arg type="i" name="state" direction="in" />
202 </method>
203
204- <method name="clearDisplayState">
205- <arg type="s" name="cookie" direction="in" />
206+ <!-- User settings -->
207+ <method name="userAutobrightnessEnable">
208+ <arg type="b" name="enable" direction="in" />
209+ </method>
210+
211+ <method name="getBrightnessParams">
212+ <!-- Returns min, max, and default brighness and whether or not
213+ autobrightness is supported, in that order -->
214+ <arg type="(iiib)" name="params" direction="out" />
215+ </method>
216+
217+ <method name="setUserBrightness">
218+ <arg type="i" name="brightness" direction="in" />
219 </method>
220
221 <!-- for debug/testing -->
222
223=== modified file 'data/device_configs/config-default.xml'
224--- data/device_configs/config-default.xml 2013-08-29 21:22:33 +0000
225+++ data/device_configs/config-default.xml 2014-01-14 03:16:31 +0000
226@@ -54,6 +54,18 @@
227 <integer-array name="config_autoBrightnessLevels">
228 </integer-array>
229
230+ <!-- Minimum screen brightness setting allowed by the power manager.
231+ The user is forbidden from setting the brightness below this level. -->
232+ <integer name="config_screenBrightnessSettingMinimum">10</integer>
233+
234+ <!-- Maximum screen brightness allowed by the power manager.
235+ The user is forbidden from setting the brightness above this level. -->
236+ <integer name="config_screenBrightnessSettingMaximum">255</integer>
237+
238+ <!-- Default screen brightness setting.
239+ Must be in the range specified by minimum and maximum. -->
240+ <integer name="config_screenBrightnessSettingDefault">102</integer>
241+
242 <!-- Screen brightness used to dim the screen when the user activity
243 timeout expires. May be less than the minimum allowed brightness setting
244 that can be set by the user. -->
245
246=== modified file 'data/device_configs/config-mako.xml'
247--- data/device_configs/config-mako.xml 2013-08-29 21:22:33 +0000
248+++ data/device_configs/config-mako.xml 2014-01-14 03:16:31 +0000
249@@ -69,6 +69,14 @@
250 <!-- Minimum screen brightness allowed by the power manager. -->
251 <integer name="config_screenBrightnessDim">1</integer>
252
253+ <!-- Default screen brightness setting.
254+ Must be in the range specified by minimum and maximum. -->
255+ <integer name="config_screenBrightnessSettingDefault">87</integer>
256+
257+ <!-- Minimum screen brightness setting allowed by the power manager.
258+ The user is forbidden from setting the brightness below this level. -->
259+ <integer name="config_screenBrightnessSettingMinimum">1</integer>
260+
261 <!-- Shutdown if the battery temperature exceeds (this value * 0.1) Celsius. -->
262 <integer name="config_shutdownBatteryTemperature">600</integer>
263
264
265=== modified file 'debian/changelog'
266--- debian/changelog 2014-01-08 06:17:09 +0000
267+++ debian/changelog 2014-01-14 03:16:31 +0000
268@@ -1,3 +1,18 @@
269+powerd (0.13+14.04.20140108.1-0ubuntu2) UNRELEASED; urgency=low
270+
271+ * Add dbus interfaces to allow getting brightness parameters and
272+ changing brightness settings
273+ * Add powerd-cli support for these new dbus interfaces
274+ * Change backlight code to use Android HAL for changing brightness,
275+ making it compatible with more devices
276+ * Disable autobrightness on startup until user setting is supplied
277+ * Fix build warning
278+ * Eliminate short delay before changing screen brightness when going
279+ from a dim or off state to bright with autobrightness enabled
280+ (LP: #1221672)
281+
282+ -- Seth Forshee <seth.forshee@canonical.com> Mon, 13 Jan 2014 15:59:44 -0600
283+
284 powerd (0.13+14.04.20140108.1-0ubuntu1) trusty; urgency=low
285
286 [ Ricardo Salveti de Araujo ]
287
288=== modified file 'debian/control'
289--- debian/control 2013-12-06 22:11:52 +0000
290+++ debian/control 2014-01-14 03:16:31 +0000
291@@ -7,7 +7,6 @@
292 libglib2.0-dev,
293 android-headers (>= 4.2.2),
294 libhybris-dev (>= 0.1.0+git20131206+0cdd7f2-0ubuntu1),
295- libudev-dev,
296 python,
297 libandroid-properties-dev,
298 libplatform-api1-dev,
299
300=== modified file 'src/autobrightness.c'
301--- src/autobrightness.c 2013-09-04 14:41:22 +0000
302+++ src/autobrightness.c 2014-01-14 03:16:31 +0000
303@@ -274,6 +274,11 @@
304 }
305 }
306
307+gboolean powerd_autobrightness_available(void)
308+{
309+ return ab_supported;
310+}
311+
312 int powerd_autobrightness_init(void)
313 {
314 GValue v = G_VALUE_INIT;
315
316=== modified file 'src/backlight.c'
317--- src/backlight.c 2013-07-02 15:50:42 +0000
318+++ src/backlight.c 2014-01-14 03:16:31 +0000
319@@ -21,344 +21,150 @@
320 * along with this program. If not, see <http://www.gnu.org/licenses/>.
321 */
322
323-#include <stdio.h>
324-#include <stdlib.h>
325-#include <string.h>
326 #include <errno.h>
327-#include <sys/types.h>
328-#include <sys/stat.h>
329-#include <fcntl.h>
330-#include <unistd.h>
331-#include <libudev.h>
332 #include <glib.h>
333-#include <glib-unix.h>
334+#include <glib-object.h>
335+#include <android/hardware/hardware.h>
336+#include <android/hardware/lights.h>
337
338 #include "powerd-internal.h"
339+#include "device-config.h"
340 #include "log.h"
341
342-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
343-
344-struct udev *udev;
345-struct udev_monitor *udev_mon;
346-guint udev_mon_source_id;
347-
348-enum bl_type {
349- BL_TYPE_FIRMWARE,
350- BL_TYPE_PLATFORM,
351- BL_TYPE_RAW,
352-};
353-
354-static const char *bl_strs[] = {
355- [BL_TYPE_FIRMWARE] = "firmware",
356- [BL_TYPE_PLATFORM] = "platform",
357- [BL_TYPE_RAW] = "raw",
358-};
359-
360-struct bl_device {
361- struct udev_device *dev;
362- enum bl_type type;
363- int max_brightness;
364-};
365-
366-struct bl_device *preferred_bl;
367-GSList *bl_devices;
368-
369-static int bl_parse_type(const char *type_str)
370-{
371- unsigned i;
372-
373- for (i = 0; i < ARRAY_SIZE(bl_strs); i++) {
374- if (!strcmp(type_str, bl_strs[i]))
375- return i;
376- }
377- return -1;
378-}
379-
380-static struct bl_device *new_backlight(struct udev_device *dev)
381-{
382- struct bl_device *bl_dev;
383- int type;
384- long max_brightness;
385- const char *data;
386-
387- powerd_debug("Processing backlight device %s",
388- udev_device_get_syspath(dev));
389-
390- data = udev_device_get_sysattr_value(dev, "type");
391- if (!data) {
392- powerd_error("Could not read backlight \"type\" attribute");
393- return NULL;
394- }
395- type = bl_parse_type(data);
396- if (type < 0) {
397- powerd_error("Invalid backlight type \"%s\"", data);
398- return NULL;
399- }
400-
401- data = udev_device_get_sysattr_value(dev, "max_brightness");
402- if (!data) {
403- powerd_error("Could not read backlight \"max_brightness\" attribute");
404- return NULL;
405- }
406- errno = 0;
407- max_brightness = strtol(data, NULL, 10);
408- if (errno != 0) {
409- powerd_error("Invalid max_brightness \"%s\"", data);
410- return NULL;
411- }
412-
413- bl_dev = malloc(sizeof(*bl_dev));
414- if (!bl_dev) {
415- powerd_error("Falied to allocate memory for backlight device: %s",
416- strerror(errno));
417- return NULL;
418- }
419-
420- udev_device_ref(dev);
421- bl_dev->dev = dev;
422- bl_dev->type = type;
423- bl_dev->max_brightness = (int)max_brightness;
424-
425- return bl_dev;
426-}
427-
428-static void free_backlight(struct bl_device *bl)
429-{
430- udev_device_unref(bl->dev);
431- free(bl);
432-}
433-
434-static gboolean remove_backlight(const char *path)
435-{
436- GSList *item;
437- struct bl_device *bl;
438-
439- for (item = bl_devices; item; item = g_slist_next(item)) {
440- bl = item->data;
441- if (!strcmp(path, udev_device_get_syspath(bl->dev))) {
442- bl_devices = g_slist_remove(bl_devices, bl);
443- free_backlight(bl);
444- return TRUE;
445- }
446- }
447-
448- return FALSE;
449-}
450-
451-static void update_preferred_backlight(void)
452-{
453- GSList *item;
454- struct bl_device *bl;
455-
456- preferred_bl = NULL;
457- for (item = bl_devices; item; item = g_slist_next(item)) {
458- bl = item->data;
459- if (!preferred_bl || bl->type < preferred_bl->type)
460- preferred_bl = bl;
461- }
462-
463- if (preferred_bl)
464- powerd_info("Using backlight at %s",
465- udev_device_get_syspath(preferred_bl->dev));
466- else
467- powerd_warn("No backlights present");
468-}
469-
470-/* Returns number of backlight devices found */
471-static int find_backlights(void)
472-{
473- int found = 0;
474- struct udev_enumerate *enumerate;
475- struct udev_list_entry *devices, *dev_list_entry;
476-
477- enumerate = udev_enumerate_new(udev);
478- udev_enumerate_add_match_subsystem(enumerate, "backlight");
479- udev_enumerate_scan_devices(enumerate);
480-
481- devices = udev_enumerate_get_list_entry(enumerate);
482- udev_list_entry_foreach(dev_list_entry, devices) {
483- struct udev_device *dev;
484- const char *path;
485- struct bl_device *new_bl;
486-
487- path = udev_list_entry_get_name(dev_list_entry);
488- dev = udev_device_new_from_syspath(udev, path);
489- new_bl = new_backlight(dev);
490- if (new_bl) {
491- bl_devices = g_slist_append(bl_devices, new_bl);
492- found++;
493- }
494- udev_device_unref(dev);
495- }
496-
497- udev_enumerate_unref(enumerate);
498- return found;
499-}
500-
501-static gboolean bl_monitor_handler(gint fd, GIOCondition cond, gpointer data)
502-{
503- struct udev_device *dev;
504- const char *path, *action;
505- struct bl_device *new_bl;
506- gboolean update = FALSE;
507-
508- dev = udev_monitor_receive_device(udev_mon);
509- if (dev) {
510- path = udev_device_get_syspath(dev);
511- action = udev_device_get_action(dev);
512- powerd_debug("Received action %s for %s", action, path);
513-
514- if (!strcmp(action, "add")) {
515- new_bl = new_backlight(dev);
516- if (new_bl) {
517- bl_devices = g_slist_append(bl_devices, new_bl);
518- update = TRUE;
519- }
520- } else if (!strcmp(action, "remove")) {
521- update = remove_backlight(path);
522- }
523-
524- udev_device_unref(dev);
525- }
526-
527- if (update)
528- update_preferred_backlight();
529-
530- return TRUE;
531-}
532-
533-static int bl_monitor_init(void)
534-{
535- int fd;
536-
537- udev_mon = udev_monitor_new_from_netlink(udev, "udev");
538- if (!udev_mon)
539- return -ENODEV;
540-
541- udev_monitor_filter_add_match_subsystem_devtype(udev_mon, "backlight", NULL);
542- udev_monitor_enable_receiving(udev_mon);
543- fd = udev_monitor_get_fd(udev_mon);
544- udev_mon_source_id = g_unix_fd_add(fd, G_IO_IN, bl_monitor_handler, NULL);
545- return 0;
546-}
547-
548-static void bl_monitor_deinit(void)
549-{
550- if (!udev_mon)
551- return;
552-
553- g_source_remove(udev_mon_source_id);
554- udev_monitor_unref(udev_mon);
555- udev_mon = NULL;
556-}
557+struct light_device_t *light_dev;
558+
559+/*
560+ * Defaults are Android default settings. They may not work if we
561+ * can't read the per-device values, but they're as good as
562+ * anything else.
563+ */
564+int min_user_brightness = 10;
565+int max_brightness = 255;
566+int default_brightness = 102;
567+int dim_brightness = 10;
568+int current_brightness = -1;
569
570 int powerd_get_brightness(void)
571 {
572- char path[128];
573- char data[32];
574- ssize_t ret;
575- int fd;
576-
577- if (!udev || !preferred_bl)
578- return -ENODEV;
579-
580- /*
581- * libudev interface returned cached values for attributes.
582- * When this is called we want to get the actual value from
583- * sysfs, so we must read it ourselves.
584- */
585- ret = snprintf(path, ARRAY_SIZE(path), "%s/%s",
586- udev_device_get_syspath(preferred_bl->dev), "brightness");
587- if (ret >= ARRAY_SIZE(path)) {
588- powerd_warn("Buffer not big enough for path to brightness attribute");
589- return -EIO;
590- }
591-
592- fd = open(path, O_RDONLY);
593- if (fd < 0) {
594- powerd_warn("Could not open %s", path);
595- return -errno;
596- }
597-
598- ret = read(fd, data, ARRAY_SIZE(data) - 1);
599- if (ret < 0) {
600- powerd_warn("Failed to read brightness");
601- ret = errno;
602- goto error;
603- }
604- data[ret] = 0;
605-
606- close(fd);
607- return atoi(data);
608-
609-error:
610- close(fd);
611- return (int)ret;
612+ return current_brightness;
613 }
614
615 int powerd_get_max_brightness(void)
616 {
617- if (!preferred_bl)
618- return -ENODEV;
619- return preferred_bl->max_brightness;
620+ return max_brightness;
621 }
622
623 int powerd_set_brightness(int brightness)
624 {
625- char buf[32];
626+ struct light_state_t state;
627+ int scaled_brightness;
628 int ret;
629
630- if (!udev || !preferred_bl)
631+ if (!light_dev)
632 return -ENODEV;
633-
634- ret = snprintf(buf, ARRAY_SIZE(buf), "%d", brightness);
635- if (ret >= ARRAY_SIZE(buf))
636+ if (brightness < 0 || brightness > max_brightness)
637 return -EINVAL;
638-
639- return udev_device_set_sysattr_value(preferred_bl->dev, "brightness", buf);
640+ if (brightness == current_brightness)
641+ return 0;
642+
643+ /* Scale brightness to range of 0 to 255 */
644+ scaled_brightness = (brightness * 255) / max_brightness;
645+ if (scaled_brightness > 255)
646+ scaled_brightness = 255;
647+
648+ state.flashMode = LIGHT_FLASH_NONE;
649+ state.brightnessMode = BRIGHTNESS_MODE_USER;
650+ /* color is ARGB, docs specifiy that alpha should be 0xff,
651+ * although it also instructs callers to ignore it. */
652+ state.color = (int)((0xffU << 24) | (scaled_brightness << 16) |
653+ (scaled_brightness << 8) | scaled_brightness);
654+
655+ ret = light_dev->set_light(light_dev, &state);
656+ if (!ret)
657+ current_brightness = brightness;
658+ return ret;
659+}
660+
661+int powerd_set_user_brightness(int brightness)
662+{
663+ return powerd_set_brightness(brightness < min_user_brightness ?
664+ min_user_brightness : brightness);
665+}
666+
667+void powerd_dim_screen(void)
668+{
669+ powerd_set_brightness(dim_brightness);
670 }
671
672 int powerd_backlight_init(void)
673 {
674- int count;
675-
676- udev = udev_new();
677- if (!udev) {
678- powerd_error("udev_new() failed, backlight support is disabled");
679- return -ENODEV;
680- }
681-
682- /*
683- * Start monitoring before scanning so we don't miss devices which
684- * might appear in the interim
685- */
686- bl_monitor_init();
687-
688- count = find_backlights();
689- if (count)
690- update_preferred_backlight();
691- else
692- powerd_warn("No backlight devices found");
693+ GValue v = G_VALUE_INIT;
694+ const struct hw_module_t *hwmod = NULL;
695+
696+ if (!device_config_get("screenBrightnessDim", &v)) {
697+ if (G_VALUE_HOLDS_UINT(&v))
698+ dim_brightness = (int)g_value_get_uint(&v);
699+ g_value_unset(&v);
700+ }
701+ if (!device_config_get("screenBrightnessSettingMinimum", &v)) {
702+ if (G_VALUE_HOLDS_UINT(&v))
703+ min_user_brightness = (int)g_value_get_uint(&v);
704+ g_value_unset(&v);
705+ }
706+ if (!device_config_get("screenBrightnessSettingMaximum", &v)) {
707+ if (G_VALUE_HOLDS_UINT(&v))
708+ max_brightness = (int)g_value_get_uint(&v);
709+ g_value_unset(&v);
710+ }
711+ if (!device_config_get("screenBrightnessSettingDefault", &v)) {
712+ if (G_VALUE_HOLDS_UINT(&v))
713+ default_brightness = (int)g_value_get_uint(&v);
714+ g_value_unset(&v);
715+ }
716+
717+ /* Sanity check default brightness value */
718+ if (default_brightness < min_user_brightness)
719+ default_brightness = min_user_brightness;
720+ else if (default_brightness > max_brightness)
721+ default_brightness = max_brightness;
722+
723+ if (hw_get_module(LIGHTS_HARDWARE_MODULE_ID, &hwmod)) {
724+ powerd_warn("Could not get lights module");
725+ return -ENODEV;
726+ }
727+ if (hwmod->methods->open(hwmod, LIGHT_ID_BACKLIGHT,
728+ (hw_device_t **)&light_dev)) {
729+ powerd_warn("Could not open backlight, brightness adjustment will be disabled");
730+ light_dev = NULL;
731+ return -ENODEV;
732+ }
733+
734+ /* XXX: May want to eliminate this when integration with shell
735+ * is complete and just wait for it to apply user settings.
736+ * Unfortunately the HAL provides no way for us to read the
737+ * current brightness when we start. */
738+ powerd_set_brightness(default_brightness);
739
740 return 0;
741 }
742
743-static void bl_destroy(gpointer data)
744-{
745- struct bl_device *bl = data;
746- free_backlight(bl);
747-}
748-
749 void powerd_backlight_deinit(void)
750 {
751- if (!udev)
752- return;
753-
754- bl_monitor_deinit();
755- g_slist_free_full(bl_devices, bl_destroy);
756- udev_unref(udev);
757-
758- bl_devices = NULL;
759- preferred_bl = NULL;
760- udev = NULL;
761+ light_dev = NULL;
762+}
763+
764+
765+/** dbus interfaces **/
766+
767+gboolean handle_get_brightness_params(PowerdSource *obj,
768+ GDBusMethodInvocation *invocation)
769+{
770+ gboolean ab_available = powerd_autobrightness_available();
771+ g_dbus_method_invocation_return_value(invocation,
772+ g_variant_new("((iiib))",
773+ min_user_brightness,
774+ max_brightness,
775+ default_brightness,
776+ ab_available));
777+ return TRUE;
778 }
779
780=== modified file 'src/display.c'
781--- src/display.c 2014-01-03 15:23:38 +0000
782+++ src/display.c 2014-01-14 03:16:31 +0000
783@@ -36,9 +36,18 @@
784
785 #include "powerd.h"
786 #include "powerd-internal.h"
787-#include "device-config.h"
788 #include "log.h"
789
790+enum bl_state {
791+ BL_OFF,
792+ BL_DIM,
793+ BL_BRIGHT,
794+ BL_AUTO,
795+
796+ NUM_BL_STATES
797+};
798+static enum bl_state target_bl_state = BL_BRIGHT;
799+
800 /* Mir usage hint file path */
801 #define MIR_HINT_PATH "/home/phablet/.display-mir"
802
803@@ -50,9 +59,8 @@
804 POWERD_DISPLAY_FLAG_DISABLE_AUTOBRIGHTNESS)
805 #define AB_ENABLED POWERD_DISPLAY_FLAG_BRIGHT
806
807-static gint saved_brightness = 255;
808-static gint target_brightness;
809-static gint dim_brightness;
810+static int user_brightness;
811+static gboolean user_ab_enabled;
812 static gboolean running_mir = FALSE;
813
814 /* Assume screen is off to start; we will force it on */
815@@ -91,9 +99,60 @@
816
817 static gboolean ab_enabled(guint32 flags)
818 {
819+ if (!powerd_autobrightness_available())
820+ return FALSE;
821+ if (!user_ab_enabled)
822+ return FALSE;
823 return (flags & AB_ENABLED_MASK) == AB_ENABLED;
824 }
825
826+static void set_backlight(enum bl_state state)
827+{
828+ static enum bl_state current_state = BL_BRIGHT;
829+ static int restore_brightness = 0;
830+
831+ if (state >= NUM_BL_STATES) {
832+ powerd_warn("Unknown backlight state %d\n", state);
833+ return;
834+ }
835+ if (state != BL_AUTO)
836+ powerd_autobrightness_disable();
837+
838+ /*
839+ * When we're enabling autobrightness it takes a second to
840+ * settle on a brightness level after enabling. This delay
841+ * becomes very noticible when going from the dim to bright
842+ * state. To avoid this lag, save off the current brightness
843+ * any time the state goes from BRIGHT or AUTO and restore
844+ * it if transitioning back to AUTO.
845+ */
846+ if (current_state >= BL_BRIGHT && state < BL_BRIGHT)
847+ restore_brightness = powerd_get_brightness();
848+
849+ switch (state) {
850+ case BL_OFF:
851+ powerd_set_brightness(0);
852+ break;
853+ case BL_DIM:
854+ powerd_dim_screen();
855+ break;
856+ case BL_BRIGHT:
857+ powerd_set_user_brightness(user_brightness);
858+ break;
859+ case BL_AUTO:
860+ if (current_state < BL_BRIGHT && restore_brightness > 0)
861+ powerd_set_brightness(restore_brightness);
862+ powerd_autobrightness_enable();
863+ break;
864+ default:
865+ /* default case is to satisfy static analysis tools, should
866+ * never actually get here */
867+ powerd_error("Unknwown backlight state %d\n", state);
868+ return;
869+ }
870+ current_state = state;
871+}
872+
873 gboolean display_set_power_mode(int display, char *power_mode)
874 {
875 GError *error = NULL;
876@@ -146,13 +205,11 @@
877 return TRUE;
878 }
879
880-static void turn_on_display(gboolean autobrightness) {
881+static void turn_on_display(void)
882+{
883 powerd_debug("turning on display");
884 display_set_power_mode(0, "on");
885- if (autobrightness)
886- powerd_autobrightness_enable();
887- else
888- powerd_set_brightness(target_brightness);
889+ set_backlight(target_bl_state);
890 }
891
892 gboolean powerd_display_enabled(void)
893@@ -160,49 +217,11 @@
894 return actual_screen_state == POWERD_DISPLAY_STATE_ON;
895 }
896
897-static int get_target_brightness(gboolean request_bright, int hw_value)
898-{
899- /*
900- * If not requesting bright, return the dim brightness, but never
901- * return something higher than the current "bright" brightness.
902- */
903- if (request_bright == FALSE)
904- return (saved_brightness < dim_brightness) ?
905- saved_brightness : dim_brightness;
906-
907- /*
908- * If bright is requested and our current state is also bright,
909- * just return the current hardware value.
910- */
911- if ((internal_state.flags & POWERD_DISPLAY_FLAG_BRIGHT) && (hw_value > 0))
912- return hw_value;
913-
914- /* Otherwise we're going from dim to bright, so return the saved value */
915- return saved_brightness;
916-}
917-
918 static void update_display_state(struct powerd_display_request *req)
919 {
920 enum powerd_display_state state = req->state;
921- gboolean use_ab, using_ab;
922 int applied_state;
923 int ret;
924- int hw_brightness;
925-
926- use_ab = ab_enabled(req->flags);
927- using_ab = ab_enabled(internal_state.flags);
928-
929- hw_brightness = powerd_get_brightness();
930- if (hw_brightness < 0)
931- hw_brightness = saved_brightness;
932-
933- if (!using_ab && hw_brightness != 0 &&
934- (internal_state.flags & POWERD_DISPLAY_FLAG_BRIGHT))
935- saved_brightness = hw_brightness;
936- if (!use_ab)
937- target_brightness = get_target_brightness(
938- !!(req->flags & POWERD_DISPLAY_FLAG_BRIGHT),
939- hw_brightness);
940
941 applied_state = screen_off_overrides ? DISPLAY_STATE_OFF : state;
942
943@@ -214,9 +233,7 @@
944 }
945
946 powerd_debug("turning off display");
947- if (using_ab)
948- powerd_autobrightness_disable();
949- powerd_set_brightness(0);
950+ set_backlight(BL_OFF);
951 if (!display_set_power_mode(0, "off")) {
952 powerd_warn("failed to set display power mode, not clearing state");
953 return;
954@@ -232,6 +249,13 @@
955 }
956 break;
957 case POWERD_DISPLAY_STATE_ON:
958+ if (ab_enabled(req->flags))
959+ target_bl_state = BL_AUTO;
960+ else if (req->flags & POWERD_DISPLAY_FLAG_BRIGHT)
961+ target_bl_state = BL_BRIGHT;
962+ else
963+ target_bl_state = BL_DIM;
964+
965 if (actual_screen_state != POWERD_DISPLAY_STATE_ON) {
966 powerd_debug("Requesting active state internally");
967 ret = request_sys_state_internal("display-request",
968@@ -247,21 +271,10 @@
969 * Otherwise we can turn on the screen right away.
970 */
971 if (!powerd_suspend_active())
972- turn_on_display(use_ab);
973+ turn_on_display();
974 } else {
975- /* Only changing brightness */
976- if (use_ab) {
977- if (!using_ab)
978- powerd_autobrightness_enable();
979- } else {
980- if (using_ab) {
981- powerd_autobrightness_disable();
982- powerd_set_brightness(target_brightness);
983- } else if ((req->flags & POWERD_DISPLAY_FLAG_BRIGHT) !=
984- (internal_state.flags & POWERD_DISPLAY_FLAG_BRIGHT)) {
985- powerd_set_brightness(target_brightness);
986- }
987- }
988+ /* Only updating backlight state */
989+ set_backlight(target_bl_state);
990 }
991 break;
992 default:
993@@ -310,6 +323,12 @@
994 internal_state = *req;
995 }
996
997+static void user_ab_enable(gboolean enable)
998+{
999+ user_ab_enabled = enable;
1000+ update_display_state(&internal_state);
1001+}
1002+
1003 static gboolean prox_update_worker(gpointer data)
1004 {
1005 unsigned long near = (unsigned long)data;
1006@@ -376,12 +395,20 @@
1007 powerd_run_mainloop_sync(apply_override_worker, &ovr_data);
1008 }
1009
1010+static void set_user_brightness(int brightness)
1011+{
1012+ int max = powerd_get_max_brightness();
1013+ if (brightness > max)
1014+ brightness = max;
1015+ user_brightness = brightness;
1016+ update_display_state(&internal_state);
1017+}
1018
1019 static gboolean exit_suspend_worker(gpointer unused)
1020 {
1021 /* Make sure suspend is still disabled */
1022 if (!powerd_suspend_active() && powerd_display_enabled())
1023- turn_on_display(ab_enabled(internal_state.flags));
1024+ turn_on_display();
1025 return FALSE;
1026 }
1027
1028@@ -392,49 +419,10 @@
1029
1030 int powerd_display_init(void)
1031 {
1032- GValue v = G_VALUE_INIT;
1033- int brightness, max_brightness;
1034 struct stat stats;
1035
1036- /*
1037- * Warning: much hand waving follows
1038- *
1039- * Right now there's no coherent system brightness policy, so we
1040- * just do the best we can. For "dim" brightness we try to read
1041- * the value from the Android config files, otherwise we just go
1042- * with 5% of maximum. For "bright" brightness, it's more
1043- * complicated.
1044- *
1045- * Our first preference for the bright value is whatever the screen
1046- * is currently set to. However, the screen could be off or dimmed
1047- * when powerd starts, so we fall back to 75% of maximum when that
1048- * happens.
1049- */
1050-
1051- if (!device_config_get("screenBrightnessDim", &v)) {
1052- if (G_VALUE_HOLDS_UINT(&v))
1053- dim_brightness = (int)g_value_get_uint(&v);
1054- g_value_unset(&v);
1055- }
1056-
1057- max_brightness = powerd_get_max_brightness();
1058-
1059- if (max_brightness <= 0) {
1060- powerd_warn("Could not read maximum brightness, guessing at dim/bright values");
1061- saved_brightness = 100;
1062- if (dim_brightness == 0)
1063- dim_brightness = 5;
1064- } else {
1065- saved_brightness = (3 * max_brightness) / 4;
1066- if (dim_brightness == 0)
1067- dim_brightness = max_brightness / 20;
1068- }
1069-
1070- brightness = powerd_get_brightness();
1071- if (brightness > dim_brightness)
1072- saved_brightness = brightness;
1073-
1074- target_brightness = saved_brightness;
1075+ /* Use the current brightness until we're told another value */
1076+ user_brightness = powerd_get_brightness();
1077
1078 /* decide whether we are running on Mir or SF */
1079 if (stat(MIR_HINT_PATH, &stats) == 0)
1080@@ -442,3 +430,24 @@
1081
1082 return 0;
1083 }
1084+
1085+
1086+/** dbus interfaces **/
1087+
1088+gboolean handle_user_autobrightness_enable(PowerdSource *obj,
1089+ GDBusMethodInvocation *invocation,
1090+ gboolean enable)
1091+{
1092+ user_ab_enable(enable);
1093+ g_dbus_method_invocation_return_value(invocation, NULL);
1094+ return TRUE;
1095+}
1096+
1097+gboolean handle_set_user_brightness(PowerdSource *obj,
1098+ GDBusMethodInvocation *invocation,
1099+ gint brightness)
1100+{
1101+ set_user_brightness(brightness);
1102+ g_dbus_method_invocation_return_value(invocation, NULL);
1103+ return TRUE;
1104+}
1105
1106=== modified file 'src/powerd-internal.h'
1107--- src/powerd-internal.h 2014-01-03 15:23:38 +0000
1108+++ src/powerd-internal.h 2014-01-14 03:16:31 +0000
1109@@ -62,6 +62,7 @@
1110 void powerd_new_als_event(double lux);
1111 void powerd_autobrightness_enable(void);
1112 void powerd_autobrightness_disable(void);
1113+gboolean powerd_autobrightness_available(void);
1114 int powerd_autobrightness_init(void);
1115 void powerd_autobrightness_deinit(void);
1116
1117@@ -71,6 +72,10 @@
1118 int powerd_get_brightness(void);
1119 int powerd_get_max_brightness(void);
1120 int powerd_set_brightness(int brightness);
1121+int powerd_set_user_brightness(int brightness);
1122+void powerd_dim_screen(void);
1123+gboolean handle_get_brightness_params(PowerdSource *obj,
1124+ GDBusMethodInvocation *invocation);
1125
1126 /* Display functions */
1127 void powerd_brightness_set_value(gint value);
1128@@ -81,6 +86,12 @@
1129 void powerd_proximity_event(gboolean near);
1130 void powerd_display_set_override(enum powerd_override_reason reason);
1131 void powerd_display_clear_override(enum powerd_override_reason reason);
1132+gboolean handle_user_autobrightness_enable(PowerdSource *obj,
1133+ GDBusMethodInvocation *invocation,
1134+ gboolean enable);
1135+gboolean handle_set_user_brightness(PowerdSource *obj,
1136+ GDBusMethodInvocation *invocation,
1137+ gint brightness);
1138
1139 /* Display request functions */
1140 int powerd_add_display_request(struct powerd_display_request *request,
1141
1142=== modified file 'src/powerd-object.c'
1143--- src/powerd-object.c 2013-08-12 02:46:09 +0000
1144+++ src/powerd-object.c 2014-01-14 03:16:31 +0000
1145@@ -124,14 +124,14 @@
1146
1147 owner = g_dbus_method_invocation_get_sender(invocation);
1148 ret = powerd_client_ack(owner, state);
1149- if (ret) {
1150- const char *msg = (ret == -EINVAL) ? "Invalid state" :
1151- "Client not registered";
1152+ if (ret)
1153 g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR,
1154- G_DBUS_ERROR_INVALID_ARGS, msg);
1155- } else {
1156+ G_DBUS_ERROR_INVALID_ARGS,
1157+ ret == -EINVAL ?
1158+ "Invalid state" :
1159+ "Client not registered");
1160+ else
1161 g_dbus_method_invocation_return_value(invocation, NULL);
1162- }
1163 return TRUE;
1164 }
1165
1166@@ -181,6 +181,12 @@
1167 G_CALLBACK(handle_get_sys_request_stats), powerd_source);
1168 g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-get-disp-request-stats",
1169 G_CALLBACK(handle_get_disp_request_stats), powerd_source);
1170+ g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-user-autobrightness-enable",
1171+ G_CALLBACK(handle_user_autobrightness_enable), powerd_source);
1172+ g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-get-brightness-params",
1173+ G_CALLBACK(handle_get_brightness_params), powerd_source);
1174+ g_signal_connect(G_OBJECT(powerd_source->priv->skel), "handle-set-user-brightness",
1175+ G_CALLBACK(handle_set_user_brightness), powerd_source);
1176
1177 powerd_dbus_init_complete();
1178 }

Subscribers

People subscribed via source and target branches