From 18fd0fa741f818ed8a6d09b8a2a4623e85d6bbdf Mon Sep 17 00:00:00 2001 From: "Y.C cheng" Date: Mon, 3 Mar 2014 17:18:05 +0800 Subject: set brightness via powerd if it exist (using dbus) --- src/service.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 5 deletions(-) (limited to 'src/service.c') diff --git a/src/service.c b/src/service.c index 982a24e..0f976d1 100644 --- a/src/service.c +++ b/src/service.c @@ -27,6 +27,7 @@ #include "device.h" #include "device-provider.h" #include "ib-brightness-control.h" +#include "ib-brightness-powerd-control.h" #include "service.h" #define BUS_NAME "com.canonical.indicator.power" @@ -104,6 +105,7 @@ struct _IndicatorPowerServicePrivate GSettings * settings; IbBrightnessControl * brightness_control; + IbBrightnessPowerdControl * brightness_powerd_control; guint own_id; guint actions_export_id; @@ -440,7 +442,12 @@ create_phone_devices_section (IndicatorPowerService * self G_GNUC_UNUSED) static void get_brightness_range (IndicatorPowerService * self, gint * low, gint * high) { - const int max = ib_brightness_control_get_max_value (self->priv->brightness_control); + int max = 0; + if (self->priv->brightness_control) { + max = ib_brightness_control_get_max_value (self->priv->brightness_control); + } else { + max = ib_brightness_powerd_control_get_max_value (self->priv->brightness_powerd_control); + } *low = max * 0.05; /* 5% minimum -- don't let the screen go completely dark */ *high = max; } @@ -483,7 +490,15 @@ static GVariant * action_state_for_brightness (IndicatorPowerService * self) { priv_t * p = self->priv; - const gint brightness = ib_brightness_control_get_value (p->brightness_control); + gint brightness = 0; + if (p->brightness_control) + { + brightness = ib_brightness_control_get_value (p->brightness_control); + } + else if (p->brightness_powerd_control) + { + brightness = ib_brightness_powerd_control_get_value (p->brightness_powerd_control); + } return g_variant_new_double (brightness_to_percentage (self, brightness)); } @@ -502,7 +517,16 @@ on_brightness_change_requested (GSimpleAction * action G_GNUC_UNUSED, IndicatorPowerService * self = INDICATOR_POWER_SERVICE (gself); const gdouble percentage = g_variant_get_double (parameter); const int brightness = percentage_to_brightness (self, percentage); - ib_brightness_control_set_value (self->priv->brightness_control, brightness); + + if (self->priv->brightness_control) + { + ib_brightness_control_set_value (self->priv->brightness_control, brightness); + } + else if (self->priv->brightness_powerd_control) + { + ib_brightness_powerd_control_set_value (self->priv->brightness_powerd_control, brightness); + } + update_brightness_action_state (self); } @@ -999,7 +1023,14 @@ my_dispose (GObject * o) g_clear_object (&p->conn); - g_clear_pointer (&p->brightness_control, ib_brightness_control_free); + if (p->brightness_control) + { + g_clear_pointer (&p->brightness_control, ib_brightness_control_free); + } + else if (p->brightness_powerd_control) + { + g_clear_pointer (&p->brightness_powerd_control, ib_brightness_powerd_control_free); + } indicator_power_service_set_device_provider (self, NULL); @@ -1013,6 +1044,7 @@ my_dispose (GObject * o) static void indicator_power_service_init (IndicatorPowerService * self) { + GDBusProxy *powerd_proxy = NULL; priv_t * p = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_TYPE_POWER_SERVICE, IndicatorPowerServicePrivate); @@ -1022,7 +1054,18 @@ indicator_power_service_init (IndicatorPowerService * self) p->settings = g_settings_new ("com.canonical.indicator.power"); - p->brightness_control = ib_brightness_control_new (); + p->brightness_control = NULL; + p->brightness_powerd_control = NULL; + + powerd_proxy = powerd_get_proxy(); + if (powerd_proxy != NULL) + { + p->brightness_powerd_control = ib_brightness_powerd_control_new(powerd_proxy); + } + else + { + p->brightness_control = ib_brightness_control_new (); + } init_gactions (self); -- cgit v1.2.3 From 0f47066b171ba99fa7ac68bb3ccf0e92b18e78ab Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 4 Mar 2014 22:57:52 -0600 Subject: update the header / menuitem text / accessible text to reflect the changes in https://wiki.ubuntu.com/Power?action=diff&rev2=44&rev1=43#Title --- src/device.c | 474 +++++++++++++++++++++++++++++++++------------------ src/device.h | 45 +++-- src/service.c | 83 ++++----- tests/Makefile.am | 2 +- tests/test-device.cc | 152 ++++++++++++----- 5 files changed, 499 insertions(+), 257 deletions(-) (limited to 'src/service.c') diff --git a/src/device.c b/src/device.c index 7f1b14f..c941454 100644 --- a/src/device.c +++ b/src/device.c @@ -37,6 +37,11 @@ struct _IndicatorPowerDevicePrivate gchar * object_path; gdouble percentage; time_t time; + + /* Timestamp of when when we first noticed that upower couldn't estimate + the time-remaining field for this device, or 0 if not applicable. + This is used when generating the time-remaining string. */ + GTimer * inestimable; }; #define INDICATOR_POWER_DEVICE_GET_PRIVATE(o) (INDICATOR_POWER_DEVICE(o)->priv) @@ -136,6 +141,11 @@ indicator_power_device_init (IndicatorPowerDevice *self) static void indicator_power_device_dispose (GObject *object) { + IndicatorPowerDevice * self = INDICATOR_POWER_DEVICE(object); + IndicatorPowerDevicePrivate * p = self->priv; + + g_clear_pointer (&p->inestimable, g_timer_destroy); + G_OBJECT_CLASS (indicator_power_device_parent_class)->dispose (object); } @@ -192,35 +202,50 @@ static void set_property (GObject * o, guint prop_id, const GValue * value, GParamSpec * pspec) { IndicatorPowerDevice * self = INDICATOR_POWER_DEVICE(o); - IndicatorPowerDevicePrivate * priv = self->priv; + IndicatorPowerDevicePrivate * p = self->priv; switch (prop_id) { case PROP_KIND: - priv->kind = g_value_get_int (value); + p->kind = g_value_get_int (value); break; case PROP_STATE: - priv->state = g_value_get_int (value); + p->state = g_value_get_int (value); break; case PROP_OBJECT_PATH: - g_free (priv->object_path); - priv->object_path = g_value_dup_string (value); + g_free (p->object_path); + p->object_path = g_value_dup_string (value); break; case PROP_PERCENTAGE: - priv->percentage = g_value_get_double (value); + p->percentage = g_value_get_double (value); break; case PROP_TIME: - priv->time = g_value_get_uint64(value); + p->time = g_value_get_uint64(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(o, prop_id, pspec); break; } + + /* update inestimable_at */ + + const gboolean is_inestimable = (p->time == 0) + && (p->state != UP_DEVICE_STATE_FULLY_CHARGED) + && (p->percentage > 0); + + if (!is_inestimable) + { + g_clear_pointer (&p->inestimable, g_timer_destroy); + } + else if (p->inestimable == NULL) + { + p->inestimable = g_timer_new (); + } } /*** @@ -442,57 +467,6 @@ indicator_power_device_get_gicon (const IndicatorPowerDevice * device) **** ***/ -/* Format time remaining for reading ("H:MM") and speech ("H hours, MM minutes") */ -static void -get_timestring (guint64 time_secs, - gchar **readable_timestring, - gchar **accessible_timestring) -{ - gint hours; - gint minutes; - - /* Add 0.5 to do rounding */ - minutes = (int) ( ( time_secs / 60.0 ) + 0.5 ); - - if (minutes == 0) - { - *readable_timestring = g_strdup (_("Unknown time")); - *accessible_timestring = g_strdup (_("Unknown time")); - - return; - } - - if (minutes < 60) - { - *readable_timestring = g_strdup_printf ("0:%.2i", minutes); - *accessible_timestring = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%i minute", - "%i minutes", - minutes), minutes); - return; - } - - hours = minutes / 60; - minutes = minutes % 60; - - *readable_timestring = g_strdup_printf ("%i:%.2i", hours, minutes); - - if (minutes == 0) - { - *accessible_timestring = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, - "%i hour", - "%i hours", - hours), hours); - } - else - { - /* TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes" - * Swap order with "%2$s %2$i %1$s %1$i if needed */ - *accessible_timestring = g_strdup_printf (_("%i %s %i %s"), - hours, g_dngettext (GETTEXT_PACKAGE, "hour", "hours", hours), - minutes, g_dngettext (GETTEXT_PACKAGE, "minute", "minutes", minutes)); - } -} - static const gchar * device_kind_to_localised_string (UpDeviceKind kind) { @@ -555,149 +529,325 @@ device_kind_to_localised_string (UpDeviceKind kind) return text; } -static char * -join_strings (const char * name, const char * time, const char * percent) +/** + * The '''brief time-remaining string''' for a component should be: + * * the time remaining for it to empty or fully charge, + * if estimable, in H:MM format; otherwise + * * “estimating…” if the time remaining has been inestimable for + * less than 30 seconds; otherwise + * * “unknown” if the time remaining has been inestimable for + * between 30 seconds and one minute; otherwise + * * the empty string. + */ +static void +get_brief_time_remaining (const IndicatorPowerDevice * device, + char * str, + gulong size) { - char * str; - const gboolean have_name = name && *name; - const gboolean have_time = time && *time; - const gboolean have_percent = percent && *percent; - - if (have_name && have_time && have_percent) - str = g_strdup_printf (_("%s (%s, %s)"), name, time, percent); - else if (have_name && have_time) - str = g_strdup_printf (_("%s (%s)"), name, time); - else if (have_name && have_percent) - str = g_strdup_printf (_("%s (%s)"), name, percent); - else if (have_name) - str = g_strdup (name); - else if (have_time && have_percent) - str = g_strdup_printf (_("(%s, %s)"), time, percent); - else if (have_time) - str = g_strdup_printf (_("(%s)"), time); - else if (have_percent) - str = g_strdup_printf (_("(%s)"), percent); - else - str = g_strdup (""); + const IndicatorPowerDevicePrivate * p = device->priv; + + if (p->time > 0) + { + int minutes = p->time / 60; + int hours = minutes / 60; + minutes %= 60; + + g_snprintf (str, size, "%0d:%02d", hours, minutes); + } + else if (p->inestimable != NULL) + { + const double elapsed = g_timer_elapsed (p->inestimable, NULL); - return str; + if (elapsed < 30) + { + g_snprintf (str, size, _("estimating…")); + } + else if (elapsed < 60) + { + g_snprintf (str, size, _("unknown")); + } + else + { + *str = '\0'; + } + } + else + { + *str = '\0'; + } } +/** + * The '''expanded time-remaining string''' for a component should + * be the same as the brief time-remaining string, except that if + * the time is estimable: + * * if the component is charging, it should be “H:MM to charge” + * * if the component is discharging, it should be “H:MM left”. + */ static void -indicator_power_device_get_text (const IndicatorPowerDevice * device, - gboolean show_time_in_header, - gboolean show_percentage_in_header, - gchar ** header, - gchar ** label, - gchar ** a11y) +get_expanded_time_remaining (const IndicatorPowerDevice * device, + char * str, + gulong size) { - if (!INDICATOR_IS_POWER_DEVICE(device)) - { - if (a11y != NULL) *a11y = NULL; - if (label != NULL) *label = NULL; - if (header != NULL) *header = NULL; - g_warning ("%s: %p is not an IndicatorPowerDevice", G_STRFUNC, device); - return; - } + const IndicatorPowerDevicePrivate * p; - const time_t time = indicator_power_device_get_time (device); - const UpDeviceState state = indicator_power_device_get_state (device); - const UpDeviceKind kind = indicator_power_device_get_kind (device); - const gchar * device_name = device_kind_to_localised_string (kind); - const gdouble percentage = indicator_power_device_get_percentage (device); - char pctstr[32] = { '\0' }; - g_snprintf (pctstr, sizeof(pctstr), "%.0lf%%", percentage); + g_return_if_fail (str != NULL); + g_return_if_fail (size > 0); + *str = '\0'; + g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); - GString * terse_time = g_string_new (NULL); - GString * verbose_time = g_string_new (NULL); - GString * accessible_time = g_string_new (NULL); + p = device->priv; - if (time > 0) + if (p->time && ((p->state == UP_DEVICE_STATE_CHARGING) || (p->state == UP_DEVICE_STATE_DISCHARGING))) { - char * readable_timestr = NULL; - char * accessible_timestr = NULL; - get_timestring (time, &readable_timestr, &accessible_timestr); + int minutes = p->time / 60; + int hours = minutes / 60; + minutes %= 60; - if (state == UP_DEVICE_STATE_CHARGING) + if (p->state == UP_DEVICE_STATE_CHARGING) { - g_string_assign (terse_time, readable_timestr); - g_string_printf (verbose_time, _("%s to charge"), readable_timestr); - g_string_printf (accessible_time, _("%s to charge"), accessible_timestr); + g_snprintf (str, size, _("%0d:%02d to charge"), hours, minutes); } - else if ((state == UP_DEVICE_STATE_DISCHARGING) && (time <= (60*60*24))) + else // discharging { - g_string_assign (terse_time, readable_timestr); - g_string_printf (verbose_time, _("%s left"), readable_timestr); - g_string_printf (accessible_time, _("%s left"), accessible_timestr); + g_snprintf (str, size, _("%0d:%02d left"), hours, minutes); } - else + } + else + { + get_brief_time_remaining (device, str, size); + } +} + +/** + * The '''accessible time-remaining string''' for a component + * should be the same as the expanded time-remaining string, + * except the H:MM time should be rendered as “''H'' hours ''M'' minutes”, + * or just as “''M'' * minutes” if the time is less than one hour. + */ +static void +get_accessible_time_remaining (const IndicatorPowerDevice * device, + char * str, + gulong size) +{ + const IndicatorPowerDevicePrivate * p; + + g_return_if_fail (str != NULL); + g_return_if_fail (size > 0); + *str = '\0'; + g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); + + p = device->priv; + + if (p->time && ((p->state == UP_DEVICE_STATE_CHARGING) || (p->state == UP_DEVICE_STATE_DISCHARGING))) + { + int minutes = p->time / 60; + int hours = minutes / 60; + minutes %= 60; + + if (p->state == UP_DEVICE_STATE_CHARGING) { - /* if there's more than 24 hours remaining, we don't show it */ + if (hours) + g_snprintf (str, size, _("%d %s %d %s to charge"), + hours, g_dngettext (NULL, "hour", "hours", hours), + minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + else + g_snprintf (str, size, _("%d %s to charge"), + minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + } + else // discharging + { + if (hours) + g_snprintf (str, size, _("%d %s %d %s left"), + hours, g_dngettext (NULL, "hour", "hours", hours), + minutes, g_dngettext (NULL, "minute", "minutes", minutes)); + else + g_snprintf (str, size, _("%d %s left"), + minutes, g_dngettext (NULL, "minute", "minutes", minutes)); } - - g_free (readable_timestr); - g_free (accessible_timestr); } - else if (state == UP_DEVICE_STATE_FULLY_CHARGED) + else { - g_string_assign (verbose_time, _("charged")); - g_string_assign (accessible_time, _("charged")); + get_brief_time_remaining (device, str, size); } - else if (percentage > 0) +} + +/** + * The time is relevant for a device if either (a) the component is charging, + * or (b) the component is discharging and the estimated time is less than + * 24 hours. (A time greater than 24 hours is probably a mistaken calculation.) + */ +static gboolean +time_is_relevant (const IndicatorPowerDevice * device) +{ + const IndicatorPowerDevicePrivate * p = device->priv; + + if (p->state == UP_DEVICE_STATE_CHARGING) + return TRUE; + + if ((p->state == UP_DEVICE_STATE_DISCHARGING) && (p->time<(24*60*60))) + return TRUE; + + return FALSE; +} + +/** + * The menu item for each chargeable component should consist of ... + * Text representing the name of the component (“Battery”, “Mouse”, + * “UPS”, “Alejandra’s iPod”, etc) and the charge status in brackets: + * + * * “X (charged)” if it is fully charged and not discharging; + * * “X (expanded time-remaining string)” if it is charging, + * or discharging with less than 24 hours left; + * * “X” if it is discharging with 24 hours or more left. + * + * The accessible label for the menu item should be the same as the + * visible label, except with the accessible time-remaining string + * instead of the expanded time-remaining string. + */ +static void +get_menuitem_text (const IndicatorPowerDevice * device, + gchar * str, + gulong size, + gboolean accessible) +{ + const IndicatorPowerDevicePrivate * p = device->priv; + const char * kind_str = device_kind_to_localised_string (p->kind); + + if (p->state == UP_DEVICE_STATE_FULLY_CHARGED) { - g_string_assign (terse_time, _("estimating…")); - g_string_assign (verbose_time, _("estimating…")); - g_string_assign (accessible_time, _("estimating…")); + g_snprintf (str, size, _("%s (charged)"), kind_str); } else { - *pctstr = '\0'; + char buf[64]; - if (kind != UP_DEVICE_KIND_LINE_POWER) + if (time_is_relevant (device)) { - g_string_assign (verbose_time, _("not present")); - g_string_assign (accessible_time, _("not present")); + if (accessible) + get_accessible_time_remaining (device, buf, sizeof(buf)); + else + get_expanded_time_remaining (device, buf, sizeof(buf)); } + else + { + *buf = '\0'; + } + + if (*buf) + g_snprintf (str, size, _("%s (%s)"), kind_str, buf); + else + g_strlcpy (str, kind_str, size); } +} - if (header != NULL) - *header = join_strings (NULL, - show_time_in_header ? terse_time->str : "", - show_percentage_in_header ? pctstr : ""); +void +indicator_power_device_get_readable_text (const IndicatorPowerDevice * device, + gchar * str, + gulong size) +{ + g_return_if_fail (str != NULL); + g_return_if_fail (size > 0); + *str = '\0'; + g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); - if (label != NULL) - *label = join_strings (device_name, - verbose_time->str, - NULL); + get_menuitem_text (device, str, size, FALSE); +} - if (a11y != NULL) - *a11y = join_strings (device_name, - accessible_time->str, - pctstr); +void +indicator_power_device_get_accessible_text (const IndicatorPowerDevice * device, + gchar * str, + gulong size) +{ + g_return_if_fail (str != NULL); + g_return_if_fail (size > 0); + *str = '\0'; + g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); - g_string_free (terse_time, TRUE); - g_string_free (verbose_time, TRUE); - g_string_free (accessible_time, TRUE); + get_menuitem_text (device, str, size, TRUE); } -gchar * -indicator_power_device_get_label (const IndicatorPowerDevice * device) +#if 0 +- If the time is relevant, the brackets should contain the time-remaining string for that component. ++ If the time is relevant, the brackets should contain the brief time-remaining string for that component. + +- Regardless, the accessible name for the whole menu title should be the same as the accessible name for that thing’s component inside the menu itself. ++ The accessible name for the whole menu title should be the same as the except using the accessible time-remaining string instead of the brief time-remaining string. +#endif + +/** + * If the time is relevant and/or “Show Percentage in Menu Bar” is checked, + * the icon should be followed by brackets. + * + * If the time is relevant, the brackets should contain the time-remaining + * string for that component. + * + * If “Show Percentage in Menu Bar” is checked (as it should not be by default), + * the brackets should contain the percentage charge for that device. + * + * If both conditions are true, the time and percentage should be separated by a space. + */ +void +indicator_power_device_get_readable_title (const IndicatorPowerDevice * device, + gchar * str, + gulong size, + gboolean want_time, + gboolean want_percent) { - gchar * label = NULL; - indicator_power_device_get_text (device, FALSE, FALSE, - NULL, &label, NULL); - return label; + char tr[64]; + const IndicatorPowerDevicePrivate * p; + + g_return_if_fail (str != NULL); + g_return_if_fail (size > 0); + *str = '\0'; + g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); + + p = device->priv; + + if (want_time && !time_is_relevant (device)) + want_time = FALSE; + + if (p->percentage < 0.01) + want_percent = FALSE; + + if (want_time) + { + get_brief_time_remaining (device, tr, sizeof(tr)); + + if (!*tr) + want_time = FALSE; + } + + if (want_time && want_percent) + { + g_snprintf (str, size, _("(%s, %.0lf%%)"), tr, p->percentage); + } + else if (want_time) + { + g_snprintf (str, size, _("(%s)"), tr); + } + else if (want_percent) + { + g_snprintf (str, size, _("(%.0lf%%)"), p->percentage); + } + else + { + *str = '\0'; + } } +/** + * Regardless, the accessible name for the whole menu title should be the same + * as the accessible name for that thing’s component inside the menu itself. + */ void -indicator_power_device_get_header (const IndicatorPowerDevice * device, - gboolean show_time, - gboolean show_percentage, - gchar ** header, - gchar ** a11y) +indicator_power_device_get_accessible_title (const IndicatorPowerDevice * device, + gchar * str, + gulong size, + gboolean want_time G_GNUC_UNUSED, + gboolean want_percent G_GNUC_UNUSED) { - indicator_power_device_get_text (device, show_time, show_percentage, - header, NULL, a11y); + indicator_power_device_get_accessible_text (device, str, size); } /*** diff --git a/src/device.h b/src/device.h index 1f395a1..65c6767 100644 --- a/src/device.h +++ b/src/device.h @@ -116,22 +116,35 @@ IndicatorPowerDevice* indicator_power_device_new (const gchar * object_path, IndicatorPowerDevice* indicator_power_device_new_from_variant (GVariant * variant); -UpDeviceKind indicator_power_device_get_kind (const IndicatorPowerDevice * device); -UpDeviceState indicator_power_device_get_state (const IndicatorPowerDevice * device); -const gchar * indicator_power_device_get_object_path (const IndicatorPowerDevice * device); -gdouble indicator_power_device_get_percentage (const IndicatorPowerDevice * device); -time_t indicator_power_device_get_time (const IndicatorPowerDevice * device); - -GStrv indicator_power_device_get_icon_names (const IndicatorPowerDevice * device); -GIcon * indicator_power_device_get_gicon (const IndicatorPowerDevice * device); - -gchar * indicator_power_device_get_label (const IndicatorPowerDevice * device); - -void indicator_power_device_get_header (const IndicatorPowerDevice * device, - gboolean show_time, - gboolean show_percentage, - gchar ** header, - gchar ** a11y); +UpDeviceKind indicator_power_device_get_kind (const IndicatorPowerDevice * device); +UpDeviceState indicator_power_device_get_state (const IndicatorPowerDevice * device); +const gchar * indicator_power_device_get_object_path (const IndicatorPowerDevice * device); +gdouble indicator_power_device_get_percentage (const IndicatorPowerDevice * device); +time_t indicator_power_device_get_time (const IndicatorPowerDevice * device); + +GStrv indicator_power_device_get_icon_names (const IndicatorPowerDevice * device); +GIcon * indicator_power_device_get_gicon (const IndicatorPowerDevice * device); + + +void indicator_power_device_get_readable_text (const IndicatorPowerDevice * device, + gchar * str, + gulong size); + +void indicator_power_device_get_accessible_text (const IndicatorPowerDevice * device, + gchar * str, + gulong size); + +void indicator_power_device_get_readable_title (const IndicatorPowerDevice * device, + gchar * str, + gulong size, + gboolean want_time, + gboolean want_percent); + +void indicator_power_device_get_accessible_title (const IndicatorPowerDevice * device, + gchar * str, + gulong size, + gboolean want_time, + gboolean want_percent); G_END_DECLS diff --git a/src/service.c b/src/service.c index 982a24e..248f953 100644 --- a/src/service.c +++ b/src/service.c @@ -312,21 +312,7 @@ static GVariant * create_header_state (IndicatorPowerService * self) { GVariantBuilder b; - gchar * label = NULL; - gchar * a11y = NULL; - GIcon * icon = NULL; - priv_t * p = self->priv; - - if (p->primary_device != NULL) - { - indicator_power_device_get_header (p->primary_device, - g_settings_get_boolean (p->settings, SETTINGS_SHOW_TIME_S), - g_settings_get_boolean (p->settings, SETTINGS_SHOW_PERCENTAGE_S), - &label, - &a11y); - - icon = indicator_power_device_get_gicon (p->primary_device); - } + const priv_t * const p = self->priv; g_variant_builder_init (&b, G_VARIANT_TYPE("a{sv}")); @@ -335,24 +321,42 @@ create_header_state (IndicatorPowerService * self) g_variant_builder_add (&b, "{sv}", "visible", g_variant_new_boolean (should_be_visible (self))); - if (label != NULL) - g_variant_builder_add (&b, "{sv}", "label", g_variant_new_take_string (label)); - - if (icon != NULL) + if (p->primary_device != NULL) { - GVariant * v; + char buf[128]; + GIcon * icon; + const gboolean want_time = g_settings_get_boolean (p->settings, SETTINGS_SHOW_TIME_S); + const gboolean want_percent = g_settings_get_boolean (p->settings, SETTINGS_SHOW_PERCENTAGE_S); + + indicator_power_device_get_readable_title (p->primary_device, + buf, sizeof(buf), + want_time, + want_percent); + if (*buf) + g_variant_builder_add (&b, "{sv}", "label", g_variant_new_string (buf)); + + + indicator_power_device_get_accessible_title (p->primary_device, + buf, sizeof(buf), + want_time, + want_percent); + if (*buf) + g_variant_builder_add (&b, "{sv}", "accessible-desc", g_variant_new_string (buf)); - if ((v = g_icon_serialize (icon))) + + if ((icon = indicator_power_device_get_gicon (p->primary_device))) { - g_variant_builder_add (&b, "{sv}", "icon", v); - g_variant_unref (v); - } + GVariant * serialized_icon = g_icon_serialize (icon); - g_object_unref (icon); - } + if (serialized_icon != NULL) + { + g_variant_builder_add (&b, "{sv}", "icon", serialized_icon); + g_variant_unref (serialized_icon); + } - if (a11y != NULL) - g_variant_builder_add (&b, "{sv}", "accessible-desc", g_variant_new_take_string (a11y)); + g_object_unref (icon); + } + } return g_variant_builder_end (&b); } @@ -371,28 +375,31 @@ append_device_to_menu (GMenu * menu, const IndicatorPowerDevice * device) if (kind != UP_DEVICE_KIND_LINE_POWER) { - char * label; + char buf[128]; GMenuItem * item; GIcon * icon; - label = indicator_power_device_get_label (device); - item = g_menu_item_new (label, "indicator.activate-statistics"); - g_free (label); - g_menu_item_set_action_and_target(item, "indicator.activate-statistics", "s", - indicator_power_device_get_object_path (device)); + indicator_power_device_get_readable_text (device, buf, sizeof(buf)); + item = g_menu_item_new (buf, "indicator.activate-statistics"); if ((icon = indicator_power_device_get_gicon (device))) { - GVariant * v; - if ((v = g_icon_serialize (icon))) + GVariant * serialized_icon = g_icon_serialize (icon); + + if (serialized_icon != NULL) { - g_menu_item_set_attribute_value (item, G_MENU_ATTRIBUTE_ICON, v); - g_variant_unref (v); + g_menu_item_set_attribute_value (item, + G_MENU_ATTRIBUTE_ICON, + serialized_icon); + g_variant_unref (serialized_icon); } g_object_unref (icon); } + g_menu_item_set_action_and_target(item, "indicator.activate-statistics", "s", + indicator_power_device_get_object_path (device)); + g_menu_append_item (menu, item); g_object_unref (item); } diff --git a/tests/Makefile.am b/tests/Makefile.am index 5c7d802..47b3e84 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -18,7 +18,7 @@ nodist_libgtest_a_SOURCES = \ $(GTEST_SOURCE)/src/gtest-all.cc \ $(GTEST_SOURCE)/src/gtest_main.cc -AM_CPPFLAGS = $(GTEST_CPPFLAGS) -I${top_srcdir}/src -Wall -Werror +AM_CPPFLAGS = $(GTEST_CPPFLAGS) -I${top_srcdir}/src -Wall -Werror -std=c++11 AM_CXXFLAGS = $(GTEST_CXXFLAGS) ### diff --git a/tests/test-device.cc b/tests/test-device.cc index 2762d4a..dfbba59 100644 --- a/tests/test-device.cc +++ b/tests/test-device.cc @@ -72,12 +72,11 @@ class DeviceTest : public ::testing::Test void check_label (const IndicatorPowerDevice * device, const char * expected_label) { - char * label; - - label = indicator_power_device_get_label (device); + char label[128]; + indicator_power_device_get_readable_text (device, label, sizeof(label)); + if (expected_label == nullptr) + expected_label = ""; EXPECT_STREQ (expected_label, label); - - g_free (label); } void check_header (const IndicatorPowerDevice * device, @@ -86,32 +85,23 @@ class DeviceTest : public ::testing::Test const char * expected_percent, const char * expected_a11y) { - char * label; - char * a11y; - - indicator_power_device_get_header (device, true, true, &label, &a11y); - EXPECT_STREQ (expected_time_and_percent, label); - EXPECT_STREQ (expected_a11y, a11y); - g_free (label); - g_free (a11y); - - indicator_power_device_get_header (device, true, false, &label, &a11y); - EXPECT_STREQ (expected_time, label); - EXPECT_STREQ (expected_a11y, a11y); - g_free (label); - g_free (a11y); - - indicator_power_device_get_header (device, false, true, &label, &a11y); - EXPECT_STREQ (expected_percent, label); - EXPECT_STREQ (expected_a11y, a11y); - g_free (label); - g_free (a11y); - - indicator_power_device_get_header (device, false, false, &label, &a11y); - ASSERT_TRUE (!label || !*label); - EXPECT_STREQ (expected_a11y, a11y); - g_free (label); - g_free (a11y); + char a11y[128]; + char title[128]; + + indicator_power_device_get_readable_title (device, title, sizeof(title), true, true); + EXPECT_STREQ (expected_time_and_percent ? expected_time_and_percent : "", title); + + indicator_power_device_get_readable_title (device, title, sizeof(title), true, false); + EXPECT_STREQ (expected_time ? expected_time : "", title); + + indicator_power_device_get_readable_title (device, title, sizeof(title), false, true); + EXPECT_STREQ (expected_percent ? expected_percent : "", title); + + indicator_power_device_get_readable_title (device, title, sizeof(title), false, false); + EXPECT_STREQ ("", title); + + indicator_power_device_get_accessible_title (device, a11y, sizeof(a11y), false, false); + EXPECT_STREQ (expected_a11y ? expected_a11y : "", a11y); } }; @@ -481,14 +471,16 @@ TEST_F(DeviceTest, Labels) g_setenv ("LANG", "en_US.UTF-8", TRUE); // bad args: NULL device - log_count_ipower_expected += 5; + log_count_ipower_expected++; check_label (NULL, NULL); + log_count_ipower_expected += 5; check_header (NULL, NULL, NULL, NULL, NULL); // bad args: a GObject that isn't a device - log_count_ipower_expected += 5; GObject * o = G_OBJECT(g_cancellable_new()); + log_count_ipower_expected++; check_label ((IndicatorPowerDevice*)o, NULL); + log_count_ipower_expected += 5; check_header (NULL, NULL, NULL, NULL, NULL); g_object_unref (o); @@ -509,7 +501,7 @@ TEST_F(DeviceTest, Labels) check_header (device, "(1:01, 50%)", "(1:01)", "(50%)", - "Battery (1 hour 1 minute to charge, 50%)"); + "Battery (1 hour 1 minute to charge)"); // discharging, < 12 hours left g_object_set (o, INDICATOR_POWER_DEVICE_KIND, UP_DEVICE_KIND_BATTERY, @@ -521,7 +513,7 @@ TEST_F(DeviceTest, Labels) check_header (device, "(1:01, 50%)", "(1:01)", "(50%)", - "Battery (1 hour 1 minute left, 50%)"); + "Battery (1 hour 1 minute left)"); // discharging, > 24 hours left // we don't show the clock time when > 24 hours discharging @@ -534,7 +526,7 @@ TEST_F(DeviceTest, Labels) check_header (device, "(50%)", "", "(50%)", - "Battery (50%)"); + "Battery"); // fully charged g_object_set (o, INDICATOR_POWER_DEVICE_KIND, UP_DEVICE_KIND_BATTERY, @@ -546,7 +538,7 @@ TEST_F(DeviceTest, Labels) check_header (device, "(100%)", "", "(100%)", - "Battery (charged, 100%)"); + "Battery (charged)"); // percentage but no time estimate g_object_set (o, INDICATOR_POWER_DEVICE_KIND, UP_DEVICE_KIND_BATTERY, @@ -558,7 +550,7 @@ TEST_F(DeviceTest, Labels) check_header (device, "(estimating…, 50%)", "(estimating…)", "(50%)", - "Battery (estimating…, 50%)"); + "Battery (estimating…)"); // no percentage, no time estimate g_object_set (o, INDICATOR_POWER_DEVICE_KIND, UP_DEVICE_KIND_BATTERY, @@ -566,8 +558,8 @@ TEST_F(DeviceTest, Labels) INDICATOR_POWER_DEVICE_PERCENTAGE, 0.0, INDICATOR_POWER_DEVICE_TIME, guint64(0), NULL); - check_label (device, "Battery (not present)"); - check_header (device, "", "", "", "Battery (not present)"); + check_label (device, "Battery"); + check_header (device, "", "", "", "Battery"); // power line g_object_set (o, INDICATOR_POWER_DEVICE_KIND, UP_DEVICE_KIND_LINE_POWER, @@ -584,6 +576,84 @@ TEST_F(DeviceTest, Labels) g_free (real_lang); } + +TEST_F(DeviceTest, Inestimable___this_takes_80_seconds) +{ + // set our language so that i18n won't break these tests + auto real_lang = g_strdup(g_getenv ("LANG")); + g_setenv ("LANG", "en_US.UTF-8", true); + + // set up the main loop + auto loop = g_main_loop_new (nullptr, false); + auto loop_quit_sourcefunc = [](gpointer l){ + g_main_loop_quit(static_cast(l)); + return G_SOURCE_REMOVE; + }; + + auto device = INDICATOR_POWER_DEVICE (g_object_new (INDICATOR_POWER_DEVICE_TYPE, nullptr)); + auto o = G_OBJECT(device); + + // percentage but no time estimate + auto timer = g_timer_new (); + g_object_set (o, INDICATOR_POWER_DEVICE_KIND, UP_DEVICE_KIND_BATTERY, + INDICATOR_POWER_DEVICE_STATE, UP_DEVICE_STATE_DISCHARGING, + INDICATOR_POWER_DEVICE_PERCENTAGE, 50.0, + INDICATOR_POWER_DEVICE_TIME, guint64(0), + nullptr); + + /* + * “estimating…” if the time remaining has been inestimable for + * less than 30 seconds; otherwise “unknown” if the time remaining + * has been inestimable for between 30 seconds and one minute; + * otherwise the empty string. + */ + for (;;) + { + g_timeout_add_seconds (1, loop_quit_sourcefunc, loop); + g_main_loop_run (loop); + + const auto elapsed = g_timer_elapsed (timer, nullptr); + + if (elapsed < 30) + { + check_label (device, "Battery (estimating…)"); + check_header (device, "(estimating…, 50%)", + "(estimating…)", + "(50%)", + "Battery (estimating…)"); + } + else if (elapsed < 60) + { + check_label (device, "Battery (unknown)"); + check_header (device, "(unknown, 50%)", + "(unknown)", + "(50%)", + "Battery (unknown)"); + } + else if (elapsed < 80) + { + check_label (device, "Battery"); + check_header (device, "(50%)", + "", + "(50%)", + "Battery"); + } + else + { + break; + } + } + + g_main_loop_unref (loop); + + // cleanup + g_timer_destroy (timer); + g_object_unref (o); + g_setenv ("LANG", real_lang, TRUE); + g_free (real_lang); +} + + /* The menu title should tell you at a glance what you need to know most: what device will lose power soonest (and optionally when), or otherwise which device will take longest to charge (and optionally how long it will take). */ @@ -645,10 +715,12 @@ TEST_F(DeviceTest, ChoosePrimary) INDICATOR_POWER_DEVICE_PERCENTAGE, tests[j].percentage, NULL); ASSERT_EQ (a, indicator_power_service_choose_primary_device(device_list)); + g_object_unref (G_OBJECT(a)); /* reverse the list to check that list order doesn't matter */ device_list = g_list_reverse (device_list); ASSERT_EQ (a, indicator_power_service_choose_primary_device(device_list)); + g_object_unref (G_OBJECT(a)); } } -- cgit v1.2.3 From 6a577e1b2d6941af7eef77a7a6a8c4c064dcbcf4 Mon Sep 17 00:00:00 2001 From: "Y.C cheng" Date: Wed, 5 Mar 2014 13:32:26 +0800 Subject: clean up / wrong code fix --- src/ib-brightness-powerd-control.c | 27 +++++++++++++++++++-------- src/service.c | 28 ++++++++++++---------------- 2 files changed, 31 insertions(+), 24 deletions(-) (limited to 'src/service.c') diff --git a/src/ib-brightness-powerd-control.c b/src/ib-brightness-powerd-control.c index 3395bda..e7d4e0e 100644 --- a/src/ib-brightness-powerd-control.c +++ b/src/ib-brightness-powerd-control.c @@ -40,8 +40,8 @@ powerd_get_proxy(void) &error); if (error != NULL) { - g_error_free (error); g_debug ("could not connect to powerd: %s", error->message); + g_error_free (error); return NULL; } return powerd_proxy; @@ -109,11 +109,12 @@ static void ib_brightness_init(IbBrightnessPowerdControl *control) { gboolean ret = getBrightnessParams(control->powerd_proxy, &(control->min), &(control->max), &(control->dflt), &(control->ab_supported)); - if (! ret) return; - - ib_brightness_powerd_control_set_value(control, control->max); + if (! ret) + return; control->inited = TRUE; + + ib_brightness_powerd_control_set_value(control, control->max * 8 / 10); } IbBrightnessPowerdControl* @@ -134,8 +135,16 @@ void ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint value) { gboolean ret; - if (! self->inited) return; - if (value > self->max || value < self->min) return; + if (! self->inited) + return; + if (value > self->max) + { + value = self->max; + } + else if (value < self->min) + { + value = self->min; + } ret = setUserBrightness(self->powerd_proxy, value); if (ret) { @@ -146,14 +155,16 @@ ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint va gint ib_brightness_powerd_control_get_value (IbBrightnessPowerdControl* self) { - if (! self->inited) return 0; + if (! self->inited) + return 0; return self->current; } gint ib_brightness_powerd_control_get_max_value (IbBrightnessPowerdControl* self) { - if (! self->inited) return 0; + if (! self->inited) + return 0; return self->max; } diff --git a/src/service.c b/src/service.c index 0f976d1..959e316 100644 --- a/src/service.c +++ b/src/service.c @@ -442,12 +442,16 @@ create_phone_devices_section (IndicatorPowerService * self G_GNUC_UNUSED) static void get_brightness_range (IndicatorPowerService * self, gint * low, gint * high) { + priv_t * p = self->priv; int max = 0; - if (self->priv->brightness_control) { - max = ib_brightness_control_get_max_value (self->priv->brightness_control); - } else { - max = ib_brightness_powerd_control_get_max_value (self->priv->brightness_powerd_control); - } + if (p->brightness_control) + { + max = ib_brightness_control_get_max_value (self->priv->brightness_control); + } + else if (p->brightness_powerd_control) + { + max = ib_brightness_powerd_control_get_max_value (self->priv->brightness_powerd_control); + } *low = max * 0.05; /* 5% minimum -- don't let the screen go completely dark */ *high = max; } @@ -1023,14 +1027,9 @@ my_dispose (GObject * o) g_clear_object (&p->conn); - if (p->brightness_control) - { - g_clear_pointer (&p->brightness_control, ib_brightness_control_free); - } - else if (p->brightness_powerd_control) - { - g_clear_pointer (&p->brightness_powerd_control, ib_brightness_powerd_control_free); - } + // g_clear_pointer has NULL check inside. + g_clear_pointer (&p->brightness_control, ib_brightness_control_free); + g_clear_pointer (&p->brightness_powerd_control, ib_brightness_powerd_control_free); indicator_power_service_set_device_provider (self, NULL); @@ -1054,9 +1053,6 @@ indicator_power_service_init (IndicatorPowerService * self) p->settings = g_settings_new ("com.canonical.indicator.power"); - p->brightness_control = NULL; - p->brightness_powerd_control = NULL; - powerd_proxy = powerd_get_proxy(); if (powerd_proxy != NULL) { -- cgit v1.2.3 From 237ba715a189e550f86b3b2ac11e4aefa43e3955 Mon Sep 17 00:00:00 2001 From: "Y.C cheng" Date: Wed, 5 Mar 2014 16:09:10 +0800 Subject: brightness parameters as necessary condition to use powerd --- src/ib-brightness-powerd-control.c | 57 ++++++++++++++++++++------------------ src/ib-brightness-powerd-control.h | 12 ++++++-- src/service.c | 5 ++-- 3 files changed, 43 insertions(+), 31 deletions(-) (limited to 'src/service.c') diff --git a/src/ib-brightness-powerd-control.c b/src/ib-brightness-powerd-control.c index e7d4e0e..461bb54 100644 --- a/src/ib-brightness-powerd-control.c +++ b/src/ib-brightness-powerd-control.c @@ -26,10 +26,18 @@ #include "ib-brightness-powerd-control.h" +static gboolean getBrightnessParams(GDBusProxy* powerd_proxy, int *min, int *max, + int *dflt, gboolean *ab_supported); + GDBusProxy* -powerd_get_proxy(void) +powerd_get_proxy(brightness_params_t *params) { GError *error = NULL; + gboolean ret; + + if (params == NULL) + return NULL; + GDBusProxy* powerd_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, @@ -39,11 +47,23 @@ powerd_get_proxy(void) NULL, &error); - if (error != NULL) { + if (error != NULL) + { g_debug ("could not connect to powerd: %s", error->message); g_error_free (error); return NULL; } + + ret = getBrightnessParams(powerd_proxy, &(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; + } + return powerd_proxy; } @@ -58,7 +78,7 @@ getBrightnessParams(GDBusProxy* powerd_proxy, int *min, int *max, int *dflt, gbo "getBrightnessParams", NULL, G_DBUS_CALL_FLAGS_NONE, - -1, NULL, &error); + 400, NULL, &error); // timeout: 400 ms if (!ret) { g_warning("getBrightnessParams failed: %s", error->message); g_error_free(error); @@ -92,8 +112,6 @@ static gboolean setUserBrightness(GDBusProxy* powerd_proxy, int brightness) struct _IbBrightnessPowerdControl { - gboolean inited; - GDBusProxy *powerd_proxy; int min; @@ -104,29 +122,20 @@ struct _IbBrightnessPowerdControl int current; }; - -static void ib_brightness_init(IbBrightnessPowerdControl *control) -{ - gboolean ret = getBrightnessParams(control->powerd_proxy, &(control->min), - &(control->max), &(control->dflt), &(control->ab_supported)); - if (! ret) - return; - - control->inited = TRUE; - - ib_brightness_powerd_control_set_value(control, control->max * 8 / 10); -} - IbBrightnessPowerdControl* -ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy) +ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy, brightness_params_t params) { IbBrightnessPowerdControl *control; control = g_new0 (IbBrightnessPowerdControl, 1); - control->inited = FALSE; control->powerd_proxy = powerd_proxy; - ib_brightness_init(control); + control->min = params.min; + control->max = params.max; + control->dflt = params.dflt; + control->ab_supported = params.ab_supported; + + ib_brightness_powerd_control_set_value(control, control->max * 8 / 10); return control; } @@ -135,8 +144,6 @@ void ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint value) { gboolean ret; - if (! self->inited) - return; if (value > self->max) { value = self->max; @@ -155,16 +162,12 @@ ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint va gint ib_brightness_powerd_control_get_value (IbBrightnessPowerdControl* self) { - if (! self->inited) - return 0; return self->current; } gint ib_brightness_powerd_control_get_max_value (IbBrightnessPowerdControl* self) { - if (! self->inited) - return 0; return self->max; } diff --git a/src/ib-brightness-powerd-control.h b/src/ib-brightness-powerd-control.h index 77e44cb..77f6c8d 100644 --- a/src/ib-brightness-powerd-control.h +++ b/src/ib-brightness-powerd-control.h @@ -21,11 +21,19 @@ #define __IB_BRIGHTNESS_POWERD_CONTROL_H__ #include -GDBusProxy* powerd_get_proxy(); + +typedef struct { + int max; + int min; + int dflt; + gboolean ab_supported; +} brightness_params_t; + +GDBusProxy* powerd_get_proxy(brightness_params_t *); typedef struct _IbBrightnessPowerdControl IbBrightnessPowerdControl; -IbBrightnessPowerdControl* ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy); +IbBrightnessPowerdControl* ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy, brightness_params_t params); void ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint value); gint ib_brightness_powerd_control_get_value (IbBrightnessPowerdControl* self); gint ib_brightness_powerd_control_get_max_value (IbBrightnessPowerdControl* self); diff --git a/src/service.c b/src/service.c index 959e316..9be5eca 100644 --- a/src/service.c +++ b/src/service.c @@ -1044,6 +1044,7 @@ static void indicator_power_service_init (IndicatorPowerService * self) { GDBusProxy *powerd_proxy = NULL; + brightness_params_t powerd_brigtness_params; priv_t * p = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_TYPE_POWER_SERVICE, IndicatorPowerServicePrivate); @@ -1053,10 +1054,10 @@ indicator_power_service_init (IndicatorPowerService * self) p->settings = g_settings_new ("com.canonical.indicator.power"); - powerd_proxy = powerd_get_proxy(); + powerd_proxy = powerd_get_proxy(&powerd_brigtness_params); if (powerd_proxy != NULL) { - p->brightness_powerd_control = ib_brightness_powerd_control_new(powerd_proxy); + p->brightness_powerd_control = ib_brightness_powerd_control_new(powerd_proxy, powerd_brigtness_params); } else { -- cgit v1.2.3 From a67018fec5c2d6ffa54cff364c513223844559f3 Mon Sep 17 00:00:00 2001 From: "Y.C cheng" Date: Thu, 6 Mar 2014 11:27:12 +0800 Subject: refine and use default value as initial brightness value --- src/ib-brightness-powerd-control.c | 43 ++++++++++++++++++-------------------- src/service.c | 8 +++---- 2 files changed, 24 insertions(+), 27 deletions(-) (limited to 'src/service.c') diff --git a/src/ib-brightness-powerd-control.c b/src/ib-brightness-powerd-control.c index 96afe7d..2136fcd 100644 --- a/src/ib-brightness-powerd-control.c +++ b/src/ib-brightness-powerd-control.c @@ -17,13 +17,6 @@ * Yuan-Chen Cheng */ -#include - -#include -#include -#include -#include - #include "ib-brightness-powerd-control.h" static gboolean getBrightnessParams(GDBusProxy* powerd_proxy, int *min, int *max, @@ -35,8 +28,7 @@ powerd_get_proxy(brightness_params_t *params) GError *error = NULL; gboolean ret; - if (params == NULL) - return NULL; + g_return_val_if_fail (params != NULL, NULL); GDBusProxy* powerd_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, @@ -79,9 +71,16 @@ getBrightnessParams(GDBusProxy* powerd_proxy, int *min, int *max, int *dflt, gbo NULL, G_DBUS_CALL_FLAGS_NONE, 400, NULL, &error); // timeout: 400 ms - if (!ret) { - g_warning("getBrightnessParams failed: %s", error->message); - g_error_free(error); + 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; } @@ -101,7 +100,7 @@ static gboolean setUserBrightness(GDBusProxy* powerd_proxy, GCancellable *gcance G_DBUS_CALL_FLAGS_NONE, -1, gcancel, &error); if (!ret) { - g_warning("setUserBrightness failed: %s", error->message); + g_warning("setUserBrightness via powerd failed: %s", error->message); g_error_free(error); return FALSE; } else { @@ -117,7 +116,7 @@ struct _IbBrightnessPowerdControl int min; int max; - int dflt; + int dflt; // defalut value gboolean ab_supported; int current; @@ -137,7 +136,11 @@ ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy, brightness_params_t control->dflt = params.dflt; control->ab_supported = params.ab_supported; - ib_brightness_powerd_control_set_value(control, control->max * 8 / 10); + // XXX: set the brightness value is the only way to sync the brightness value with + // powerd, 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_powerd_control_set_value(control, control->dflt); return control; } @@ -146,14 +149,8 @@ void ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint value) { gboolean ret; - if (value > self->max) - { - value = self->max; - } - else if (value < self->min) - { - value = self->min; - } + + value = CLAMP(value, self->min, self->max); ret = setUserBrightness(self->powerd_proxy, self->gcancel, value); if (ret) { diff --git a/src/service.c b/src/service.c index 9be5eca..f6653f4 100644 --- a/src/service.c +++ b/src/service.c @@ -1043,8 +1043,8 @@ my_dispose (GObject * o) static void indicator_power_service_init (IndicatorPowerService * self) { - GDBusProxy *powerd_proxy = NULL; - brightness_params_t powerd_brigtness_params; + GDBusProxy *powerd_proxy; + brightness_params_t powerd_brightness_params; priv_t * p = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_TYPE_POWER_SERVICE, IndicatorPowerServicePrivate); @@ -1054,10 +1054,10 @@ indicator_power_service_init (IndicatorPowerService * self) p->settings = g_settings_new ("com.canonical.indicator.power"); - powerd_proxy = powerd_get_proxy(&powerd_brigtness_params); + powerd_proxy = powerd_get_proxy(&powerd_brightness_params); if (powerd_proxy != NULL) { - p->brightness_powerd_control = ib_brightness_powerd_control_new(powerd_proxy, powerd_brigtness_params); + p->brightness_powerd_control = ib_brightness_powerd_control_new(powerd_proxy, powerd_brightness_params); } else { -- cgit v1.2.3 From 9936e22d5e70cd10988f328e8d86b1e5bc93ede9 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 13 Mar 2014 09:05:34 -0500 Subject: in the new indicator_power_device_get_*() functions, use heap-allocated strings rather than relying on g_snprintf(). --- src/device.c | 147 +++++++++++++++++++++------------------------------ src/device.h | 16 ++---- src/service.c | 43 ++++++++------- tests/test-device.cc | 45 ++++++++-------- 4 files changed, 113 insertions(+), 138 deletions(-) (limited to 'src/service.c') diff --git a/src/device.c b/src/device.c index e7384ee..37b1d8b 100644 --- a/src/device.c +++ b/src/device.c @@ -543,11 +543,10 @@ device_kind_to_localised_string (UpDeviceKind kind) * between 30 seconds and one minute; otherwise * * the empty string. */ -static void -get_brief_time_remaining (const IndicatorPowerDevice * device, - char * str, - gulong size) +static char * +get_brief_time_remaining (const IndicatorPowerDevice * device) { + gchar * str = NULL; const IndicatorPowerDevicePrivate * p = device->priv; if (p->time > 0) @@ -556,7 +555,7 @@ get_brief_time_remaining (const IndicatorPowerDevice * device, int hours = minutes / 60; minutes %= 60; - g_snprintf (str, size, "%0d:%02d", hours, minutes); + str = g_strdup_printf("%0d:%02d", hours, minutes); } else if (p->inestimable != NULL) { @@ -564,21 +563,15 @@ get_brief_time_remaining (const IndicatorPowerDevice * device, if (elapsed < 30) { - g_snprintf (str, size, _("estimating…")); + str = g_strdup_printf (_("estimating…")); } else if (elapsed < 60) { - g_snprintf (str, size, _("unknown")); + str = g_strdup_printf (_("unknown")); } - else - { - *str = '\0'; - } - } - else - { - *str = '\0'; } + + return str; } /** @@ -588,16 +581,12 @@ get_brief_time_remaining (const IndicatorPowerDevice * device, * * if the component is charging, it should be “H:MM to charge” * * if the component is discharging, it should be “H:MM left”. */ -static void -get_expanded_time_remaining (const IndicatorPowerDevice * device, - char * str, - gulong size) +static char* +get_expanded_time_remaining (const IndicatorPowerDevice * device) { + char * str = NULL; const IndicatorPowerDevicePrivate * p; - g_return_if_fail (str != NULL); - g_return_if_fail (size > 0); - *str = '\0'; g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); p = device->priv; @@ -610,35 +599,33 @@ get_expanded_time_remaining (const IndicatorPowerDevice * device, if (p->state == UP_DEVICE_STATE_CHARGING) { - g_snprintf (str, size, _("%0d:%02d to charge"), hours, minutes); + str = g_strdup_printf (_("%0d:%02d to charge"), hours, minutes); } else // discharging { - g_snprintf (str, size, _("%0d:%02d left"), hours, minutes); + str = g_strdup_printf (_("%0d:%02d left"), hours, minutes); } } else { - get_brief_time_remaining (device, str, size); + str = get_brief_time_remaining (device); } + + return str; } /** * The '''accessible time-remaining string''' for a component * should be the same as the expanded time-remaining string, * except the H:MM time should be rendered as “''H'' hours ''M'' minutes”, - * or just as “''M'' * minutes” if the time is less than one hour. + * or just as “''M'' minutes” if the time is less than one hour. */ -static void -get_accessible_time_remaining (const IndicatorPowerDevice * device, - char * str, - gulong size) +static char * +get_accessible_time_remaining (const IndicatorPowerDevice * device) { + char * str = NULL; const IndicatorPowerDevicePrivate * p; - g_return_if_fail (str != NULL); - g_return_if_fail (size > 0); - *str = '\0'; g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); p = device->priv; @@ -652,28 +639,30 @@ get_accessible_time_remaining (const IndicatorPowerDevice * device, if (p->state == UP_DEVICE_STATE_CHARGING) { if (hours > 0) - g_snprintf (str, size, _("%d %s %d %s to charge"), + str = g_strdup_printf (_("%d %s %d %s to charge"), hours, g_dngettext (NULL, "hour", "hours", hours), minutes, g_dngettext (NULL, "minute", "minutes", minutes)); else - g_snprintf (str, size, _("%d %s to charge"), + str = g_strdup_printf (_("%d %s to charge"), minutes, g_dngettext (NULL, "minute", "minutes", minutes)); } else // discharging { if (hours > 0) - g_snprintf (str, size, _("%d %s %d %s left"), + str = g_strdup_printf (_("%d %s %d %s left"), hours, g_dngettext (NULL, "hour", "hours", hours), minutes, g_dngettext (NULL, "minute", "minutes", minutes)); else - g_snprintf (str, size, _("%d %s left"), + str = g_strdup_printf (_("%d %s left"), minutes, g_dngettext (NULL, "minute", "minutes", minutes)); } } else { - get_brief_time_remaining (device, str, size); + str = get_brief_time_remaining (device); } + + return str; } /** @@ -709,66 +698,55 @@ time_is_relevant (const IndicatorPowerDevice * device) * visible label, except with the accessible time-remaining string * instead of the expanded time-remaining string. */ -static void +static char * get_menuitem_text (const IndicatorPowerDevice * device, - gchar * str, - gulong size, gboolean accessible) { + char * str = NULL; const IndicatorPowerDevicePrivate * p = device->priv; const char * kind_str = device_kind_to_localised_string (p->kind); if (p->state == UP_DEVICE_STATE_FULLY_CHARGED) { - g_snprintf (str, size, _("%s (charged)"), kind_str); + str = g_strdup_printf (_("%s (charged)"), kind_str); } else { - char buf[64]; + char * time_str = NULL; if (time_is_relevant (device)) { if (accessible) - get_accessible_time_remaining (device, buf, sizeof(buf)); + time_str = get_accessible_time_remaining (device); else - get_expanded_time_remaining (device, buf, sizeof(buf)); - } - else - { - *buf = '\0'; + time_str = get_expanded_time_remaining (device); } - if (*buf) - g_snprintf (str, size, _("%s (%s)"), kind_str, buf); + if (time_str && *time_str) + str = g_strdup_printf (_("%s (%s)"), kind_str, time_str); else - g_strlcpy (str, kind_str, size); + str = g_strdup (kind_str); + + g_free (time_str); } + + return str; } -void -indicator_power_device_get_readable_text (const IndicatorPowerDevice * device, - gchar * str, - gulong size) +char * +indicator_power_device_get_readable_text (const IndicatorPowerDevice * device) { - g_return_if_fail (str != NULL); - g_return_if_fail (size > 0); - *str = '\0'; g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); - get_menuitem_text (device, str, size, FALSE); + return get_menuitem_text (device, FALSE); } -void -indicator_power_device_get_accessible_text (const IndicatorPowerDevice * device, - gchar * str, - gulong size) +char * +indicator_power_device_get_accessible_text (const IndicatorPowerDevice * device) { - g_return_if_fail (str != NULL); - g_return_if_fail (size > 0); - *str = '\0'; g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); - get_menuitem_text (device, str, size, TRUE); + return get_menuitem_text (device, TRUE); } /** @@ -783,19 +761,15 @@ indicator_power_device_get_accessible_text (const IndicatorPowerDevice * device, * * If both conditions are true, the time and percentage should be separated by a space. */ -void +char* indicator_power_device_get_readable_title (const IndicatorPowerDevice * device, - gchar * str, - gulong size, gboolean want_time, gboolean want_percent) { - char tr[64]; + char * str = NULL; + char * time_str = NULL; const IndicatorPowerDevicePrivate * p; - g_return_if_fail (str != NULL); - g_return_if_fail (size > 0); - *str = '\0'; g_return_if_fail (INDICATOR_IS_POWER_DEVICE(device)); p = device->priv; @@ -811,42 +785,41 @@ indicator_power_device_get_readable_title (const IndicatorPowerDevice * device, // try to build the time-remaining string if (want_time) { - get_brief_time_remaining (device, tr, sizeof(tr)); - - if (!*tr) - want_time = FALSE; + time_str = get_brief_time_remaining (device); + want_time = time_str && *time_str; } if (want_time && want_percent) { - g_snprintf (str, size, _("(%s, %.0lf%%)"), tr, p->percentage); + str = g_strdup_printf (_("(%s, %.0lf%%)"), time_str, p->percentage); } else if (want_time) { - g_snprintf (str, size, _("(%s)"), tr); + str = g_strdup_printf (_("(%s)"), time_str); } else if (want_percent) { - g_snprintf (str, size, _("(%.0lf%%)"), p->percentage); + str = g_strdup_printf (_("(%.0lf%%)"), p->percentage); } else { - *str = '\0'; + str = NULL; } + + g_free (time_str); + return str; } /** * Regardless, the accessible name for the whole menu title should be the same * as the accessible name for that thing’s component inside the menu itself. */ -void +char * indicator_power_device_get_accessible_title (const IndicatorPowerDevice * device, - gchar * str, - gulong size, gboolean want_time G_GNUC_UNUSED, gboolean want_percent G_GNUC_UNUSED) { - indicator_power_device_get_accessible_text (device, str, size); + return indicator_power_device_get_accessible_text (device); } /*** diff --git a/src/device.h b/src/device.h index 65c6767..3a10f89 100644 --- a/src/device.h +++ b/src/device.h @@ -126,23 +126,15 @@ GStrv indicator_power_device_get_icon_names (const IndicatorPower GIcon * indicator_power_device_get_gicon (const IndicatorPowerDevice * device); -void indicator_power_device_get_readable_text (const IndicatorPowerDevice * device, - gchar * str, - gulong size); +char * indicator_power_device_get_readable_text (const IndicatorPowerDevice * device); -void indicator_power_device_get_accessible_text (const IndicatorPowerDevice * device, - gchar * str, - gulong size); +char * indicator_power_device_get_accessible_text (const IndicatorPowerDevice * device); -void indicator_power_device_get_readable_title (const IndicatorPowerDevice * device, - gchar * str, - gulong size, +char * indicator_power_device_get_readable_title (const IndicatorPowerDevice * device, gboolean want_time, gboolean want_percent); -void indicator_power_device_get_accessible_title (const IndicatorPowerDevice * device, - gchar * str, - gulong size, +char * indicator_power_device_get_accessible_title (const IndicatorPowerDevice * device, gboolean want_time, gboolean want_percent); diff --git a/src/service.c b/src/service.c index 248f953..405ad96 100644 --- a/src/service.c +++ b/src/service.c @@ -323,26 +323,32 @@ create_header_state (IndicatorPowerService * self) if (p->primary_device != NULL) { - char buf[128]; + char * title; GIcon * icon; const gboolean want_time = g_settings_get_boolean (p->settings, SETTINGS_SHOW_TIME_S); const gboolean want_percent = g_settings_get_boolean (p->settings, SETTINGS_SHOW_PERCENTAGE_S); - indicator_power_device_get_readable_title (p->primary_device, - buf, sizeof(buf), - want_time, - want_percent); - if (*buf) - g_variant_builder_add (&b, "{sv}", "label", g_variant_new_string (buf)); - - - indicator_power_device_get_accessible_title (p->primary_device, - buf, sizeof(buf), - want_time, - want_percent); - if (*buf) - g_variant_builder_add (&b, "{sv}", "accessible-desc", g_variant_new_string (buf)); + title = indicator_power_device_get_readable_title (p->primary_device, + want_time, + want_percent); + if (title) + { + if (*title) + g_variant_builder_add (&b, "{sv}", "label", g_variant_new_take_string (title)); + else + g_free (title); + } + title = indicator_power_device_get_accessible_title (p->primary_device, + want_time, + want_percent); + if (title) + { + if (*title) + g_variant_builder_add (&b, "{sv}", "accessible-desc", g_variant_new_take_string (title)); + else + g_free (title); + } if ((icon = indicator_power_device_get_gicon (p->primary_device))) { @@ -375,12 +381,13 @@ append_device_to_menu (GMenu * menu, const IndicatorPowerDevice * device) if (kind != UP_DEVICE_KIND_LINE_POWER) { - char buf[128]; + char * label; GMenuItem * item; GIcon * icon; - indicator_power_device_get_readable_text (device, buf, sizeof(buf)); - item = g_menu_item_new (buf, "indicator.activate-statistics"); + label = indicator_power_device_get_readable_text (device); + item = g_menu_item_new (label, "indicator.activate-statistics"); + g_free (label); if ((icon = indicator_power_device_get_gicon (device))) { diff --git a/tests/test-device.cc b/tests/test-device.cc index dfbba59..dee0aa6 100644 --- a/tests/test-device.cc +++ b/tests/test-device.cc @@ -72,11 +72,9 @@ class DeviceTest : public ::testing::Test void check_label (const IndicatorPowerDevice * device, const char * expected_label) { - char label[128]; - indicator_power_device_get_readable_text (device, label, sizeof(label)); - if (expected_label == nullptr) - expected_label = ""; + char * label = indicator_power_device_get_readable_text (device); EXPECT_STREQ (expected_label, label); + g_free (label); } void check_header (const IndicatorPowerDevice * device, @@ -85,23 +83,28 @@ class DeviceTest : public ::testing::Test const char * expected_percent, const char * expected_a11y) { - char a11y[128]; - char title[128]; + char * a11y = NULL; + char * title = NULL; - indicator_power_device_get_readable_title (device, title, sizeof(title), true, true); - EXPECT_STREQ (expected_time_and_percent ? expected_time_and_percent : "", title); + title = indicator_power_device_get_readable_title (device, true, true); + EXPECT_STREQ (expected_time_and_percent, title); + g_free (title); - indicator_power_device_get_readable_title (device, title, sizeof(title), true, false); - EXPECT_STREQ (expected_time ? expected_time : "", title); + title = indicator_power_device_get_readable_title (device, true, false); + EXPECT_STREQ (expected_time, title); + g_free (title); - indicator_power_device_get_readable_title (device, title, sizeof(title), false, true); - EXPECT_STREQ (expected_percent ? expected_percent : "", title); + title = indicator_power_device_get_readable_title (device, false, true); + EXPECT_STREQ (expected_percent, title); + g_free (title); - indicator_power_device_get_readable_title (device, title, sizeof(title), false, false); - EXPECT_STREQ ("", title); + title = indicator_power_device_get_readable_title (device, false, false); + EXPECT_STREQ (NULL, title); + g_free (title); - indicator_power_device_get_accessible_title (device, a11y, sizeof(a11y), false, false); - EXPECT_STREQ (expected_a11y ? expected_a11y : "", a11y); + a11y = indicator_power_device_get_accessible_title (device, false, false); + EXPECT_STREQ (expected_a11y, a11y); + g_free (a11y); } }; @@ -524,7 +527,7 @@ TEST_F(DeviceTest, Labels) NULL); check_label (device, "Battery"); check_header (device, "(50%)", - "", + NULL, "(50%)", "Battery"); @@ -536,7 +539,7 @@ TEST_F(DeviceTest, Labels) NULL); check_label (device, "Battery (charged)"); check_header (device, "(100%)", - "", + NULL, "(100%)", "Battery (charged)"); @@ -559,7 +562,7 @@ TEST_F(DeviceTest, Labels) INDICATOR_POWER_DEVICE_TIME, guint64(0), NULL); check_label (device, "Battery"); - check_header (device, "", "", "", "Battery"); + check_header (device, NULL, NULL, NULL, "Battery"); // power line g_object_set (o, INDICATOR_POWER_DEVICE_KIND, UP_DEVICE_KIND_LINE_POWER, @@ -568,7 +571,7 @@ TEST_F(DeviceTest, Labels) INDICATOR_POWER_DEVICE_TIME, guint64(0), NULL); check_label (device, "AC Adapter"); - check_header (device, "", "", "", "AC Adapter"); + check_header (device, NULL, NULL, NULL, "AC Adapter"); // cleanup g_object_unref(o); @@ -634,7 +637,7 @@ TEST_F(DeviceTest, Inestimable___this_takes_80_seconds) { check_label (device, "Battery"); check_header (device, "(50%)", - "", + NULL, "(50%)", "Battery"); } -- cgit v1.2.3 From d6159805fc552643902321b3d41d1a0a53594f05 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 13 Mar 2014 17:27:29 -0500 Subject: add lp:~charlesk/indicator-power/lp-1256872 --- src/service.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'src/service.c') diff --git a/src/service.c b/src/service.c index 405ad96..1d8ba3e 100644 --- a/src/service.c +++ b/src/service.c @@ -375,7 +375,7 @@ create_header_state (IndicatorPowerService * self) ***/ static void -append_device_to_menu (GMenu * menu, const IndicatorPowerDevice * device) +append_device_to_menu (GMenu * menu, const IndicatorPowerDevice * device, int profile) { const UpDeviceKind kind = indicator_power_device_get_kind (device); @@ -386,7 +386,7 @@ append_device_to_menu (GMenu * menu, const IndicatorPowerDevice * device) GIcon * icon; label = indicator_power_device_get_readable_text (device); - item = g_menu_item_new (label, "indicator.activate-statistics"); + item = g_menu_item_new (label, NULL); g_free (label); if ((icon = indicator_power_device_get_gicon (device))) @@ -404,8 +404,11 @@ append_device_to_menu (GMenu * menu, const IndicatorPowerDevice * device) g_object_unref (icon); } - g_menu_item_set_action_and_target(item, "indicator.activate-statistics", "s", - indicator_power_device_get_object_path (device)); + if (profile == PROFILE_DESKTOP) + { + g_menu_item_set_action_and_target(item, "indicator.activate-statistics", "s", + indicator_power_device_get_object_path (device)); + } g_menu_append_item (menu, item); g_object_unref (item); @@ -414,13 +417,13 @@ append_device_to_menu (GMenu * menu, const IndicatorPowerDevice * device) static GMenuModel * -create_desktop_devices_section (IndicatorPowerService * self) +create_desktop_devices_section (IndicatorPowerService * self, int profile) { GList * l; GMenu * menu = g_menu_new (); for (l=self->priv->devices; l!=NULL; l=l->next) - append_device_to_menu (menu, l->data); + append_device_to_menu (menu, l->data, profile); return G_MENU_MODEL (menu); } @@ -595,8 +598,8 @@ rebuild_now (IndicatorPowerService * self, guint sections) if (sections & SECTION_DEVICES) { - rebuild_section (desktop->submenu, 0, create_desktop_devices_section (self)); - rebuild_section (greeter->submenu, 0, create_desktop_devices_section (self)); + rebuild_section (desktop->submenu, 0, create_desktop_devices_section (self, PROFILE_DESKTOP)); + rebuild_section (greeter->submenu, 0, create_desktop_devices_section (self, PROFILE_DESKTOP_GREETER)); } if (sections & SECTION_SETTINGS) @@ -647,12 +650,12 @@ create_menu (IndicatorPowerService * self, int profile) break; case PROFILE_DESKTOP: - sections[n++] = create_desktop_devices_section (self); + sections[n++] = create_desktop_devices_section (self, PROFILE_DESKTOP); sections[n++] = create_desktop_settings_section (self); break; case PROFILE_DESKTOP_GREETER: - sections[n++] = create_desktop_devices_section (self); + sections[n++] = create_desktop_devices_section (self, PROFILE_DESKTOP_GREETER); break; } -- cgit v1.2.3 From b3ec90e07e00f3f28665207987bb9fb73153664b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 19 Mar 2014 14:15:54 -0500 Subject: when choosing a primary device and more than one battery is found, accumulate their percentages and time-remaining properties as per the spec revisions in bug #880881. --- src/service.c | 130 +++++++++++++++++++++++++++++++++++++++-- tests/test-device.cc | 160 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 220 insertions(+), 70 deletions(-) (limited to 'src/service.c') diff --git a/src/service.c b/src/service.c index 248f953..e042e9e 100644 --- a/src/service.c +++ b/src/service.c @@ -1125,6 +1125,129 @@ indicator_power_service_set_device_provider (IndicatorPowerService * self, } } +/* If a device has multiple batteries and uses only one of them at a time, + they should be presented as separate items inside the battery menu, + but everywhere else they should be aggregated (bug 880881). + Their percentages should be averaged. If any are discharging, + the aggregated time remaining should be the maximum of the times + for all those that are discharging, plus the sum of the times + for all those that are idle. Otherwise, the aggregated time remaining + should be the the maximum of the times for all those that are charging. */ +static IndicatorPowerDevice * +create_totalled_battery_device (const GList * devices) +{ + const GList * l; + guint n_charged = 0; + guint n_charging = 0; + guint n_discharging = 0; + guint n_batteries = 0; + double sum_percent = 0; + time_t max_discharge_time = 0; + time_t max_charge_time = 0; + time_t sum_charged_time = 0; + IndicatorPowerDevice * device = NULL; + + for (l=devices; l!=NULL; l=l->next) + { + const IndicatorPowerDevice * device = INDICATOR_POWER_DEVICE(l->data); + + if (indicator_power_device_get_kind(device) == UP_DEVICE_KIND_BATTERY) + { + const double percent = indicator_power_device_get_percentage (device); + const time_t t = indicator_power_device_get_time (device); + const UpDeviceState state = indicator_power_device_get_state (device); + + ++n_batteries; + + if (percent > 0.01) + sum_percent += percent; + + if (state == UP_DEVICE_STATE_CHARGING) + { + ++n_charging; + max_charge_time = MAX(max_charge_time, t); + } + else if (state == UP_DEVICE_STATE_DISCHARGING) + { + ++n_discharging; + max_discharge_time = MAX(max_discharge_time, t); + } + else if (state == UP_DEVICE_STATE_FULLY_CHARGED) + { + ++n_charged; + sum_charged_time += t; + } + } + } + + if (n_batteries > 1) + { + const double percent = sum_percent / n_batteries; + UpDeviceState state; + time_t time_left; + + if (n_discharging > 0) + { + state = UP_DEVICE_STATE_DISCHARGING; + time_left = max_discharge_time + sum_charged_time; + } + else if (n_charging > 0) + { + state = UP_DEVICE_STATE_CHARGING; + time_left = max_charge_time; + } + else if (n_charged > 0) + { + state = UP_DEVICE_STATE_FULLY_CHARGED; + time_left = 0; + } + else + { + state = UP_DEVICE_STATE_UNKNOWN; + time_left = 0; + } + + device = indicator_power_device_new (NULL, + UP_DEVICE_KIND_BATTERY, + percent, + state, + time_left); + } + + return device; +} + +/** + * If there are multiple UP_DEVICE_KIND_BATTERY devices in the list, + * they're merged into a new 'totalled' device representing the sum of them. + * + * Returns: (element-type IndicatorPowerDevice)(transfer full): a list of devices + */ +static GList* +merge_batteries_together (GList * devices) +{ + GList * ret; + IndicatorPowerDevice * merged_device; + + if ((merged_device = create_totalled_battery_device (devices))) + { + GList * l; + + ret = g_list_append (NULL, merged_device); + + for (l=devices; l!=NULL; l=l->next) + if (indicator_power_device_get_kind(INDICATOR_POWER_DEVICE(l->data)) != UP_DEVICE_KIND_BATTERY) + ret = g_list_append (ret, g_object_ref(l->data)); + } + else /* not enough batteries to merge */ + { + ret = g_list_copy (devices); + g_list_foreach (ret, (GFunc)g_object_ref, NULL); + } + + return ret; +} + IndicatorPowerDevice * indicator_power_service_choose_primary_device (GList * devices) { @@ -1132,13 +1255,10 @@ indicator_power_service_choose_primary_device (GList * devices) if (devices != NULL) { - GList * tmp; - - tmp = g_list_copy (devices); + GList * tmp = merge_batteries_together (devices); tmp = g_list_sort (tmp, device_compare_func); primary = g_object_ref (tmp->data); - - g_list_free (tmp); + g_list_free_full (tmp, (GDestroyNotify)g_object_unref); } return primary; diff --git a/tests/test-device.cc b/tests/test-device.cc index dfbba59..010dd92 100644 --- a/tests/test-device.cc +++ b/tests/test-device.cc @@ -19,6 +19,7 @@ with this program. If not, see . #include #include +#include // ceil() #include "device.h" #include "service.h" @@ -653,77 +654,106 @@ TEST_F(DeviceTest, Inestimable___this_takes_80_seconds) g_free (real_lang); } - -/* The menu title should tell you at a glance what you need to know most: what - device will lose power soonest (and optionally when), or otherwise which - device will take longest to charge (and optionally how long it will take). */ +/* If a device has multiple batteries and uses only one of them at a time, + they should be presented as separate items inside the battery menu, + but everywhere else they should be aggregated (bug 880881). + Their percentages should be averaged. If any are discharging, + the aggregated time remaining should be the maximum of the times + for all those that are discharging, plus the sum of the times + for all those that are idle. Otherwise, the aggregated time remaining + should be the the maximum of the times for all those that are charging. */ TEST_F(DeviceTest, ChoosePrimary) { - GList * device_list; - IndicatorPowerDevice * a; - IndicatorPowerDevice * b; - - a = indicator_power_device_new ("/org/freedesktop/UPower/devices/mouse", - UP_DEVICE_KIND_MOUSE, - 0.0, - UP_DEVICE_STATE_DISCHARGING, - 0); - b = indicator_power_device_new ("/org/freedesktop/UPower/devices/battery", - UP_DEVICE_KIND_BATTERY, - 0.0, - UP_DEVICE_STATE_DISCHARGING, - 0); - - /* device states + time left to {discharge,charge} + % of charge left, - sorted in order of preference wrt the spec's criteria. - So tests[i] should be picked over any test with an index greater than i */ - struct { - int kind; - int state; + struct Description + { + const char * path; + UpDeviceKind kind; + UpDeviceState state; guint64 time; double percentage; - } tests[] = { - { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 49, 50.0 }, - { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 50, 50.0 }, - { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 50, 100.0 }, - { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 51, 50.0 }, - { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 50, 50.0 }, - { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 49, 50.0 }, - { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 49, 100.0 }, - { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 48, 50.0 }, - { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_FULLY_CHARGED, 0, 50.0 }, - { UP_DEVICE_KIND_KEYBOARD, UP_DEVICE_STATE_FULLY_CHARGED, 0, 50.0 }, - { UP_DEVICE_KIND_LINE_POWER, UP_DEVICE_STATE_UNKNOWN, 0, 0.0 } }; - device_list = NULL; - device_list = g_list_append (device_list, a); - device_list = g_list_append (device_list, b); + const Description descriptions[] = { + { "/some/path/d0", UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 10, 60.0 }, // 0 + { "/some/path/d1", UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 20, 80.0 }, // 1 + { "/some/path/d2", UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 30, 100.0 }, // 2 - for (int i=0, n=G_N_ELEMENTS(tests); i devices; + for(const auto& desc : descriptions) + devices.push_back(indicator_power_device_new(desc.path, desc.kind, desc.percentage, desc.state, desc.time)); + + const struct { + std::vector device_indices; + Description expected; + } tests[] = { + + { { 0 }, descriptions[0] }, // 1 discharging + { { 0, 1 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 20, 70.0 } }, // 2 discharging + { { 1, 2 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 30, 90.0 } }, // 2 discharging + { { 0, 1, 2 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 30, 80.0 } }, // 3 discharging + + { { 3 }, descriptions[3] }, // 1 charging + { { 3, 4 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 20, 70.0 } }, // 2 charging + { { 4, 5 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 30, 90.0 } }, // 2 charging + { { 3, 4, 5 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 30, 80.0 } }, // 3 charging + + { { 6 }, descriptions[6] }, // 1 charged + { { 6, 0 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 10, 80.0 } }, // 1 charged, 1 discharging + { { 6, 3 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 10, 80.0 } }, // 1 charged, 1 charging + { { 6, 0, 3 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 10, 73.3 } }, // 1 charged, 1 charging, 1 discharging + + { { 0, 7 }, descriptions[0] }, // 1 discharging battery, 1 discharging mouse. pick the one with the least time left. + { { 2, 7 }, descriptions[7] }, // 1 discharging battery, 1 discharging mouse. pick the one with the least time left. + + { { 0, 8 }, descriptions[0] }, // 1 discharging battery, 1 fully-charged mouse. pick the one that's discharging. + { { 6, 7 }, descriptions[7] }, // 1 discharging mouse, 1 fully-charged battery. pick the one that's discharging. + + { { 0, 9 }, descriptions[0] }, // everything comes before power lines + { { 3, 9 }, descriptions[3] }, + { { 7, 9 }, descriptions[7] } + }; + + for(const auto& test : tests) + { + const auto& x = test.expected; + + GList * device_glist = nullptr; + for(const auto& i : test.device_indices) + device_glist = g_list_append(device_glist, devices[i]); + + auto primary = indicator_power_service_choose_primary_device(device_glist); + EXPECT_STREQ(x.path, indicator_power_device_get_object_path(primary)); + EXPECT_EQ(x.kind, indicator_power_device_get_kind(primary)); + EXPECT_EQ(x.state, indicator_power_device_get_state(primary)); + EXPECT_EQ(x.time, indicator_power_device_get_time(primary)); + EXPECT_EQ((int)ceil(x.percentage), (int)ceil(indicator_power_device_get_percentage(primary))); + g_object_unref(primary); + + // reverse the list and repeat the test + // to confirm that list order doesn't matter + device_glist = g_list_reverse (device_glist); + primary = indicator_power_service_choose_primary_device (device_glist); + EXPECT_STREQ(x.path, indicator_power_device_get_object_path(primary)); + EXPECT_EQ(x.kind, indicator_power_device_get_kind(primary)); + EXPECT_EQ(x.state, indicator_power_device_get_state(primary)); + EXPECT_EQ(x.time, indicator_power_device_get_time(primary)); + EXPECT_EQ((int)ceil(x.percentage), (int)ceil(indicator_power_device_get_percentage(primary))); + g_object_unref(primary); + + // cleanup + g_list_free(device_glist); + } + + for (auto& device : devices) + g_object_unref (device); } -- cgit v1.2.3 From 0b58eeb4ac217053c261444accc1124463e1ee3f Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 27 Mar 2014 13:17:22 +0100 Subject: Use com.canonical.indicator.basic menu item for device items That menu item can handle non-square icons. --- src/service.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/service.c') diff --git a/src/service.c b/src/service.c index 1d8ba3e..1a4e24a 100644 --- a/src/service.c +++ b/src/service.c @@ -389,6 +389,8 @@ append_device_to_menu (GMenu * menu, const IndicatorPowerDevice * device, int pr item = g_menu_item_new (label, NULL); g_free (label); + g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.basic"); + if ((icon = indicator_power_device_get_gicon (device))) { GVariant * serialized_icon = g_icon_serialize (icon); -- cgit v1.2.3 From b36744ef3a292f8027d90ebecded9f751c199af7 Mon Sep 17 00:00:00 2001 From: Iain Lane Date: Tue, 15 Apr 2014 14:08:08 +0100 Subject: Don't add the brightness entry to the phone profile; it's been removed by design --- src/service.c | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) (limited to 'src/service.c') diff --git a/src/service.c b/src/service.c index 00efe9b..46ad802 100644 --- a/src/service.c +++ b/src/service.c @@ -491,24 +491,6 @@ percentage_to_brightness (IndicatorPowerService * self, double percentage) return (int)(lo + (percentage*(hi-lo))); } -static GMenuItem * -create_brightness_menuitem (IndicatorPowerService * self) -{ - int lo, hi; - GMenuItem * item; - - get_brightness_range (self, &lo, &hi); - - 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", brightness_to_percentage (self, lo)); - g_menu_item_set_attribute (item, "max-value", "d", brightness_to_percentage (self, hi)); - g_menu_item_set_attribute (item, "min-icon", "s", "torch-off" ); - g_menu_item_set_attribute (item, "max-icon", "s", "torch-on" ); - - return item; -} - static GVariant * action_state_for_brightness (IndicatorPowerService * self) { @@ -574,18 +556,12 @@ create_desktop_settings_section (IndicatorPowerService * self G_GNUC_UNUSED) } static GMenuModel * -create_phone_settings_section (IndicatorPowerService * self G_GNUC_UNUSED) +create_phone_settings_section (IndicatorPowerService * self) { GMenu * section; - GMenuItem * item; section = g_menu_new (); - - item = create_brightness_menuitem (self); - g_menu_append_item (section, item); update_brightness_action_state (self); - g_object_unref (item); - g_menu_append (section, _("Battery settings…"), "indicator.activate-phone-settings"); return G_MENU_MODEL (section); -- cgit v1.2.3 From 9e9a0da8c20c64dd394d98b94955e58911b2c53e Mon Sep 17 00:00:00 2001 From: Alberto Aguirre Date: Thu, 19 Jun 2014 10:04:01 -0500 Subject: Remove references to powerd since the brightness interface is now provided by Unity.Screen --- src/Makefile.am | 4 +- src/ib-brightness-powerd-control.c | 201 ----------------------------------- src/ib-brightness-powerd-control.h | 43 -------- src/ib-brightness-uscreen-control.c | 202 ++++++++++++++++++++++++++++++++++++ src/ib-brightness-uscreen-control.h | 43 ++++++++ src/service.c | 28 ++--- 6 files changed, 261 insertions(+), 260 deletions(-) delete mode 100644 src/ib-brightness-powerd-control.c delete mode 100644 src/ib-brightness-powerd-control.h create mode 100644 src/ib-brightness-uscreen-control.c create mode 100644 src/ib-brightness-uscreen-control.h (limited to 'src/service.c') diff --git a/src/Makefile.am b/src/Makefile.am index 2461592..3f71b60 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,8 +46,8 @@ libindciatorpower_upower_a_LDFLAGS = $(COVERAGE_LDFLAGS) libindicatorpower_service_a_SOURCES = \ ib-brightness-control.c \ ib-brightness-control.h \ - ib-brightness-powerd-control.c \ - ib-brightness-powerd-control.h \ + ib-brightness-uscreen-control.c \ + ib-brightness-uscreen-control.h \ device-provider.c \ device-provider.h \ device.c \ diff --git a/src/ib-brightness-powerd-control.c b/src/ib-brightness-powerd-control.c deleted file mode 100644 index ef18ad6..0000000 --- a/src/ib-brightness-powerd-control.c +++ /dev/null @@ -1,201 +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 . - * - * Authors: - * Yuan-Chen Cheng - */ - -#include "ib-brightness-powerd-control.h" - -static gboolean getBrightnessParams(GDBusProxy* powerd_proxy, int *dim, int *min, - int *max, int *dflt, gboolean *ab_supported); - -GDBusProxy* -powerd_get_proxy(brightness_params_t *params) -{ - GError *error = NULL; - gboolean ret; - - g_return_val_if_fail (params != NULL, NULL); - - 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_object_unref (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* powerd_proxy, GCancellable *gcancel, int brightness) -{ - GVariant *ret = NULL; - GError *error = NULL; - - ret = g_dbus_proxy_call_sync(powerd_proxy, - "setUserBrightness", - g_variant_new("(i)", brightness), - G_DBUS_CALL_FLAGS_NONE, - -1, gcancel, &error); - if (!ret) { - g_warning("setUserBrightness via powerd failed: %s", error->message); - g_error_free(error); - return FALSE; - } else { - g_variant_unref(ret); - return TRUE; - } -} - -struct _IbBrightnessPowerdControl -{ - GDBusProxy *powerd_proxy; - GCancellable *gcancel; - - int dim; - int min; - int max; - int dflt; // defalut value - gboolean ab_supported; - - int current; -}; - -IbBrightnessPowerdControl* -ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy, brightness_params_t params) -{ - IbBrightnessPowerdControl *control; - - control = g_new0 (IbBrightnessPowerdControl, 1); - control->powerd_proxy = powerd_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 - // powerd, 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_powerd_control_set_value(control, control->dflt); - - return control; -} - -void -ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint value) -{ - gboolean ret; - - value = CLAMP(value, self->min, self->max); - ret = setUserBrightness(self->powerd_proxy, self->gcancel, value); - if (ret) - { - self->current = value; - } -} - -gint -ib_brightness_powerd_control_get_value (IbBrightnessPowerdControl* self) -{ - return self->current; -} - -gint -ib_brightness_powerd_control_get_max_value (IbBrightnessPowerdControl* self) -{ - return self->max; -} - -void -ib_brightness_powerd_control_free (IbBrightnessPowerdControl *self) -{ - g_cancellable_cancel (self->gcancel); - g_object_unref (self->gcancel); - g_object_unref (self->powerd_proxy); - g_free (self); -} - diff --git a/src/ib-brightness-powerd-control.h b/src/ib-brightness-powerd-control.h deleted file mode 100644 index 95de1f4..0000000 --- a/src/ib-brightness-powerd-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 . - * - * Authors: - * Y.C Cheng - */ - -#ifndef __IB_BRIGHTNESS_POWERD_CONTROL_H__ -#define __IB_BRIGHTNESS_POWERD_CONTROL_H__ - -#include - -typedef struct { - int dim; - int min; - int max; - int dflt; - gboolean ab_supported; -} brightness_params_t; - -GDBusProxy* powerd_get_proxy(brightness_params_t *); - -typedef struct _IbBrightnessPowerdControl IbBrightnessPowerdControl; - -IbBrightnessPowerdControl* ib_brightness_powerd_control_new (GDBusProxy* powerd_proxy, brightness_params_t params); -void ib_brightness_powerd_control_set_value (IbBrightnessPowerdControl* self, gint value); -gint ib_brightness_powerd_control_get_value (IbBrightnessPowerdControl* self); -gint ib_brightness_powerd_control_get_max_value (IbBrightnessPowerdControl* self); -void ib_brightness_powerd_control_free (IbBrightnessPowerdControl *self); - -#endif diff --git a/src/ib-brightness-uscreen-control.c b/src/ib-brightness-uscreen-control.c new file mode 100644 index 0000000..4f8cd3e --- /dev/null +++ b/src/ib-brightness-uscreen-control.c @@ -0,0 +1,202 @@ +/* + * 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 . + * + * Authors: + * Yuan-Chen Cheng + */ + +#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 powerd 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 new file mode 100644 index 0000000..3d026a9 --- /dev/null +++ b/src/ib-brightness-uscreen-control.h @@ -0,0 +1,43 @@ +/* + * 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 . + * + * Authors: + * Y.C Cheng + */ + +#ifndef __IB_BRIGHTNESS_USCREEN_CONTROL_H__ +#define __IB_BRIGHTNESS_USCREEN_CONTROL_H__ + +#include + +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 46ad802..6438c9a 100644 --- a/src/service.c +++ b/src/service.c @@ -27,7 +27,7 @@ #include "device.h" #include "device-provider.h" #include "ib-brightness-control.h" -#include "ib-brightness-powerd-control.h" +#include "ib-brightness-uscreen-control.h" #include "service.h" #define BUS_NAME "com.canonical.indicator.power" @@ -105,7 +105,7 @@ struct _IndicatorPowerServicePrivate GSettings * settings; IbBrightnessControl * brightness_control; - IbBrightnessPowerdControl * brightness_powerd_control; + IbBrightnessUscreenControl * brightness_uscreen_control; guint own_id; guint actions_export_id; @@ -467,9 +467,9 @@ get_brightness_range (IndicatorPowerService * self, gint * low, gint * high) { max = ib_brightness_control_get_max_value (self->priv->brightness_control); } - else if (p->brightness_powerd_control) + else if (p->brightness_uscreen_control) { - max = ib_brightness_powerd_control_get_max_value (self->priv->brightness_powerd_control); + max = ib_brightness_uscreen_control_get_max_value (self->priv->brightness_uscreen_control); } *low = max * 0.05; /* 5% minimum -- don't let the screen go completely dark */ *high = max; @@ -500,9 +500,9 @@ action_state_for_brightness (IndicatorPowerService * self) { brightness = ib_brightness_control_get_value (p->brightness_control); } - else if (p->brightness_powerd_control) + else if (p->brightness_uscreen_control) { - brightness = ib_brightness_powerd_control_get_value (p->brightness_powerd_control); + brightness = ib_brightness_uscreen_control_get_value (p->brightness_uscreen_control); } return g_variant_new_double (brightness_to_percentage (self, brightness)); } @@ -527,9 +527,9 @@ on_brightness_change_requested (GSimpleAction * action G_GNUC_UNUSED, { ib_brightness_control_set_value (self->priv->brightness_control, brightness); } - else if (self->priv->brightness_powerd_control) + else if (self->priv->brightness_uscreen_control) { - ib_brightness_powerd_control_set_value (self->priv->brightness_powerd_control, brightness); + ib_brightness_uscreen_control_set_value (self->priv->brightness_uscreen_control, brightness); } update_brightness_action_state (self); @@ -1024,7 +1024,7 @@ my_dispose (GObject * o) // g_clear_pointer has NULL check inside. g_clear_pointer (&p->brightness_control, ib_brightness_control_free); - g_clear_pointer (&p->brightness_powerd_control, ib_brightness_powerd_control_free); + g_clear_pointer (&p->brightness_uscreen_control, ib_brightness_uscreen_control_free); indicator_power_service_set_device_provider (self, NULL); @@ -1038,8 +1038,8 @@ my_dispose (GObject * o) static void indicator_power_service_init (IndicatorPowerService * self) { - GDBusProxy *powerd_proxy; - brightness_params_t powerd_brightness_params; + GDBusProxy *uscreen_proxy; + brightness_params_t brightness_params; priv_t * p = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_TYPE_POWER_SERVICE, IndicatorPowerServicePrivate); @@ -1049,10 +1049,10 @@ indicator_power_service_init (IndicatorPowerService * self) p->settings = g_settings_new ("com.canonical.indicator.power"); - powerd_proxy = powerd_get_proxy(&powerd_brightness_params); - if (powerd_proxy != NULL) + uscreen_proxy = uscreen_get_proxy(&brightness_params); + if (uscreen_proxy != NULL) { - p->brightness_powerd_control = ib_brightness_powerd_control_new(powerd_proxy, powerd_brightness_params); + p->brightness_uscreen_control = ib_brightness_uscreen_control_new(uscreen_proxy, brightness_params); } else { -- cgit v1.2.3 From 3f29c1a35113bfd2461dca76235f1812c8dfd6ef Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 13 Jul 2014 23:33:16 -0500 Subject: fix some compiler warnings generated by clang static analyzer --- src/device-provider-upower.c | 10 ++++------ src/device-provider.c | 2 +- src/device.c | 18 ++++++++---------- src/ib-brightness-control.c | 6 +++--- src/main.c | 2 -- src/service.c | 33 +++++++++------------------------ tests/test-device.cc | 4 ++-- 7 files changed, 27 insertions(+), 48 deletions(-) (limited to 'src/service.c') diff --git a/src/device-provider-upower.c b/src/device-provider-upower.c index 7c12beb..400a060 100644 --- a/src/device-provider-upower.c +++ b/src/device-provider-upower.c @@ -17,8 +17,6 @@ * with this program. If not, see . */ -#include "config.h" - #include "dbus-upower.h" #include "device.h" #include "device-provider.h" @@ -60,7 +58,7 @@ G_DEFINE_TYPE_WITH_CODE ( indicator_power_device_provider_upower, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (INDICATOR_TYPE_POWER_DEVICE_PROVIDER, - indicator_power_device_provider_interface_init)); + indicator_power_device_provider_interface_init)) /*** **** UPOWER DBUS @@ -102,7 +100,7 @@ on_device_properties_ready (GObject * o, GAsyncResult * res, gpointer gdata) gdouble percentage = 0; gint64 time_to_empty = 0; gint64 time_to_full = 0; - time_t time; + gint64 time; IndicatorPowerDevice * device; IndicatorPowerDeviceProviderUPowerPriv * p = data->self->priv; GVariant * dict = g_variant_get_child_value (response, 0); @@ -120,7 +118,7 @@ on_device_properties_ready (GObject * o, GAsyncResult * res, gpointer gdata) INDICATOR_POWER_DEVICE_STATE, (gint)state, INDICATOR_POWER_DEVICE_OBJECT_PATH, data->path, INDICATOR_POWER_DEVICE_PERCENTAGE, percentage, - INDICATOR_POWER_DEVICE_TIME, (guint64)time, + INDICATOR_POWER_DEVICE_TIME, time, NULL); } else @@ -129,7 +127,7 @@ on_device_properties_ready (GObject * o, GAsyncResult * res, gpointer gdata) kind, percentage, state, - time); + (time_t)time); g_hash_table_insert (p->devices, g_strdup (data->path), diff --git a/src/device-provider.c b/src/device-provider.c index 81a8eec..46fcfad 100644 --- a/src/device-provider.c +++ b/src/device-provider.c @@ -29,7 +29,7 @@ static guint signals[SIGNAL_LAST] = { 0 }; G_DEFINE_INTERFACE (IndicatorPowerDeviceProvider, indicator_power_device_provider, - 0); + 0) static void indicator_power_device_provider_default_init (IndicatorPowerDeviceProviderInterface * klass) diff --git a/src/device.c b/src/device.c index 8780d72..f37aa7d 100644 --- a/src/device.c +++ b/src/device.c @@ -44,8 +44,6 @@ struct _IndicatorPowerDevicePrivate GTimer * inestimable; }; -#define INDICATOR_POWER_DEVICE_GET_PRIVATE(o) (INDICATOR_POWER_DEVICE(o)->priv) - /* Properties */ /* Enum for the properties so that they can be quickly found and looked up. */ enum { @@ -69,7 +67,7 @@ static void set_property (GObject*, guint prop_id, const GValue*, GParamSpec* ); static void get_property (GObject*, guint prop_id, GValue*, GParamSpec* ); /* LCOV_EXCL_START */ -G_DEFINE_TYPE (IndicatorPowerDevice, indicator_power_device, G_TYPE_OBJECT); +G_DEFINE_TYPE (IndicatorPowerDevice, indicator_power_device, G_TYPE_OBJECT) /* LCOV_EXCL_STOP */ static void @@ -189,7 +187,7 @@ get_property (GObject * o, guint prop_id, GValue * value, GParamSpec * pspec) break; case PROP_TIME: - g_value_set_uint64 (value, priv->time); + g_value_set_uint64 (value, (guint64)priv->time); break; default: @@ -207,11 +205,11 @@ set_property (GObject * o, guint prop_id, const GValue * value, GParamSpec * psp switch (prop_id) { case PROP_KIND: - p->kind = g_value_get_int (value); + p->kind = (UpDeviceKind) g_value_get_int (value); break; case PROP_STATE: - p->state = g_value_get_int (value); + p->state = (UpDeviceState) g_value_get_int (value); break; case PROP_OBJECT_PATH: @@ -224,7 +222,7 @@ set_property (GObject * o, guint prop_id, const GValue * value, GParamSpec * psp break; case PROP_TIME: - p->time = g_value_get_uint64(value); + p->time = (time_t) g_value_get_uint64(value); break; default: @@ -627,8 +625,8 @@ get_accessible_time_remaining (const IndicatorPowerDevice * device) if (p->time && ((p->state == UP_DEVICE_STATE_CHARGING) || (p->state == UP_DEVICE_STATE_DISCHARGING))) { - int minutes = p->time / 60; - const int hours = minutes / 60; + guint minutes = (guint)p->time / 60u; + const guint hours = minutes / 60u; minutes %= 60; if (p->state == UP_DEVICE_STATE_CHARGING) @@ -889,5 +887,5 @@ indicator_power_device_new_from_variant (GVariant * v) kind, percentage, state, - time); + (time_t)time); } diff --git a/src/ib-brightness-control.c b/src/ib-brightness-control.c index 4fb6bc5..67da10c 100644 --- a/src/ib-brightness-control.c +++ b/src/ib-brightness-control.c @@ -76,7 +76,7 @@ ib_brightness_control_set_value (IbBrightnessControl* self, gint value) gint fd; gchar *filename; gchar *svalue; - gint length; + size_t length; gint err; if (self->path == NULL) @@ -95,7 +95,7 @@ ib_brightness_control_set_value (IbBrightnessControl* self, gint value) err = errno; errno = 0; - if (write (fd, svalue, length) != length) { + if (write (fd, svalue, length) != (ssize_t)length) { g_warning ("Fail to write brightness information: %s", g_strerror(errno)); } errno = err; @@ -105,7 +105,7 @@ ib_brightness_control_set_value (IbBrightnessControl* self, gint value) g_free (filename); } -gint +static gint ib_brightness_control_get_value_from_file (IbBrightnessControl *self, const gchar *file) { GError *error; diff --git a/src/main.c b/src/main.c index ef615dc..7363284 100644 --- a/src/main.c +++ b/src/main.c @@ -17,8 +17,6 @@ * with this program. If not, see . */ -#include "config.h" - #include #include /* exit() */ diff --git a/src/service.c b/src/service.c index 6438c9a..7478d0f 100644 --- a/src/service.c +++ b/src/service.c @@ -18,8 +18,6 @@ * with this program. If not, see . */ -#include "config.h" - #include #include #include @@ -471,7 +469,7 @@ get_brightness_range (IndicatorPowerService * self, gint * low, gint * high) { max = ib_brightness_uscreen_control_get_max_value (self->priv->brightness_uscreen_control); } - *low = max * 0.05; /* 5% minimum -- don't let the screen go completely dark */ + *low = (gint)(max * 0.05); /* 5% minimum -- don't let the screen go completely dark */ *high = max; } @@ -621,18 +619,6 @@ rebuild_header_now (IndicatorPowerService * self) rebuild_now (self, SECTION_HEADER); } -static inline void -rebuild_devices_section_now (IndicatorPowerService * self) -{ - rebuild_now (self, SECTION_DEVICES); -} - -static inline void -rebuild_settings_section_now (IndicatorPowerService * self) -{ - rebuild_now (self, SECTION_SETTINGS); -} - static void create_menu (IndicatorPowerService * self, int profile) { @@ -938,7 +924,7 @@ on_devices_changed (IndicatorPowerService * self) if (p->primary_device == NULL) battery_level = 0; else - battery_level = (int)(indicator_power_device_get_percentage (p->primary_device) + 0.5); + battery_level = (guint32)(indicator_power_device_get_percentage (p->primary_device) + 0.5); g_simple_action_set_state (p->battery_level_action, g_variant_new_uint32 (battery_level)); rebuild_now (self, SECTION_HEADER | SECTION_DEVICES); @@ -1131,9 +1117,8 @@ indicator_power_service_set_device_provider (IndicatorPowerService * self, if (p->device_provider != NULL) { - g_signal_handlers_disconnect_by_func (p->device_provider, - G_CALLBACK(on_devices_changed), - self); + g_signal_handlers_disconnect_by_data (p->device_provider, self); + g_clear_object (&p->device_provider); g_clear_object (&p->primary_device); @@ -1177,13 +1162,13 @@ create_totalled_battery_device (const GList * devices) for (l=devices; l!=NULL; l=l->next) { - const IndicatorPowerDevice * device = INDICATOR_POWER_DEVICE(l->data); + const IndicatorPowerDevice * walk = INDICATOR_POWER_DEVICE(l->data); - if (indicator_power_device_get_kind(device) == UP_DEVICE_KIND_BATTERY) + if (indicator_power_device_get_kind(walk) == UP_DEVICE_KIND_BATTERY) { - const double percent = indicator_power_device_get_percentage (device); - const time_t t = indicator_power_device_get_time (device); - const UpDeviceState state = indicator_power_device_get_state (device); + const double percent = indicator_power_device_get_percentage (walk); + const time_t t = indicator_power_device_get_time (walk); + const UpDeviceState state = indicator_power_device_get_state (walk); ++n_batteries; diff --git a/tests/test-device.cc b/tests/test-device.cc index 7d54816..1d10b5b 100644 --- a/tests/test-device.cc +++ b/tests/test-device.cc @@ -710,10 +710,10 @@ TEST_F(DeviceTest, ChoosePrimary) std::vector devices; for(const auto& desc : descriptions) - devices.push_back(indicator_power_device_new(desc.path, desc.kind, desc.percentage, desc.state, desc.time)); + devices.push_back(indicator_power_device_new(desc.path, desc.kind, desc.percentage, desc.state, (time_t)desc.time)); const struct { - std::vector device_indices; + std::vector device_indices; Description expected; } tests[] = { -- cgit v1.2.3 From b08f9b096f956b528ad974a30828a809b827efef Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 21 Jul 2014 00:50:24 -0500 Subject: second draft of low battery power notifications, still a work in progress --- data/com.canonical.indicator.power.Battery.xml | 23 +++ src/CMakeLists.txt | 4 + src/dbus-shared.h | 28 +++ src/main.c | 4 - src/notifier.c | 270 +++++++++++++++++++------ src/notifier.h | 4 + src/service.c | 11 + 7 files changed, 275 insertions(+), 69 deletions(-) create mode 100644 data/com.canonical.indicator.power.Battery.xml create mode 100644 src/dbus-shared.h (limited to 'src/service.c') diff --git a/data/com.canonical.indicator.power.Battery.xml b/data/com.canonical.indicator.power.Battery.xml new file mode 100644 index 0000000..d2c8a2d --- /dev/null +++ b/data/com.canonical.indicator.power.Battery.xml @@ -0,0 +1,23 @@ + + + + + + + + + The battery's power level. 0==No Low Battery, 1==Low, 2==Very Low, 3==Critical + + + + + + + + Whether or not indicator-power-service is warning the user about low battery power. + + + + + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4747b12..7a4a297 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,6 +20,10 @@ add_gdbus_codegen_with_namespace(SERVICE_GENERATED_SOURCES dbus-upower org.freedesktop Dbus ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.UPower.xml) +add_gdbus_codegen_with_namespace(SERVICE_GENERATED_SOURCES dbus-battery + com.canonical.indicator.power + Dbus + ${CMAKE_SOURCE_DIR}/data/com.canonical.indicator.power.Battery.xml) # add the bin dir to our include path so the code can find the generated header files include_directories(${CMAKE_CURRENT_BINARY_DIR}) diff --git a/src/dbus-shared.h b/src/dbus-shared.h new file mode 100644 index 0000000..bf54034 --- /dev/null +++ b/src/dbus-shared.h @@ -0,0 +1,28 @@ +/* + * 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 . + * + * Authors: + * Charles Kerr + * Ted Gould + */ + +#ifndef DBUS_SHARED_H +#define DBUS_SHARED_H + +#define BUS_NAME "com.canonical.indicator.power" +#define BUS_PATH "/com/canonical/indicator/power" + +#endif /* DBUS_SHARED_H */ + diff --git a/src/main.c b/src/main.c index 70b7f2a..d7953e6 100644 --- a/src/main.c +++ b/src/main.c @@ -25,7 +25,6 @@ #include "device.h" #include "device-provider-upower.h" -#include "notifier.h" #include "service.h" /*** @@ -43,7 +42,6 @@ int main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) { IndicatorPowerDeviceProvider * device_provider; - IndicatorPowerNotifier * notifier; IndicatorPowerService * service; GMainLoop * loop; @@ -54,7 +52,6 @@ main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) /* run */ device_provider = indicator_power_device_provider_upower_new (); - notifier = indicator_power_notifier_new (device_provider); service = indicator_power_service_new (device_provider); loop = g_main_loop_new (NULL, FALSE); g_signal_connect (service, INDICATOR_POWER_SERVICE_SIGNAL_NAME_LOST, @@ -64,7 +61,6 @@ main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) /* cleanup */ g_main_loop_unref (loop); g_clear_object (&service); - g_clear_object (¬ifier); g_clear_object (&device_provider); return 0; } diff --git a/src/notifier.c b/src/notifier.c index 79ea4cc..897154a 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -17,6 +17,8 @@ * Charles Kerr */ +#include "dbus-battery-info.h" +#include "dbus-shared.h" #include "device.h" #include "device-provider.h" #include "notifier.h" @@ -35,20 +37,41 @@ enum { PROP_0, PROP_DEVICE_PROVIDER, + PROP_IS_WARNING, + PROP_POWER_LEVEL, LAST_PROP }; +#define DEVICE_PROVIDER_NAME "device-provider" +#define IS_WARNING_NAME "is-warning" +#define POWER_LEVEL_NAME "power-level" + static GParamSpec * properties[LAST_PROP]; static int n_notifiers = 0; +typedef enum +{ + POWER_LEVEL_OK, + POWER_LEVEL_LOW, + POWER_LEVEL_VERY_LOW, + POWER_LEVEL_CRITICAL +} +PowerLevel; + struct _IndicatorPowerNotifierPrivate { IndicatorPowerDeviceProvider * device_provider; - IndicatorPowerDevice * primary_device; - gdouble battery_level; - time_t time_remaining; + + IndicatorPowerDevice * battery; NotifyNotification* notify_notification; + gboolean is_warning; + PowerLevel power_level; + + DbusBattery * dbus_battery; + GBinding * is_warning_binding; + GBinding * power_level_binding; + GDBusConnection * bus; }; typedef IndicatorPowerNotifierPrivate priv_t; @@ -57,35 +80,53 @@ typedef IndicatorPowerNotifierPrivate priv_t; **** ***/ +/* implemented here rather than my_set_property() to guard from public use + because this is a read-only property */ static void -emit_critical_signal(IndicatorPowerNotifier * self G_GNUC_UNUSED) +set_is_warning_property (IndicatorPowerNotifier * self, gboolean is_warning) { - g_message("FIXME %s %s", G_STRFUNC, G_STRLOC); -} + priv_t * p = self->priv; -static void -emit_hide_signal(IndicatorPowerNotifier * self G_GNUC_UNUSED) -{ - g_message("FIXME %s %s", G_STRFUNC, G_STRLOC); + if (p->is_warning != is_warning) + { + p->is_warning = is_warning; + + g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_IS_WARNING]); + } } +/* implemented here rather than my_set_property() to guard from public use + because this is a read-only property */ static void -emit_show_signal(IndicatorPowerNotifier * self G_GNUC_UNUSED) +set_power_level_property (IndicatorPowerNotifier * self, PowerLevel power_level) { - g_message("FIXME %s %s", G_STRFUNC, G_STRLOC); + priv_t * p = self->priv; + + if (p->power_level != power_level) + { + p->power_level = power_level; + + g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_POWER_LEVEL]); + } } +/*** +**** +***/ + static void -notification_clear(IndicatorPowerNotifier * self) +notification_clear (IndicatorPowerNotifier * self) { priv_t * p = self->priv; if (p->notify_notification != NULL) { + set_is_warning_property (self, FALSE); + notify_notification_clear_actions(p->notify_notification); g_signal_handlers_disconnect_by_data(p->notify_notification, self); g_clear_object(&p->notify_notification); - emit_hide_signal(self); + } } @@ -107,10 +148,7 @@ notification_show(IndicatorPowerNotifier * self, NotifyNotification * nn; // if there's already a notification, tear it down - if (p->notify_notification != NULL) - { - notification_clear (self); - } + notification_clear (self); // create the notification body = g_strdup_printf(_("%d%% charge remaining"), (int)indicator_power_device_get_percentage(device)); @@ -130,63 +168,75 @@ notification_show(IndicatorPowerNotifier * self, } else { - emit_show_signal(self); + set_is_warning_property (self, TRUE); } g_free (body); } -static void -on_battery_level_changed(IndicatorPowerNotifier * self G_GNUC_UNUSED, - IndicatorPowerDevice * device, - gdouble old_value, - gdouble new_value) +static PowerLevel +get_power_level (const IndicatorPowerDevice * device) { - static const double critical_level = 2.0; - static const double very_low_level = 5.0; - static const double low_level = 48.0; - - if (indicator_power_device_get_state(device) != UP_DEVICE_STATE_DISCHARGING) - return; - -g_message ("%s - %s - %f - %f", G_STRFUNC, indicator_power_device_get_object_path(device), old_value, new_value); + static const double percent_critical = 2.0; + static const double percent_very_low = 5.0; + static const double percent_low = 48.0; + const gdouble p = indicator_power_device_get_percentage(device); + PowerLevel ret; + + if (p <= percent_critical) + ret = POWER_LEVEL_CRITICAL; + else if (p <= percent_very_low) + ret = POWER_LEVEL_VERY_LOW; + else if (p <= percent_low) + ret = POWER_LEVEL_LOW; + else + ret = POWER_LEVEL_OK; - if ((old_value > critical_level) && (new_value <= critical_level)) - { - emit_critical_signal(self); - } - else if ((old_value > very_low_level) && (new_value <= very_low_level)) - { - notification_show(self, device); - } - else if ((old_value > low_level) && (new_value <= low_level)) - { - notification_show(self, device); - } + return ret; } - + static void on_devices_changed(IndicatorPowerNotifier * self) { priv_t * p = self->priv; GList * devices; - - // find the primary device - devices = indicator_power_device_provider_get_devices(p->device_provider); - g_clear_object(&p->primary_device); - p->primary_device = indicator_power_service_choose_primary_device (devices); + IndicatorPowerDevice * primary; + + /* find the primary battery */ + devices = indicator_power_device_provider_get_devices (p->device_provider); + primary = indicator_power_service_choose_primary_device (devices); + g_clear_object (&p->battery); + if ((primary != NULL) && (indicator_power_device_get_kind (primary) == UP_DEVICE_KIND_BATTERY)) + p->battery = g_object_ref (primary); + g_clear_object(&primary); g_list_free_full (devices, (GDestroyNotify)g_object_unref); - if (p->primary_device != NULL) + /* update our state based on the new primary device */ + if (p->battery == NULL) { - // test for battery level change - const gdouble old_level = (int)(p->battery_level*1000) ? p->battery_level : 100.0; - const gdouble new_level = indicator_power_device_get_percentage(p->primary_device); - if ((int)(old_level*1000) != (int)(new_level*1000)) - on_battery_level_changed (self, p->primary_device, old_level, new_level); - - p->battery_level = new_level; - p->time_remaining = indicator_power_device_get_time (p->primary_device); + /* if there's no primary battery, put everything in standby mode */ + set_power_level_property (self, POWER_LEVEL_OK); + notification_clear(self); + } + else + { + const PowerLevel power_level = get_power_level (p->battery); + + if (p->power_level != power_level) + { + set_power_level_property (self, power_level); + + /* maybe update the notifications */ + if ((power_level == POWER_LEVEL_OK) || + (indicator_power_device_get_state(p->battery) != UP_DEVICE_STATE_DISCHARGING)) + { + notification_clear (self); + } + else + { + notification_show (self, p->battery); + } + } } } @@ -209,6 +259,14 @@ my_get_property (GObject * o, g_value_set_object (value, p->device_provider); break; + case PROP_POWER_LEVEL: + g_value_set_int (value, p->power_level); + break; + + case PROP_IS_WARNING: + g_value_set_boolean (value, p->is_warning); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); } @@ -237,16 +295,24 @@ static void my_dispose (GObject * o) { IndicatorPowerNotifier * self = INDICATOR_POWER_NOTIFIER(o); + priv_t * p = self->priv; +g_message ("%s %s dispose %p", G_STRLOC, G_STRFUNC, (void*)o); - indicator_power_notifier_set_device_provider(self, NULL); + indicator_power_notifier_set_bus(self, NULL); notification_clear(self); + indicator_power_notifier_set_device_provider (self, NULL); + + g_clear_pointer (&p->power_level_binding, g_binding_unbind); + g_clear_pointer (&p->is_warning_binding, g_binding_unbind); + g_clear_object (&p->dbus_battery); G_OBJECT_CLASS (indicator_power_notifier_parent_class)->dispose (o); } static void -my_finalize (GObject * o G_GNUC_UNUSED) +my_finalize (GObject * o) { +g_message ("%s %s finalize %p", G_STRLOC, G_STRFUNC, (void*)o); if (!--n_notifiers) notify_uninit(); } @@ -262,8 +328,23 @@ indicator_power_notifier_init (IndicatorPowerNotifier * self) INDICATOR_TYPE_POWER_NOTIFIER, IndicatorPowerNotifierPrivate); self->priv = p; +g_message ("%s %s init %p", G_STRLOC, G_STRFUNC, (void*)self); + + p->dbus_battery = dbus_battery_skeleton_new (); + + /* FIXME: own the busname and export the skeleton */ - //p->battery_levels = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref); + p->is_warning_binding = g_object_bind_property (self, + IS_WARNING_NAME, + p->dbus_battery, + IS_WARNING_NAME, + G_BINDING_SYNC_CREATE); + + p->power_level_binding = g_object_bind_property (self, + POWER_LEVEL_NAME, + p->dbus_battery, + POWER_LEVEL_NAME, + G_BINDING_SYNC_CREATE); if (!n_notifiers++ && !notify_init("indicator-power-service")) g_critical("Unable to initialize libnotify! Notifications might not be shown."); @@ -284,12 +365,28 @@ indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) properties[PROP_0] = NULL; properties[PROP_DEVICE_PROVIDER] = g_param_spec_object ( - "device-provider", + DEVICE_PROVIDER_NAME, "Device Provider", "Source for power devices", G_TYPE_OBJECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + properties[PROP_POWER_LEVEL] = g_param_spec_int ( + POWER_LEVEL_NAME, + "Power Level", + "Power Level of the batteries", + POWER_LEVEL_OK, + POWER_LEVEL_CRITICAL, + POWER_LEVEL_OK, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + properties[PROP_IS_WARNING] = g_param_spec_boolean ( + IS_WARNING_NAME, + "Is Warning", + "Whether or not we're currently warning the user about a low battery", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, LAST_PROP, properties); } @@ -301,7 +398,7 @@ IndicatorPowerNotifier * indicator_power_notifier_new (IndicatorPowerDeviceProvider * device_provider) { GObject * o = g_object_new (INDICATOR_TYPE_POWER_NOTIFIER, - "device-provider", device_provider, + DEVICE_PROVIDER_NAME, device_provider, NULL); return INDICATOR_POWER_NOTIFIER (o); @@ -321,7 +418,7 @@ indicator_power_notifier_set_device_provider(IndicatorPowerNotifier * self, { g_signal_handlers_disconnect_by_data(p->device_provider, self); g_clear_object(&p->device_provider); - g_clear_object(&p->primary_device); + g_clear_object(&p->battery); } if (dp != NULL) @@ -334,3 +431,46 @@ indicator_power_notifier_set_device_provider(IndicatorPowerNotifier * self, on_devices_changed(self); } } + +void +indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, + GDBusConnection * bus) +{ + priv_t * p; + + g_return_if_fail(INDICATOR_IS_POWER_NOTIFIER(self)); + p = self->priv; + + if (p->bus != NULL) + { + if (p->dbus_battery != NULL) + { + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON(p->dbus_battery)); + } + + g_clear_object (&p->bus); + } + + if (bus != NULL) + { + GError * error; + + p->bus = g_object_ref (bus); + + error = NULL; + g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(p->dbus_battery), + bus, + BUS_PATH"/Battery", + &error); + if (error != NULL) + { + g_warning ("Unable to export LowBattery properties: %s", error->message); + g_error_free (error); + } + } +} + + + + + diff --git a/src/notifier.h b/src/notifier.h index e8dfaab..c224b29 100644 --- a/src/notifier.h +++ b/src/notifier.h @@ -22,6 +22,7 @@ #include #include +#include /* GDBusConnection */ #include "device-provider.h" @@ -59,6 +60,9 @@ GType indicator_power_notifier_get_type (void); IndicatorPowerNotifier * indicator_power_notifier_new (IndicatorPowerDeviceProvider * provider); +void indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, + GDBusConnection * connection); + void indicator_power_notifier_set_device_provider (IndicatorPowerNotifier * self, IndicatorPowerDeviceProvider * provider); diff --git a/src/service.c b/src/service.c index 7478d0f..d8f1371 100644 --- a/src/service.c +++ b/src/service.c @@ -22,8 +22,10 @@ #include #include +#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" @@ -120,6 +122,7 @@ struct _IndicatorPowerServicePrivate GList * devices; /* IndicatorPowerDevice */ IndicatorPowerDeviceProvider * device_provider; + IndicatorPowerNotifier * notifier; }; typedef IndicatorPowerServicePrivate priv_t; @@ -821,6 +824,9 @@ on_bus_acquired (GDBusConnection * connection, p->conn = g_object_ref (G_OBJECT (connection)); + /* export the battery properties */ + indicator_power_notifier_set_bus (p->notifier, connection); + /* export the actions */ if ((id = g_dbus_connection_export_action_group (connection, BUS_PATH, @@ -1001,6 +1007,7 @@ my_dispose (GObject * o) g_clear_object (&p->settings); } + g_clear_object (&p->notifier); g_clear_object (&p->brightness_action); g_clear_object (&p->battery_level_action); g_clear_object (&p->header_action); @@ -1035,6 +1042,8 @@ indicator_power_service_init (IndicatorPowerService * self) p->settings = g_settings_new ("com.canonical.indicator.power"); + p->notifier = indicator_power_notifier_new (NULL); + uscreen_proxy = uscreen_get_proxy(&brightness_params); if (uscreen_proxy != NULL) { @@ -1136,6 +1145,8 @@ indicator_power_service_set_device_provider (IndicatorPowerService * self, on_devices_changed (self); } + + indicator_power_notifier_set_device_provider (p->notifier, dp); } /* If a device has multiple batteries and uses only one of them at a time, -- cgit v1.2.3 From 1902911c18a863ca285c53ae323e233119cf0d86 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 21 Jul 2014 11:25:16 -0500 Subject: remove DeviceProvider from Notifier --- src/notifier.c | 260 +++++++++++++++++++++++++-------------------------------- src/notifier.h | 17 +++- src/service.c | 10 ++- 3 files changed, 136 insertions(+), 151 deletions(-) (limited to 'src/service.c') diff --git a/src/notifier.c b/src/notifier.c index 897154a..d32008f 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -19,10 +19,7 @@ #include "dbus-battery-info.h" #include "dbus-shared.h" -#include "device.h" -#include "device-provider.h" #include "notifier.h" -#include "service.h" #include @@ -33,40 +30,44 @@ G_DEFINE_TYPE(IndicatorPowerNotifier, indicator_power_notifier, G_TYPE_OBJECT) +/** +*** GObject Properties +**/ + enum { PROP_0, - PROP_DEVICE_PROVIDER, + PROP_BATTERY, PROP_IS_WARNING, PROP_POWER_LEVEL, LAST_PROP }; -#define DEVICE_PROVIDER_NAME "device-provider" +#define BATTERY_NAME "battery" #define IS_WARNING_NAME "is-warning" #define POWER_LEVEL_NAME "power-level" static GParamSpec * properties[LAST_PROP]; -static int n_notifiers = 0; +/** +*** +**/ -typedef enum -{ - POWER_LEVEL_OK, - POWER_LEVEL_LOW, - POWER_LEVEL_VERY_LOW, - POWER_LEVEL_CRITICAL -} -PowerLevel; +static int n_notifiers = 0; struct _IndicatorPowerNotifierPrivate { IndicatorPowerDeviceProvider * device_provider; + /* The battery we're currently watching. + This may be a physical battery or it may be a "merged" battery + synthesized from multiple batteries present on the device. + See indicator_power_service_choose_primary_device() */ IndicatorPowerDevice * battery; + PowerLevel power_level; + NotifyNotification* notify_notification; gboolean is_warning; - PowerLevel power_level; DbusBattery * dbus_battery; GBinding * is_warning_binding; @@ -77,41 +78,7 @@ struct _IndicatorPowerNotifierPrivate typedef IndicatorPowerNotifierPrivate priv_t; /*** -**** -***/ - -/* implemented here rather than my_set_property() to guard from public use - because this is a read-only property */ -static void -set_is_warning_property (IndicatorPowerNotifier * self, gboolean is_warning) -{ - priv_t * p = self->priv; - - if (p->is_warning != is_warning) - { - p->is_warning = is_warning; - - g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_IS_WARNING]); - } -} - -/* implemented here rather than my_set_property() to guard from public use - because this is a read-only property */ -static void -set_power_level_property (IndicatorPowerNotifier * self, PowerLevel power_level) -{ - priv_t * p = self->priv; - - if (p->power_level != power_level) - { - p->power_level = power_level; - - g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_POWER_LEVEL]); - } -} - -/*** -**** +**** Notifications ***/ static void @@ -135,30 +102,38 @@ on_notification_clicked(NotifyNotification * notify_notification G_GNUC_UNUSED, char * action G_GNUC_UNUSED, gpointer gself G_GNUC_UNUSED) { - /* no-op */ + /* no-op because notify_notification_add_action() doesn't like a NULL cb */ } static void -notification_show(IndicatorPowerNotifier * self, - IndicatorPowerDevice * device) - +notification_show(IndicatorPowerNotifier * self) { - priv_t * p = self->priv; + priv_t * p; + IndicatorPowerDevice * battery; char * body; NotifyNotification * nn; - // if there's already a notification, tear it down notification_clear (self); - // create the notification - body = g_strdup_printf(_("%d%% charge remaining"), (int)indicator_power_device_get_percentage(device)); - p->notify_notification = nn = notify_notification_new(_("Battery Low"), body, NULL); - notify_notification_set_hint(nn, "x-canonical-snap-decisions", g_variant_new_boolean(TRUE)); - notify_notification_set_hint(nn, "x-canonical-private-button-tint", g_variant_new_boolean(TRUE)); - notify_notification_add_action(nn, "OK", _("OK"), on_notification_clicked, self, NULL); + p = self->priv; + battery = p->battery; + g_return_if_fail (battery != NULL); + + /* create the notification */ + body = g_strdup_printf(_("%d%% charge remaining"), + (int)indicator_power_device_get_percentage(battery)); + p->notify_notification = nn = notify_notification_new(_("Battery Low"), + body, + NULL); + notify_notification_set_hint(nn, "x-canonical-snap-decisions", + g_variant_new_boolean(TRUE)); + notify_notification_set_hint(nn, "x-canonical-private-button-tint", + g_variant_new_boolean(TRUE)); + notify_notification_add_action(nn, "OK", _("OK"), + on_notification_clicked, self, NULL); g_signal_connect_swapped(nn, "closed", G_CALLBACK(notification_clear), self); - // show the notification + /* show the notification */ GError* error = NULL; notify_notification_show(nn, &error); if (error != NULL) @@ -174,12 +149,16 @@ notification_show(IndicatorPowerNotifier * self, g_free (body); } +/*** +**** +***/ + static PowerLevel get_power_level (const IndicatorPowerDevice * device) { static const double percent_critical = 2.0; static const double percent_very_low = 5.0; - static const double percent_low = 48.0; + static const double percent_low = 10.0; const gdouble p = indicator_power_device_get_percentage(device); PowerLevel ret; @@ -195,50 +174,6 @@ get_power_level (const IndicatorPowerDevice * device) return ret; } -static void -on_devices_changed(IndicatorPowerNotifier * self) -{ - priv_t * p = self->priv; - GList * devices; - IndicatorPowerDevice * primary; - - /* find the primary battery */ - devices = indicator_power_device_provider_get_devices (p->device_provider); - primary = indicator_power_service_choose_primary_device (devices); - g_clear_object (&p->battery); - if ((primary != NULL) && (indicator_power_device_get_kind (primary) == UP_DEVICE_KIND_BATTERY)) - p->battery = g_object_ref (primary); - g_clear_object(&primary); - g_list_free_full (devices, (GDestroyNotify)g_object_unref); - - /* update our state based on the new primary device */ - if (p->battery == NULL) - { - /* if there's no primary battery, put everything in standby mode */ - set_power_level_property (self, POWER_LEVEL_OK); - notification_clear(self); - } - else - { - const PowerLevel power_level = get_power_level (p->battery); - - if (p->power_level != power_level) - { - set_power_level_property (self, power_level); - - /* maybe update the notifications */ - if ((power_level == POWER_LEVEL_OK) || - (indicator_power_device_get_state(p->battery) != UP_DEVICE_STATE_DISCHARGING)) - { - notification_clear (self); - } - else - { - notification_show (self, p->battery); - } - } - } -} /*** **** GObject virtual functions @@ -255,8 +190,8 @@ my_get_property (GObject * o, switch (property_id) { - case PROP_DEVICE_PROVIDER: - g_value_set_object (value, p->device_provider); + case PROP_BATTERY: + g_value_set_object (value, p->battery); break; case PROP_POWER_LEVEL: @@ -282,8 +217,8 @@ my_set_property (GObject * o, switch (property_id) { - case PROP_DEVICE_PROVIDER: - indicator_power_notifier_set_device_provider (self, g_value_get_object (value)); + case PROP_BATTERY: + indicator_power_notifier_set_battery (self, g_value_get_object(value)); break; default: @@ -291,17 +226,43 @@ my_set_property (GObject * o, } } +/* read-only property, so not implemented in my_set_property() */ +static void +set_is_warning_property (IndicatorPowerNotifier * self, gboolean is_warning) +{ + priv_t * p = self->priv; + + if (p->is_warning != is_warning) + { + p->is_warning = is_warning; + + g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_IS_WARNING]); + } +} + +/* read-only property, so not implemented in my_set_property() */ +static void +set_power_level_property (IndicatorPowerNotifier * self, PowerLevel power_level) +{ + priv_t * p = self->priv; + + if (p->power_level != power_level) + { + p->power_level = power_level; + + g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_POWER_LEVEL]); + } +} + static void my_dispose (GObject * o) { IndicatorPowerNotifier * self = INDICATOR_POWER_NOTIFIER(o); priv_t * p = self->priv; -g_message ("%s %s dispose %p", G_STRLOC, G_STRFUNC, (void*)o); - - indicator_power_notifier_set_bus(self, NULL); - notification_clear(self); - indicator_power_notifier_set_device_provider (self, NULL); + indicator_power_notifier_set_bus (self, NULL); + notification_clear (self); + indicator_power_notifier_set_device (self, NULL); g_clear_pointer (&p->power_level_binding, g_binding_unbind); g_clear_pointer (&p->is_warning_binding, g_binding_unbind); g_clear_object (&p->dbus_battery); @@ -310,9 +271,8 @@ g_message ("%s %s dispose %p", G_STRLOC, G_STRFUNC, (void*)o); } static void -my_finalize (GObject * o) +my_finalize (GObject * o G_GNUC_UNUSED) { -g_message ("%s %s finalize %p", G_STRLOC, G_STRFUNC, (void*)o); if (!--n_notifiers) notify_uninit(); } @@ -328,12 +288,9 @@ indicator_power_notifier_init (IndicatorPowerNotifier * self) INDICATOR_TYPE_POWER_NOTIFIER, IndicatorPowerNotifierPrivate); self->priv = p; -g_message ("%s %s init %p", G_STRLOC, G_STRFUNC, (void*)self); p->dbus_battery = dbus_battery_skeleton_new (); - /* FIXME: own the busname and export the skeleton */ - p->is_warning_binding = g_object_bind_property (self, IS_WARNING_NAME, p->dbus_battery, @@ -364,17 +321,17 @@ indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) properties[PROP_0] = NULL; - properties[PROP_DEVICE_PROVIDER] = g_param_spec_object ( - DEVICE_PROVIDER_NAME, - "Device Provider", - "Source for power devices", + properties[PROP_BATTERY] = g_param_spec_object ( + BATTERY_NAME, + "Battery", + "The current battery", G_TYPE_OBJECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); properties[PROP_POWER_LEVEL] = g_param_spec_int ( POWER_LEVEL_NAME, "Power Level", - "Power Level of the batteries", + "The battery's power level", POWER_LEVEL_OK, POWER_LEVEL_CRITICAL, POWER_LEVEL_OK, @@ -397,50 +354,65 @@ indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) IndicatorPowerNotifier * indicator_power_notifier_new (IndicatorPowerDeviceProvider * device_provider) { - GObject * o = g_object_new (INDICATOR_TYPE_POWER_NOTIFIER, - DEVICE_PROVIDER_NAME, device_provider, - NULL); + GObject * o = g_object_new (INDICATOR_TYPE_POWER_NOTIFIER, NULL); return INDICATOR_POWER_NOTIFIER (o); } void -indicator_power_notifier_set_device_provider(IndicatorPowerNotifier * self, - IndicatorPowerDeviceProvider * dp) +indicator_power_notifier_set_battery (IndicatorPowerNotifier * self, + IndicatorPowerDevice * battery) { priv_t * p; g_return_if_fail(INDICATOR_IS_POWER_NOTIFIER(self)); - g_return_if_fail(!dp || INDICATOR_IS_POWER_DEVICE_PROVIDER(dp)); - p = self->priv; + g_return_if_fail((battery == NULL) || INDICATOR_IS_POWER_DEVICE(battery)); + g_return_if_fail((battery == NULL) || (indicator_power_device_get_kind(battery) == UP_DEVICE_KIND_BATTERY)); - if (p->device_provider != NULL) + if (p->battery != NULL) { - g_signal_handlers_disconnect_by_data(p->device_provider, self); - g_clear_object(&p->device_provider); - g_clear_object(&p->battery); + g_clear_object (&p->battery); + set_power_level_property (self, POWER_LEVEL_OK); + notification_clear (self); } - if (dp != NULL) + if (battery != NULL) { - p->device_provider = g_object_ref(dp); + const PowerLevel power_level = get_power_level (battery); - g_signal_connect_swapped(p->device_provider, "devices-changed", - G_CALLBACK(on_devices_changed), self); + p->battery = g_object_ref(battery); - on_devices_changed(self); + if (p->power_level != power_level) + { + set_power_level_property (self, power_level); + + if ((power_level == POWER_LEVEL_OK) || + (indicator_power_device_get_state(battery) != UP_DEVICE_STATE_DISCHARGING)) + { + notification_clear (self); + } + else + { + notification_show (self); + } + } } } void indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, - GDBusConnection * bus) + GDBusConnection * bus) { priv_t * p; g_return_if_fail(INDICATOR_IS_POWER_NOTIFIER(self)); + g_return_if_fail((bus == NULL) || G_IS_DBUS_CONNECTION(bus)); + p = self->priv; + if (p->bus == bus) + return; + if (p->bus != NULL) { if (p->dbus_battery != NULL) diff --git a/src/notifier.h b/src/notifier.h index c224b29..2602171 100644 --- a/src/notifier.h +++ b/src/notifier.h @@ -24,7 +24,7 @@ #include #include /* GDBusConnection */ -#include "device-provider.h" +#include "device.h" G_BEGIN_DECLS @@ -37,6 +37,15 @@ typedef struct _IndicatorPowerNotifier IndicatorPowerNotifier; typedef struct _IndicatorPowerNotifierClass IndicatorPowerNotifierClass; typedef struct _IndicatorPowerNotifierPrivate IndicatorPowerNotifierPrivate; +typedef enum +{ + POWER_LEVEL_OK, + POWER_LEVEL_LOW, + POWER_LEVEL_VERY_LOW, + POWER_LEVEL_CRITICAL +} +PowerLevel; + /** * The Indicator Power Notifier. */ @@ -58,13 +67,13 @@ struct _IndicatorPowerNotifierClass GType indicator_power_notifier_get_type (void); -IndicatorPowerNotifier * indicator_power_notifier_new (IndicatorPowerDeviceProvider * provider); +IndicatorPowerNotifier * indicator_power_notifier_new (void); void indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, GDBusConnection * connection); -void indicator_power_notifier_set_device_provider (IndicatorPowerNotifier * self, - IndicatorPowerDeviceProvider * provider); +void indicator_power_notifier_set_device (IndicatorPowerNotifier * self, + IndicatorPowerDevice * provider); G_END_DECLS diff --git a/src/service.c b/src/service.c index d8f1371..1c1f8f7 100644 --- a/src/service.c +++ b/src/service.c @@ -926,6 +926,12 @@ on_devices_changed (IndicatorPowerService * self) g_clear_object (&p->primary_device); p->primary_device = indicator_power_service_choose_primary_device (p->devices); + /* update the notifier's battery */ + if ((p->primary_device != NULL) || (indicator_power_device_get_kind(p->primary_device) == UP_DEVICE_KIND_BATTERY)) + indicator_power_notifier_set_battery (p->primary_device); + else + indicator_power_notifier_set_battery (NULL); + /* update the battery-level action's state */ if (p->primary_device == NULL) battery_level = 0; @@ -1042,7 +1048,7 @@ indicator_power_service_init (IndicatorPowerService * self) p->settings = g_settings_new ("com.canonical.indicator.power"); - p->notifier = indicator_power_notifier_new (NULL); + p->notifier = indicator_power_notifier_new (); uscreen_proxy = uscreen_get_proxy(&brightness_params); if (uscreen_proxy != NULL) @@ -1145,8 +1151,6 @@ indicator_power_service_set_device_provider (IndicatorPowerService * self, on_devices_changed (self); } - - indicator_power_notifier_set_device_provider (p->notifier, dp); } /* If a device has multiple batteries and uses only one of them at a time, -- cgit v1.2.3 From 7b3b8a27aa6e0a9a10f6faec1cd13b10f5b2492a Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 21 Jul 2014 12:10:41 -0500 Subject: fix build issues --- src/notifier.c | 13 ++++++++----- src/notifier.h | 4 ++-- src/service.c | 6 +++--- 3 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src/service.c') diff --git a/src/notifier.c b/src/notifier.c index d32008f..1d9428c 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -17,7 +17,7 @@ * Charles Kerr */ -#include "dbus-battery-info.h" +#include "dbus-battery.h" #include "dbus-shared.h" #include "notifier.h" @@ -57,8 +57,6 @@ static int n_notifiers = 0; struct _IndicatorPowerNotifierPrivate { - IndicatorPowerDeviceProvider * device_provider; - /* The battery we're currently watching. This may be a physical battery or it may be a "merged" battery synthesized from multiple batteries present on the device. @@ -77,6 +75,9 @@ struct _IndicatorPowerNotifierPrivate typedef IndicatorPowerNotifierPrivate priv_t; +static void set_is_warning_property (IndicatorPowerNotifier*, gboolean is_warning); +static void set_power_level_property (IndicatorPowerNotifier*, PowerLevel power_level); + /*** **** Notifications ***/ @@ -262,7 +263,7 @@ my_dispose (GObject * o) indicator_power_notifier_set_bus (self, NULL); notification_clear (self); - indicator_power_notifier_set_device (self, NULL); + indicator_power_notifier_set_battery (self, NULL); g_clear_pointer (&p->power_level_binding, g_binding_unbind); g_clear_pointer (&p->is_warning_binding, g_binding_unbind); g_clear_object (&p->dbus_battery); @@ -352,7 +353,7 @@ indicator_power_notifier_class_init (IndicatorPowerNotifierClass * klass) ***/ IndicatorPowerNotifier * -indicator_power_notifier_new (IndicatorPowerDeviceProvider * device_provider) +indicator_power_notifier_new (void) { GObject * o = g_object_new (INDICATOR_TYPE_POWER_NOTIFIER, NULL); @@ -369,6 +370,8 @@ indicator_power_notifier_set_battery (IndicatorPowerNotifier * self, g_return_if_fail((battery == NULL) || INDICATOR_IS_POWER_DEVICE(battery)); g_return_if_fail((battery == NULL) || (indicator_power_device_get_kind(battery) == UP_DEVICE_KIND_BATTERY)); + p = self->priv; + if (p->battery != NULL) { g_clear_object (&p->battery); diff --git a/src/notifier.h b/src/notifier.h index 2602171..c1c5a1b 100644 --- a/src/notifier.h +++ b/src/notifier.h @@ -72,8 +72,8 @@ IndicatorPowerNotifier * indicator_power_notifier_new (void); void indicator_power_notifier_set_bus (IndicatorPowerNotifier * self, GDBusConnection * connection); -void indicator_power_notifier_set_device (IndicatorPowerNotifier * self, - IndicatorPowerDevice * provider); +void indicator_power_notifier_set_battery (IndicatorPowerNotifier * self, + IndicatorPowerDevice * battery); G_END_DECLS diff --git a/src/service.c b/src/service.c index 1c1f8f7..23cef84 100644 --- a/src/service.c +++ b/src/service.c @@ -927,10 +927,10 @@ on_devices_changed (IndicatorPowerService * self) p->primary_device = indicator_power_service_choose_primary_device (p->devices); /* update the notifier's battery */ - if ((p->primary_device != NULL) || (indicator_power_device_get_kind(p->primary_device) == UP_DEVICE_KIND_BATTERY)) - indicator_power_notifier_set_battery (p->primary_device); + if ((p->primary_device != NULL) && (indicator_power_device_get_kind(p->primary_device) == UP_DEVICE_KIND_BATTERY)) + indicator_power_notifier_set_battery (p->notifier, p->primary_device); else - indicator_power_notifier_set_battery (NULL); + indicator_power_notifier_set_battery (p->notifier, NULL); /* update the battery-level action's state */ if (p->primary_device == NULL) -- cgit v1.2.3 From dd5f50b07bea7a5dec515a753cf66f060e1d79c6 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 22 Jul 2014 09:54:36 -0500 Subject: when a device changes, update the header action state even if the menus haven't been created yet. This fixes a startup condition found by the tests. --- src/service.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/service.c') diff --git a/src/service.c b/src/service.c index 23cef84..0cd448b 100644 --- a/src/service.c +++ b/src/service.c @@ -595,14 +595,14 @@ rebuild_now (IndicatorPowerService * self, guint sections) struct ProfileMenuInfo * desktop = &p->menus[PROFILE_DESKTOP]; struct ProfileMenuInfo * greeter = &p->menus[PROFILE_DESKTOP_GREETER]; - if (p->conn == NULL) /* we haven't built the menus yet */ - return; - if (sections & SECTION_HEADER) { g_simple_action_set_state (p->header_action, create_header_state (self)); } + if (p->conn == NULL) /* we haven't built the menus yet */ + return; + if (sections & SECTION_DEVICES) { rebuild_section (desktop->submenu, 0, create_desktop_devices_section (self, PROFILE_DESKTOP)); -- cgit v1.2.3