aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/brightness.c509
-rw-r--r--src/brightness.h67
-rw-r--r--src/ib-brightness-control.c156
-rw-r--r--src/ib-brightness-control.h33
-rw-r--r--src/ib-brightness-uscreen-control.c202
-rw-r--r--src/ib-brightness-uscreen-control.h43
-rw-r--r--src/service.c193
8 files changed, 680 insertions, 526 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9b3d815..f7efb80 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -5,9 +5,8 @@ add_definitions(-DG_LOG_DOMAIN="Indicator-Power")
# handwritten sources
set(SERVICE_MANUAL_SOURCES
+ brightness.c
device-provider-upower.c
- ib-brightness-control.c
- ib-brightness-uscreen-control.c
device-provider.c
device.c
notifier.c
diff --git a/src/brightness.c b/src/brightness.c
new file mode 100644
index 0000000..5e7c5e5
--- /dev/null
+++ b/src/brightness.c
@@ -0,0 +1,509 @@
+/*
+ * Copyright 2014 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Charles Kerr <charles.kerr@canonical.com>
+ */
+
+#include "brightness.h"
+
+#include <gio/gio.h>
+
+#define SCHEMA_NAME "com.ubuntu.touch.system"
+#define KEY_AUTO "auto-brightness"
+#define KEY_AUTO_SUPPORTED "auto-brightness-supported"
+#define KEY_BRIGHTNESS "brightness"
+#define KEY_NEED_DEFAULT "brightness-needs-hardware-default"
+
+enum
+{
+ PROP_0,
+ PROP_PERCENTAGE,
+ PROP_AUTO,
+ PROP_AUTO_SUPPORTED,
+ LAST_PROP
+};
+
+static GParamSpec* properties[LAST_PROP];
+
+typedef struct
+{
+ GDBusConnection * system_bus;
+ GCancellable * cancellable;
+
+ GSettings * settings;
+
+ guint powerd_name_tag;
+
+ double percentage;
+
+ /* powerd brightness params */
+ gint powerd_dim;
+ gint powerd_min;
+ gint powerd_max;
+ gint powerd_default_value;
+ gboolean powerd_ab_supported;
+ gboolean have_powerd_params;
+}
+IndicatorPowerBrightnessPrivate;
+
+typedef IndicatorPowerBrightnessPrivate priv_t;
+
+G_DEFINE_TYPE_WITH_PRIVATE(IndicatorPowerBrightness,
+ indicator_power_brightness,
+ G_TYPE_OBJECT)
+
+#define get_priv(o) ((priv_t*)indicator_power_brightness_get_instance_private(o))
+
+/***
+**** GObject virtual functions
+***/
+
+static void
+my_get_property(GObject * o,
+ guint property_id,
+ GValue * value,
+ GParamSpec * pspec)
+{
+ IndicatorPowerBrightness * self = INDICATOR_POWER_BRIGHTNESS(o);
+ priv_t * p = get_priv(self);
+
+ switch (property_id)
+ {
+ case PROP_PERCENTAGE:
+ g_value_set_double(value, indicator_power_brightness_get_percentage(self));
+ break;
+
+ case PROP_AUTO:
+ g_value_set_boolean(value, p->settings ? g_settings_get_boolean(p->settings, KEY_AUTO) : FALSE);
+ break;
+
+ case PROP_AUTO_SUPPORTED:
+ g_value_set_boolean(value, p->powerd_ab_supported);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(o, property_id, pspec);
+ }
+}
+
+static void
+my_set_property(GObject * o,
+ guint property_id,
+ const GValue * value,
+ GParamSpec * pspec)
+{
+ IndicatorPowerBrightness * self = INDICATOR_POWER_BRIGHTNESS(o);
+ priv_t * p = get_priv(self);
+
+ switch (property_id)
+ {
+ case PROP_PERCENTAGE:
+ indicator_power_brightness_set_percentage(self, g_value_get_double(value));
+ break;
+
+ case PROP_AUTO:
+ if (p->settings != NULL)
+ g_settings_set_boolean (p->settings, KEY_AUTO, g_value_get_boolean(value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(o, property_id, pspec);
+ }
+}
+
+static void
+my_dispose(GObject * o)
+{
+ IndicatorPowerBrightness * self = INDICATOR_POWER_BRIGHTNESS(o);
+ priv_t * p = get_priv(self);
+
+ if (p->cancellable != NULL)
+ {
+ g_cancellable_cancel(p->cancellable);
+ g_clear_object(&p->cancellable);
+ }
+
+ if (p->powerd_name_tag)
+ {
+ g_bus_unwatch_name(p->powerd_name_tag);
+ p->powerd_name_tag = 0;
+ }
+
+ g_clear_object(&p->settings);
+ g_clear_object(&p->system_bus);
+
+ G_OBJECT_CLASS(indicator_power_brightness_parent_class)->dispose(o);
+}
+
+/***
+**** Percentage <-> Brightness Int conversion helpers
+***/
+
+static gdouble
+brightness_to_percentage(IndicatorPowerBrightness * self, int brightness)
+{
+ const priv_t * p;
+ gdouble percentage;
+
+ p = get_priv(self);
+ if (p->have_powerd_params)
+ {
+ const int lo = p->powerd_min;
+ const int hi = p->powerd_max;
+ percentage = (brightness-lo) / (double)(hi-lo);
+ }
+ else
+ {
+ percentage = 0;
+ }
+
+ return percentage;
+}
+
+static int
+percentage_to_brightness(IndicatorPowerBrightness * self, double percentage)
+{
+ const priv_t * p;
+ int brightness;
+
+ p = get_priv(self);
+ if (p->have_powerd_params)
+ {
+ const int lo = p->powerd_min;
+ const int hi = p->powerd_max;
+ brightness = (int)(lo + (percentage*(hi-lo)));
+ }
+ else
+ {
+ brightness = 0;
+ }
+
+ return brightness;
+}
+
+/**
+ * DBus Chatter: com.canonical.powerd
+ *
+ * This is used to get default value, and upper and lower bounds,
+ * of the brightness setting
+ */
+
+static void set_brightness_global(IndicatorPowerBrightness*, int);
+
+static void
+on_powerd_brightness_params_ready(GObject * source,
+ GAsyncResult * res,
+ gpointer gself)
+{
+ GError * error;
+ GVariant * v;
+
+ error = NULL;
+ v = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &error);
+ if (v == NULL)
+ {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning("Unable to get system bus: %s", error->message);
+
+ g_error_free(error);
+ }
+ else
+ {
+ IndicatorPowerBrightness * self = INDICATOR_POWER_BRIGHTNESS(gself);
+ priv_t * p = get_priv(self);
+ const gboolean old_ab_supported = p->powerd_ab_supported;
+
+ p->have_powerd_params = TRUE;
+ g_variant_get(v, "((iiiib))", &p->powerd_dim,
+ &p->powerd_min,
+ &p->powerd_max,
+ &p->powerd_default_value,
+ &p->powerd_ab_supported);
+ g_debug("powerd brightness settings: dim=%d, min=%d, max=%d, default=%d, ab_supported=%d",
+ p->powerd_dim,
+ p->powerd_min,
+ p->powerd_max,
+ p->powerd_default_value,
+ (int)p->powerd_ab_supported);
+
+ if (old_ab_supported != p->powerd_ab_supported)
+ g_object_notify_by_pspec(G_OBJECT(self), properties[PROP_AUTO_SUPPORTED]);
+
+ if (p->settings != NULL)
+ {
+ if (g_settings_get_boolean(p->settings, KEY_NEED_DEFAULT))
+ {
+ /* user's first session, so init the schema's default
+ brightness from powerd's hardware-specific params */
+ g_debug("%s is true, so initializing brightness to powerd default '%d'", KEY_NEED_DEFAULT, p->powerd_default_value);
+ set_brightness_global(self, p->powerd_default_value);
+ g_settings_set_boolean(p->settings, KEY_NEED_DEFAULT, FALSE);
+ }
+ else
+ {
+ /* not the first time, so restore the previous session's brightness */
+ set_brightness_global(self, g_settings_get_int(p->settings, KEY_BRIGHTNESS));
+ }
+ }
+
+ /* cleanup */
+ g_variant_unref(v);
+ }
+}
+
+static void
+call_powerd_get_brightness_params(IndicatorPowerBrightness * self)
+{
+ priv_t * p = get_priv(self);
+
+ g_dbus_connection_call(p->system_bus,
+ "com.canonical.powerd",
+ "/com/canonical/powerd",
+ "com.canonical.powerd",
+ "getBrightnessParams",
+ NULL,
+ G_VARIANT_TYPE("((iiiib))"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, /* default timeout */
+ p->cancellable,
+ on_powerd_brightness_params_ready,
+ self);
+}
+
+static void
+on_powerd_appeared(GDBusConnection * connection,
+ const gchar * bus_name G_GNUC_UNUSED,
+ const gchar * name_owner G_GNUC_UNUSED,
+ gpointer gself)
+{
+ IndicatorPowerBrightness * self = INDICATOR_POWER_BRIGHTNESS(gself);
+ priv_t * p = get_priv(self);
+
+ /* keep a handle to the system bus */
+ g_clear_object(&p->system_bus);
+ p->system_bus = g_object_ref(connection);
+
+ /* update our cache of powerd's brightness params */
+ call_powerd_get_brightness_params(self);
+}
+
+static void
+on_powerd_vanished(GDBusConnection * connection G_GNUC_UNUSED,
+ const gchar * bus_name G_GNUC_UNUSED,
+ gpointer gself)
+{
+ priv_t * p = get_priv(INDICATOR_POWER_BRIGHTNESS(gself));
+
+ p->have_powerd_params = FALSE;
+}
+
+/**
+ * DBus Chatter: com.canonical.Unity.Screen
+ *
+ * Used to set the backlight brightness via setUserBrightness
+ */
+
+/* setUserBrightness doesn't return anything,
+ so this function is just to check for bus error messages */
+static void
+on_set_uscreen_user_brightness_result(GObject * system_bus,
+ GAsyncResult * res,
+ gpointer gself G_GNUC_UNUSED)
+{
+ GError * error;
+ GVariant * v;
+
+ error = NULL;
+ v = g_dbus_connection_call_finish(G_DBUS_CONNECTION(system_bus), res, &error);
+ if (error != NULL)
+ {
+ if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning("Unable to call uscreen.setBrightness: %s", error->message);
+
+ g_error_free(error);
+ }
+
+ g_clear_pointer(&v, g_variant_unref);
+}
+
+static void
+set_uscreen_user_brightness(IndicatorPowerBrightness * self,
+ int value)
+{
+ priv_t * p = get_priv(self);
+
+ g_dbus_connection_call(p->system_bus,
+ "com.canonical.Unity.Screen",
+ "/com/canonical/Unity/Screen",
+ "com.canonical.Unity.Screen",
+ "setUserBrightness",
+ g_variant_new("(i)", value),
+ NULL, /* no return args */
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, /* default timeout */
+ p->cancellable,
+ on_set_uscreen_user_brightness_result,
+ self);
+}
+
+/***
+****
+***/
+
+static void
+set_brightness_local(IndicatorPowerBrightness * self, int brightness)
+{
+ priv_t * p = get_priv(self);
+ p->percentage = brightness_to_percentage(self, brightness);
+ g_object_notify_by_pspec(G_OBJECT(self), properties[PROP_PERCENTAGE]);
+}
+
+static void
+on_brightness_changed_in_schema(GSettings * settings,
+ gchar * key,
+ gpointer gself)
+{
+ set_brightness_local(INDICATOR_POWER_BRIGHTNESS(gself),
+ g_settings_get_int(settings, key));
+}
+
+static void
+set_brightness_global(IndicatorPowerBrightness * self, int brightness)
+{
+ priv_t * p = get_priv(self);
+
+ set_uscreen_user_brightness(self, brightness);
+
+ if (p->settings != NULL)
+ g_settings_set_int(p->settings, KEY_BRIGHTNESS, brightness);
+ else
+ set_brightness_local(self, brightness);
+}
+
+static void
+on_auto_changed_in_schema(IndicatorPowerBrightness * self)
+{
+ g_object_notify_by_pspec(G_OBJECT(self), properties[PROP_AUTO]);
+}
+
+
+/***
+**** Instantiation
+***/
+
+static void
+indicator_power_brightness_init(IndicatorPowerBrightness * self)
+{
+ priv_t * p;
+ GSettingsSchema * schema;
+
+ p = get_priv(self);
+ p->cancellable = g_cancellable_new();
+
+ schema = g_settings_schema_source_lookup(g_settings_schema_source_get_default(),
+ SCHEMA_NAME,
+ TRUE);
+
+ /* "brightness" is only spec'ed for the phone profile,
+ so fail gracefully & silently if we don't have the
+ schema for it. */
+ if (schema != NULL)
+ {
+ if (g_settings_schema_has_key(schema, KEY_BRIGHTNESS))
+ {
+ p->settings = g_settings_new(SCHEMA_NAME);
+ g_signal_connect(p->settings, "changed::" KEY_BRIGHTNESS,
+ G_CALLBACK(on_brightness_changed_in_schema), self);
+ g_signal_connect_swapped(p->settings, "changed::" KEY_AUTO,
+ G_CALLBACK(on_auto_changed_in_schema), self);
+ }
+ g_settings_schema_unref(schema);
+ }
+
+ p->powerd_name_tag = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
+ "com.canonical.powerd",
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ on_powerd_appeared,
+ on_powerd_vanished,
+ self,
+ NULL);
+}
+
+static void
+indicator_power_brightness_class_init(IndicatorPowerBrightnessClass * klass)
+{
+ GObjectClass * object_class = G_OBJECT_CLASS(klass);
+
+ object_class->dispose = my_dispose;
+ object_class->get_property = my_get_property;
+ object_class->set_property = my_set_property;
+
+ properties[PROP_0] = NULL;
+
+ properties[PROP_PERCENTAGE] = g_param_spec_double(
+ "percentage",
+ "Percentage",
+ "Brightness percentage",
+ 0.0, /* minimum */
+ 1.0, /* maximum */
+ 0.8,
+ G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_AUTO] = g_param_spec_boolean(
+ "auto-brightness",
+ "Auto-Brightness",
+ "Automatically adjust brightness level",
+ FALSE,
+ G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_AUTO_SUPPORTED] = g_param_spec_boolean(
+ "auto-brightness-supported",
+ "Auto-Brightness Supported",
+ "True if the device can automatically adjust brightness",
+ FALSE,
+ G_PARAM_READABLE|G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties(object_class, LAST_PROP, properties);
+}
+
+/***
+**** Public API
+***/
+
+IndicatorPowerBrightness *
+indicator_power_brightness_new(void)
+{
+ gpointer o = g_object_new(INDICATOR_TYPE_POWER_BRIGHTNESS, NULL);
+
+ return INDICATOR_POWER_BRIGHTNESS(o);
+}
+
+void
+indicator_power_brightness_set_percentage(IndicatorPowerBrightness * self,
+ double percentage)
+{
+ g_return_if_fail(INDICATOR_IS_POWER_BRIGHTNESS(self));
+
+ set_brightness_global(self, percentage_to_brightness(self, percentage));
+}
+
+double
+indicator_power_brightness_get_percentage(IndicatorPowerBrightness * self)
+{
+ g_return_val_if_fail(INDICATOR_IS_POWER_BRIGHTNESS(self), 0.0);
+
+ return get_priv(self)->percentage;
+}
diff --git a/src/brightness.h b/src/brightness.h
new file mode 100644
index 0000000..d2fcc61
--- /dev/null
+++ b/src/brightness.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2014 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Charles Kerr <charles.kerr@canonical.com>
+ */
+
+#ifndef INDICATOR_POWER_BRIGHTNESS__H
+#define INDICATOR_POWER_BRIGHTNESS__H
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/* standard GObject macros */
+#define INDICATOR_POWER_BRIGHTNESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_POWER_BRIGHTNESS, IndicatorPowerBrightness))
+#define INDICATOR_TYPE_POWER_BRIGHTNESS (indicator_power_brightness_get_type())
+#define INDICATOR_IS_POWER_BRIGHTNESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_POWER_BRIGHTNESS))
+
+typedef struct _IndicatorPowerBrightness IndicatorPowerBrightness;
+typedef struct _IndicatorPowerBrightnessClass IndicatorPowerBrightnessClass;
+
+/* property keys */
+#define INDICATOR_POWER_BRIGHTNESS_PROP_PERCENTAGE "percentage"
+
+/**
+ * The Indicator Power Brightness.
+ */
+struct _IndicatorPowerBrightness
+{
+ /*< private >*/
+ GObject parent;
+};
+
+struct _IndicatorPowerBrightnessClass
+{
+ GObjectClass parent_class;
+};
+
+/***
+****
+***/
+
+GType indicator_power_brightness_get_type(void);
+
+IndicatorPowerBrightness * indicator_power_brightness_new(void);
+
+void indicator_power_brightness_set_percentage(IndicatorPowerBrightness * self, double percentage);
+
+double indicator_power_brightness_get_percentage(IndicatorPowerBrightness * self);
+
+G_END_DECLS
+
+#endif /* INDICATOR_POWER_BRIGHTNESS__H */
diff --git a/src/ib-brightness-control.c b/src/ib-brightness-control.c
deleted file mode 100644
index 67da10c..0000000
--- a/src/ib-brightness-control.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright 2012 Canonical Ltd.
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 3, as published
- * by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranties of
- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Renato Araujo Oliveira Filho <renato@canonical.com>
- */
-
-#include <gudev/gudev.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include "ib-brightness-control.h"
-
-struct _IbBrightnessControl
-{
- gchar *path;
-};
-
-IbBrightnessControl*
-ib_brightness_control_new (void)
-{
- IbBrightnessControl *control;
- GUdevClient *client;
- gchar *path = NULL;
- GList *devices;
-
- // detect device
- client = g_udev_client_new (NULL);
- devices = g_udev_client_query_by_subsystem (client, "backlight");
- if (devices != NULL) {
- GList *device;
- const gchar *device_type;
-
- for (device = devices; device != NULL; device = device->next) {
- device_type = g_udev_device_get_sysfs_attr (device->data, "type");
- if ((g_strcmp0 (device_type, "firmware") == 0) ||
- (g_strcmp0 (device_type, "platform") == 0) ||
- (g_strcmp0 (device_type, "raw") == 0)) {
- path = g_strdup (g_udev_device_get_sysfs_path (device->data));
- g_debug ("found: %s", path);
- break;
- }
- }
-
- g_list_free_full (devices, g_object_unref);
- }
- else {
- g_warning ("Fail to query backlight devices.");
- }
-
- control = g_new0 (IbBrightnessControl, 1);
- control->path = path;
-
- g_object_unref (client);
- return control;
-}
-
-void
-ib_brightness_control_set_value (IbBrightnessControl* self, gint value)
-{
- gint fd;
- gchar *filename;
- gchar *svalue;
- size_t length;
- gint err;
-
- if (self->path == NULL)
- return;
-
- filename = g_build_filename (self->path, "brightness", NULL);
- fd = open(filename, O_WRONLY);
- if (fd < 0) {
- g_warning ("Fail to set brightness.");
- g_free (filename);
- return;
- }
-
- svalue = g_strdup_printf ("%i", value);
- length = strlen (svalue);
-
- err = errno;
- errno = 0;
- if (write (fd, svalue, length) != (ssize_t)length) {
- g_warning ("Fail to write brightness information: %s", g_strerror(errno));
- }
- errno = err;
-
- close (fd);
- g_free (svalue);
- g_free (filename);
-}
-
-static gint
-ib_brightness_control_get_value_from_file (IbBrightnessControl *self, const gchar *file)
-{
- GError *error;
- gchar *svalue;
- gint value;
- gchar *filename;
-
- if (self->path == NULL)
- return 0;
-
- svalue = NULL;
- error = NULL;
- filename = g_build_filename (self->path, file, NULL);
- g_file_get_contents (filename, &svalue, NULL, &error);
- if (error) {
- g_warning ("Fail to get brightness value: %s", error->message);
- value = -1;
- g_error_free (error);
- } else {
- value = atoi (svalue);
- g_free (svalue);
- }
-
- g_free (filename);
-
- return value;
-
-}
-
-gint
-ib_brightness_control_get_value (IbBrightnessControl* self)
-{
- return ib_brightness_control_get_value_from_file (self, "brightness");
-}
-
-gint
-ib_brightness_control_get_max_value (IbBrightnessControl* self)
-{
- return ib_brightness_control_get_value_from_file (self, "max_brightness");
-}
-
-void
-ib_brightness_control_free (IbBrightnessControl *self)
-{
- g_free (self->path);
- g_free (self);
-}
-
diff --git a/src/ib-brightness-control.h b/src/ib-brightness-control.h
deleted file mode 100644
index 87711e4..0000000
--- a/src/ib-brightness-control.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2012 Canonical Ltd.
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 3, as published
- * by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranties of
- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Renato Araujo Oliveira Filho <renato@canonical.com>
- */
-
-#ifndef __IB_BRIGHTNESS_CONTROL_H__
-#define __IB_BRIGHTNESS_CONTROL_H__
-
-#include <gio/gio.h>
-
-typedef struct _IbBrightnessControl IbBrightnessControl;
-
-IbBrightnessControl* ib_brightness_control_new (void);
-void ib_brightness_control_set_value (IbBrightnessControl* self, gint value);
-gint ib_brightness_control_get_value (IbBrightnessControl* self);
-gint ib_brightness_control_get_max_value (IbBrightnessControl* self);
-void ib_brightness_control_free (IbBrightnessControl *self);
-
-#endif
diff --git a/src/ib-brightness-uscreen-control.c b/src/ib-brightness-uscreen-control.c
deleted file mode 100644
index ad2c155..0000000
--- a/src/ib-brightness-uscreen-control.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright 2014 Canonical Ltd.
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 3, as published
- * by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranties of
- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Yuan-Chen Cheng <yc.cheng@canonical.com>
- */
-
-#include "ib-brightness-uscreen-control.h"
-
-static gboolean getBrightnessParams(GDBusProxy* powerd_proxy, int *dim, int *min,
- int *max, int *dflt, gboolean *ab_supported);
-
-GDBusProxy*
-uscreen_get_proxy(brightness_params_t *params)
-{
- GError *error = NULL;
- gboolean ret;
-
- g_return_val_if_fail (params != NULL, NULL);
-
- /* For now we still need to obtain the brigthness params from powerd */
- GDBusProxy* powerd_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- "com.canonical.powerd",
- "/com/canonical/powerd",
- "com.canonical.powerd",
- NULL,
- &error);
-
- if (error != NULL)
- {
- g_debug ("could not connect to powerd: %s", error->message);
- g_error_free (error);
- return NULL;
- }
-
- ret = getBrightnessParams(powerd_proxy, &(params->dim), &(params->min),
- &(params->max), &(params->dflt), &(params->ab_supported));
-
- if (! ret)
- {
- g_debug ("can't get brightness parameters from powerd");
- g_object_unref (powerd_proxy);
- return NULL;
- }
-
- g_clear_object (&powerd_proxy);
-
- GDBusProxy* uscreen_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- "com.canonical.Unity.Screen",
- "/com/canonical/Unity/Screen",
- "com.canonical.Unity.Screen",
- NULL,
- &error);
-
- if (error != NULL)
- {
- g_debug ("could not connect to unity screen: %s", error->message);
- g_error_free (error);
- return NULL;
- }
-
- return uscreen_proxy;
-}
-
-
-static gboolean
-getBrightnessParams(GDBusProxy* powerd_proxy, int *dim, int *min, int *max, int *dflt, gboolean *ab_supported)
-{
- GVariant *ret = NULL;
- GError *error = NULL;
-
- ret = g_dbus_proxy_call_sync(powerd_proxy,
- "getBrightnessParams",
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- 400, NULL, &error); // timeout: 400 ms
- if (!ret)
- {
- if (error != NULL)
- {
- if (!g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN))
- {
- g_warning("getBrightnessParams from powerd failed: %s", error->message);
- }
- g_error_free(error);
- }
- return FALSE;
- }
-
- g_variant_get(ret, "((iiiib))", dim, min, max, dflt, ab_supported);
- g_variant_unref(ret);
- return TRUE;
-}
-
-static gboolean setUserBrightness(GDBusProxy* uscreen_proxy, GCancellable *gcancel, int brightness)
-{
- GVariant *ret = NULL;
- GError *error = NULL;
-
- ret = g_dbus_proxy_call_sync(uscreen_proxy,
- "setUserBrightness",
- g_variant_new("(i)", brightness),
- G_DBUS_CALL_FLAGS_NONE,
- -1, gcancel, &error);
- if (!ret) {
- g_warning("setUserBrightness via unity.screen failed: %s", error->message);
- g_error_free(error);
- return FALSE;
- } else {
- g_variant_unref(ret);
- return TRUE;
- }
-}
-
-struct _IbBrightnessUScreenControl
-{
- GDBusProxy *uscreen_proxy;
- GCancellable *gcancel;
-
- int dim;
- int min;
- int max;
- int dflt; // defalut value
- gboolean ab_supported;
-
- int current;
-};
-
-IbBrightnessUscreenControl*
-ib_brightness_uscreen_control_new (GDBusProxy* uscreen_proxy, brightness_params_t params)
-{
- IbBrightnessUscreenControl *control;
-
- control = g_new0 (IbBrightnessUscreenControl, 1);
- control->uscreen_proxy = uscreen_proxy;
- control->gcancel = g_cancellable_new();
-
- control->dim = params.dim;
- control->min = params.min;
- control->max = params.max;
- control->dflt = params.dflt;
- control->ab_supported = params.ab_supported;
-
- // XXX: set the brightness value is the only way to sync the brightness value with
- // unity.screen, and we should set the user prefered / last set brightness value upon startup.
- // Before we have code to store last set brightness value or other mechanism, we set
- // it to default brightness that powerd proposed.
- ib_brightness_uscreen_control_set_value(control, control->dflt);
-
- return control;
-}
-
-void
-ib_brightness_uscreen_control_set_value (IbBrightnessUscreenControl* self, gint value)
-{
- gboolean ret;
-
- value = CLAMP(value, self->min, self->max);
- ret = setUserBrightness(self->uscreen_proxy, self->gcancel, value);
- if (ret)
- {
- self->current = value;
- }
-}
-
-gint
-ib_brightness_uscreen_control_get_value (IbBrightnessUscreenControl* self)
-{
- return self->current;
-}
-
-gint
-ib_brightness_uscreen_control_get_max_value (IbBrightnessUscreenControl* self)
-{
- return self->max;
-}
-
-void
-ib_brightness_uscreen_control_free (IbBrightnessUscreenControl *self)
-{
- g_cancellable_cancel (self->gcancel);
- g_object_unref (self->gcancel);
- g_object_unref (self->uscreen_proxy);
- g_free (self);
-}
-
diff --git a/src/ib-brightness-uscreen-control.h b/src/ib-brightness-uscreen-control.h
deleted file mode 100644
index 3d026a9..0000000
--- a/src/ib-brightness-uscreen-control.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2014 Canonical Ltd.
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 3, as published
- * by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranties of
- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Y.C Cheng <yc.cheng@canonical.com>
- */
-
-#ifndef __IB_BRIGHTNESS_USCREEN_CONTROL_H__
-#define __IB_BRIGHTNESS_USCREEN_CONTROL_H__
-
-#include <gio/gio.h>
-
-typedef struct {
- int dim;
- int min;
- int max;
- int dflt;
- gboolean ab_supported;
-} brightness_params_t;
-
-GDBusProxy* uscreen_get_proxy(brightness_params_t *);
-
-typedef struct _IbBrightnessUScreenControl IbBrightnessUscreenControl;
-
-IbBrightnessUscreenControl* ib_brightness_uscreen_control_new (GDBusProxy* uscreen_proxy, brightness_params_t params);
-void ib_brightness_uscreen_control_set_value (IbBrightnessUscreenControl* self, gint value);
-gint ib_brightness_uscreen_control_get_value (IbBrightnessUscreenControl* self);
-gint ib_brightness_uscreen_control_get_max_value (IbBrightnessUscreenControl* self);
-void ib_brightness_uscreen_control_free (IbBrightnessUscreenControl *self);
-
-#endif
diff --git a/src/service.c b/src/service.c
index 0cd448b..665151c 100644
--- a/src/service.c
+++ b/src/service.c
@@ -22,12 +22,11 @@
#include <gio/gio.h>
#include <url-dispatcher.h>
+#include "brightness.h"
#include "dbus-shared.h"
#include "device.h"
#include "device-provider.h"
#include "notifier.h"
-#include "ib-brightness-control.h"
-#include "ib-brightness-uscreen-control.h"
#include "service.h"
#define BUS_NAME "com.canonical.indicator.power"
@@ -104,8 +103,7 @@ struct _IndicatorPowerServicePrivate
GSettings * settings;
- IbBrightnessControl * brightness_control;
- IbBrightnessUscreenControl * brightness_uscreen_control;
+ IndicatorPowerBrightness * brightness;
guint own_id;
guint actions_export_id;
@@ -459,53 +457,26 @@ create_phone_devices_section (IndicatorPowerService * self G_GNUC_UNUSED)
****
***/
-static void
-get_brightness_range (IndicatorPowerService * self, gint * low, gint * high)
+static GMenuItem *
+create_brightness_menu_item(void)
{
- priv_t * p = self->priv;
- int max = 0;
- if (p->brightness_control)
- {
- max = ib_brightness_control_get_max_value (self->priv->brightness_control);
- }
- else if (p->brightness_uscreen_control)
- {
- max = ib_brightness_uscreen_control_get_max_value (self->priv->brightness_uscreen_control);
- }
- *low = (gint)(max * 0.05); /* 5% minimum -- don't let the screen go completely dark */
- *high = max;
-}
+ GMenuItem * item;
-static gdouble
-brightness_to_percentage (IndicatorPowerService * self, int brightness)
-{
- int lo, hi;
- get_brightness_range (self, &lo, &hi);
- return (brightness-lo) / (double)(hi-lo);
-}
+ item = g_menu_item_new(NULL, "indicator.brightness");
+ g_menu_item_set_attribute(item, "x-canonical-type", "s", "com.canonical.unity.slider");
+ g_menu_item_set_attribute(item, "min-value", "d", 0.0);
+ g_menu_item_set_attribute(item, "max-value", "d", 1.0);
+ g_menu_item_set_attribute(item, "min-icon", "s", "torch-off" );
+ g_menu_item_set_attribute(item, "max-icon", "s", "torch-on" );
-static int
-percentage_to_brightness (IndicatorPowerService * self, double percentage)
-{
- int lo, hi;
- get_brightness_range (self, &lo, &hi);
- return (int)(lo + (percentage*(hi-lo)));
+ return item;
}
static GVariant *
action_state_for_brightness (IndicatorPowerService * self)
{
- priv_t * p = self->priv;
- gint brightness = 0;
- if (p->brightness_control)
- {
- brightness = ib_brightness_control_get_value (p->brightness_control);
- }
- else if (p->brightness_uscreen_control)
- {
- brightness = ib_brightness_uscreen_control_get_value (p->brightness_uscreen_control);
- }
- return g_variant_new_double (brightness_to_percentage (self, brightness));
+ IndicatorPowerBrightness * b = self->priv->brightness;
+ return g_variant_new_double(indicator_power_brightness_get_percentage(b));
}
static void
@@ -521,19 +492,9 @@ on_brightness_change_requested (GSimpleAction * action G_GNUC_UNUSED,
gpointer gself)
{
IndicatorPowerService * self = INDICATOR_POWER_SERVICE (gself);
- const gdouble percentage = g_variant_get_double (parameter);
- const int brightness = percentage_to_brightness (self, percentage);
- if (self->priv->brightness_control)
- {
- ib_brightness_control_set_value (self->priv->brightness_control, brightness);
- }
- else if (self->priv->brightness_uscreen_control)
- {
- ib_brightness_uscreen_control_set_value (self->priv->brightness_uscreen_control, brightness);
- }
-
- update_brightness_action_state (self);
+ indicator_power_brightness_set_percentage(self->priv->brightness,
+ g_variant_get_double (parameter));
}
static GMenuModel *
@@ -557,15 +518,34 @@ create_desktop_settings_section (IndicatorPowerService * self G_GNUC_UNUSED)
}
static GMenuModel *
-create_phone_settings_section (IndicatorPowerService * self)
+create_phone_settings_section(IndicatorPowerService * self)
{
GMenu * section;
+ GMenuItem * item;
+ gboolean ab_supported;
+
+ section = g_menu_new();
+
+ item = create_brightness_menu_item();
+ g_menu_append_item(section, item);
+ update_brightness_action_state(self);
+ g_object_unref(item);
+
+ g_object_get(self->priv->brightness,
+ "auto-brightness-supported", &ab_supported,
+ NULL);
+
+ if (ab_supported)
+ {
+ item = g_menu_item_new(_("Adjust brightness automatically"), "indicator.auto-brightness");
+ g_menu_item_set_attribute(item, "x-canonical-type", "s", "com.canonical.indicator.switch");
+ g_menu_append_item(section, item);
+ g_object_unref(item);
+ }
- section = g_menu_new ();
- update_brightness_action_state (self);
- g_menu_append (section, _("Battery settingsā€¦"), "indicator.activate-phone-settings");
+ g_menu_append(section, _("Battery settingsā€¦"), "indicator.activate-phone-settings");
- return G_MENU_MODEL (section);
+ return G_MENU_MODEL(section);
}
/***
@@ -612,7 +592,7 @@ rebuild_now (IndicatorPowerService * self, guint sections)
if (sections & SECTION_SETTINGS)
{
rebuild_section (desktop->submenu, 1, create_desktop_settings_section (self));
- rebuild_section (phone->submenu, 1, create_desktop_settings_section (self));
+ rebuild_section (phone->submenu, 1, create_phone_settings_section (self));
}
}
@@ -752,6 +732,28 @@ on_phone_settings_activated (GSimpleAction * a G_GNUC_UNUSED,
****
***/
+static gboolean
+convert_auto_prop_to_state(GBinding * binding G_GNUC_UNUSED,
+ const GValue * from_value,
+ GValue * to_value,
+ gpointer user_data G_GNUC_UNUSED)
+{
+ const gboolean b = g_value_get_boolean(from_value);
+ g_value_set_variant(to_value, g_variant_new_boolean(b));
+ return TRUE;
+}
+
+static gboolean
+convert_auto_state_to_prop(GBinding * binding G_GNUC_UNUSED,
+ const GValue * from_value,
+ GValue * to_value,
+ gpointer user_data G_GNUC_UNUSED)
+{
+ GVariant * v = g_value_get_variant(from_value);
+ g_value_set_boolean(to_value, g_variant_get_boolean(v));
+ return TRUE;
+}
+
static void
init_gactions (IndicatorPowerService * self)
{
@@ -784,6 +786,16 @@ init_gactions (IndicatorPowerService * self)
g_action_map_add_action (G_ACTION_MAP(p->actions), G_ACTION(a));
p->battery_level_action = a;
+ /* add the auto-brightness action */
+ a = g_simple_action_new_stateful("auto-brightness", NULL, g_variant_new_boolean(FALSE));
+ g_object_bind_property_full(p->brightness, "auto-brightness",
+ a, "state",
+ G_BINDING_SYNC_CREATE|G_BINDING_BIDIRECTIONAL,
+ convert_auto_prop_to_state,
+ convert_auto_state_to_prop,
+ NULL, NULL);
+ g_action_map_add_action(G_ACTION_MAP(p->actions), G_ACTION(a));
+
/* add the brightness action */
a = g_simple_action_new_stateful ("brightness", NULL, action_state_for_brightness (self));
g_action_map_add_action (G_ACTION_MAP(p->actions), G_ACTION(a));
@@ -848,9 +860,6 @@ on_bus_acquired (GDBusConnection * connection,
g_string_printf (path, "%s/%s", BUS_PATH, menu_names[i]);
- if (menu->menu == NULL)
- create_menu (self, i);
-
if ((id = g_dbus_connection_export_menu_model (connection,
path->str,
G_MENU_MODEL (menu->menu),
@@ -942,6 +951,12 @@ on_devices_changed (IndicatorPowerService * self)
rebuild_now (self, SECTION_HEADER | SECTION_DEVICES);
}
+static void
+on_auto_brightness_supported_changed(IndicatorPowerService * self)
+{
+ rebuild_now(self, SECTION_SETTINGS);
+}
+
/***
**** GObject virtual functions
@@ -1015,16 +1030,13 @@ my_dispose (GObject * o)
g_clear_object (&p->notifier);
g_clear_object (&p->brightness_action);
+ g_clear_object (&p->brightness);
g_clear_object (&p->battery_level_action);
g_clear_object (&p->header_action);
g_clear_object (&p->actions);
g_clear_object (&p->conn);
- // g_clear_pointer has NULL check inside.
- g_clear_pointer (&p->brightness_control, ib_brightness_control_free);
- g_clear_pointer (&p->brightness_uscreen_control, ib_brightness_uscreen_control_free);
-
indicator_power_service_set_device_provider (self, NULL);
G_OBJECT_CLASS (indicator_power_service_parent_class)->dispose (o);
@@ -1037,11 +1049,12 @@ my_dispose (GObject * o)
static void
indicator_power_service_init (IndicatorPowerService * self)
{
- GDBusProxy *uscreen_proxy;
- brightness_params_t brightness_params;
- priv_t * p = G_TYPE_INSTANCE_GET_PRIVATE (self,
- INDICATOR_TYPE_POWER_SERVICE,
- IndicatorPowerServicePrivate);
+ priv_t * p;
+ int i;
+
+ p = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ INDICATOR_TYPE_POWER_SERVICE,
+ IndicatorPowerServicePrivate);
self->priv = p;
p->cancellable = g_cancellable_new ();
@@ -1050,28 +1063,28 @@ indicator_power_service_init (IndicatorPowerService * self)
p->notifier = indicator_power_notifier_new ();
- uscreen_proxy = uscreen_get_proxy(&brightness_params);
- if (uscreen_proxy != NULL)
- {
- p->brightness_uscreen_control = ib_brightness_uscreen_control_new(uscreen_proxy, brightness_params);
- }
- else
- {
- p->brightness_control = ib_brightness_control_new ();
- }
+ p->brightness = indicator_power_brightness_new();
+ g_signal_connect_swapped(p->brightness, "notify::percentage",
+ G_CALLBACK(update_brightness_action_state), self);
init_gactions (self);
g_signal_connect_swapped (p->settings, "changed", G_CALLBACK(rebuild_header_now), self);
- p->own_id = g_bus_own_name (G_BUS_TYPE_SESSION,
- BUS_NAME,
- G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,
- on_bus_acquired,
- NULL,
- on_name_lost,
- self,
- NULL);
+ for (i=0; i<N_PROFILES; ++i)
+ create_menu(self, i);
+
+ g_signal_connect_swapped(p->brightness, "notify::auto-brightness-supported",
+ G_CALLBACK(on_auto_brightness_supported_changed), self);
+
+ p->own_id = g_bus_own_name(G_BUS_TYPE_SESSION,
+ BUS_NAME,
+ G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,
+ on_bus_acquired,
+ NULL,
+ on_name_lost,
+ self,
+ NULL);
}
static void