After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 700913 - Make GetPrimaryDevice always return the composite device, cleanups
Make GetPrimaryDevice always return the composite device, cleanups
Status: RESOLVED FIXED
Product: gnome-settings-daemon
Classification: Core
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: gnome-settings-daemon-maint
gnome-settings-daemon-maint
Depends on:
Blocks:
 
 
Reported: 2013-05-23 18:29 UTC by Jasper St. Pierre (not reading bugmail)
Modified: 2013-06-17 16:48 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
power: Make GetPrimaryDevice always return the composite device (5.05 KB, patch)
2013-05-23 18:29 UTC, Jasper St. Pierre (not reading bugmail)
needs-work Details | Review
power: Clean up code relating to the composite device (8.64 KB, patch)
2013-05-23 18:29 UTC, Jasper St. Pierre (not reading bugmail)
committed Details | Review
power: Ensure that we always have a composite device (5.65 KB, patch)
2013-06-10 18:54 UTC, Jasper St. Pierre (not reading bugmail)
committed Details | Review
power: Remove get_composite_device (4.07 KB, patch)
2013-06-10 18:54 UTC, Jasper St. Pierre (not reading bugmail)
committed Details | Review
power: Ensure that the composite device only represent battery devices (3.38 KB, patch)
2013-06-10 18:54 UTC, Jasper St. Pierre (not reading bugmail)
committed Details | Review
power: Use is-present to mark whether the composite device is relevant (2.09 KB, patch)
2013-06-10 18:54 UTC, Jasper St. Pierre (not reading bugmail)
committed Details | Review
power: Make the Percentage property always reflect the composite device (2.15 KB, patch)
2013-06-10 18:54 UTC, Jasper St. Pierre (not reading bugmail)
committed Details | Review
power: Make GetPrimaryDevice always return the composite device (3.78 KB, patch)
2013-06-10 18:54 UTC, Jasper St. Pierre (not reading bugmail)
committed Details | Review
power: Update time_to_empty/time_to_full from the real batteries (2.21 KB, patch)
2013-06-14 16:47 UTC, Bastien Nocera
committed Details | Review

Description Jasper St. Pierre (not reading bugmail) 2013-05-23 18:29:26 UTC
Right now, the Power menu in the shell has a weird behavior. If you have
your power cord plugged in, we return an error from GetPrimaryDevice, so
the shell goes back to enumerating all batteries.

We probably shouldn't do this, and instead always return the composite
device from GetPrimaryDevice.
Comment 1 Jasper St. Pierre (not reading bugmail) 2013-05-23 18:29:28 UTC
Created attachment 245164 [details] [review]
power: Make GetPrimaryDevice always return the composite device

With one battery, the composite device should report what we want as
well, so this shouldn't see any major changes in most cases. The reason
this is wanted is so that when the device is charging or fully charged,
we'll get the composite device as well, rather than throwing an error.
Comment 2 Jasper St. Pierre (not reading bugmail) 2013-05-23 18:29:31 UTC
Created attachment 245165 [details] [review]
power: Clean up code relating to the composite device

A lot of code was trying to be generic about the kind of devices
the composite device would handle, when the surrounding code just
took batteries. Remove some of this genericism.
Comment 3 Bastien Nocera 2013-06-04 09:48:59 UTC
Review of attachment 245164 [details] [review]:

::: plugins/power/gsd-power-manager.c
@@ -795,3 @@
-        }
-
-        /* just use the original device if only one primary battery */

That particular change could probably be done separately from the engine_get_primary_device() removal. It should be innocuous enough.

@@ -1843,3 @@
-
-                /* not discharging */
-                if (state != UP_DEVICE_STATE_DISCHARGING)

From our discussion with Richard:
<hughsie> hadess, okay, the reason it was added was to avoid batteries not involved in any action, i.e. in a pending state
<hughsie> it might be more correct to do:
                 /* not charging or discharging */
                 if (state != UP_DEVICE_STATE_CHARGING &&
                     state != UP_DEVICE_STATE_DISCHARGING)
                         continue;
<hughsie> or
                 if (state == UP_DEVICE_STATE_PENDING_CHARGE ||
                     state == UP_DEVICE_STATE_PENDING_DISCHARGE)
                         continue;

You'd need to do the latter check in engine_update_composite_device().

@@ +3733,3 @@
         /* return object */
         if (g_strcmp0 (method_name, "GetPrimaryDevice") == 0) {
+                value = device_to_variant_blob (manager->priv->device_composite);

And if there are no batteries, the composite device contains nothing of interest, and you should return an error.

@@ +3741,3 @@
         /* return array */
         if (g_strcmp0 (method_name, "GetDevices") == 0) {
+                UpDevice *device;

The move of this declaration could be done in a separate patch, it's a small somewhat-related cleanup.
Comment 4 Bastien Nocera 2013-06-04 10:48:24 UTC
Review of attachment 245165 [details] [review]:

::: plugins/power/gsd-power-manager.c
@@ +529,3 @@
+                /* Doing it here as it could be a composite device */
+                g_object_get (device, "percentage", &percentage, NULL);
+                return percentage;

This function was already broken, and it's just as broken I think.

You'd return the percentage of battery for whatever the first battery would be. So if the first listed battery is a mouse battery, and not the laptop one, you'd return the battery percentage for that. Probably not what you want.

The code can be largely simplified by returning -1 if there's no UP_DEVICE_KIND_BATTERY, or the "percentage" property value if there is a laptop/ups battery. You should be able to use "is-present" to keep whether the composite device represents 0 or more devices.

Please split this change in a separate patch as well, as it shouldn't change the behaviour.

@@ +560,3 @@
 
+                if (kind != device_kind)
+                        continue;

The changes to engine_get_icon_priv() look fine but they can also be made separately.
Comment 5 Jasper St. Pierre (not reading bugmail) 2013-06-10 18:54:29 UTC
Created attachment 246434 [details] [review]
power: Ensure that we always have a composite device

In the scenario when we only have one battery, we short-circuit and
use that instead of creating a composite device. We want to always
expose the composite device as an API, so never do that.
Comment 6 Jasper St. Pierre (not reading bugmail) 2013-06-10 18:54:32 UTC
Created attachment 246435 [details] [review]
power: Remove get_composite_device

This was always a bit unnecessary, as it was only called with a
device kind of BATTERY.
Comment 7 Jasper St. Pierre (not reading bugmail) 2013-06-10 18:54:36 UTC
Created attachment 246436 [details] [review]
power: Ensure that the composite device only represent battery devices

The code before was a tad too generic..
Comment 8 Jasper St. Pierre (not reading bugmail) 2013-06-10 18:54:38 UTC
Created attachment 246437 [details] [review]
power: Use is-present to mark whether the composite device is relevant
Comment 9 Jasper St. Pierre (not reading bugmail) 2013-06-10 18:54:41 UTC
Created attachment 246438 [details] [review]
power: Make the Percentage property always reflect the composite device

And ensure that it returns -1 when we have no devices in the composite
device.
Comment 10 Jasper St. Pierre (not reading bugmail) 2013-06-10 18:54:44 UTC
Created attachment 246439 [details] [review]
power: Make GetPrimaryDevice always return the composite device

With one battery, the composite device should report what we want as
well, so this shouldn't see any major changes in most cases. The reason
this is wanted is so that when the device is charging or fully charged,
we'll get the composite device as well, rather than throwing an error.
Comment 11 Jasper St. Pierre (not reading bugmail) 2013-06-10 18:57:25 UTC
Comment on attachment 245165 [details] [review]
power: Clean up code relating to the composite device

Since you seemed to want patches split out, here's all the patches split out.

Review comments have been taken into account.
Comment 12 Bastien Nocera 2013-06-11 16:00:43 UTC
Review of attachment 246435 [details] [review]:

Looks good.
Comment 13 Bastien Nocera 2013-06-11 16:01:37 UTC
Review of attachment 246436 [details] [review]:

Looks good.
Comment 14 Bastien Nocera 2013-06-11 16:02:12 UTC
Review of attachment 246437 [details] [review]:

Looks good.
Comment 15 Bastien Nocera 2013-06-11 16:04:13 UTC
Review of attachment 246438 [details] [review]:

::: plugins/power/gsd-power-manager.c
@@ +518,3 @@
+        if (is_present)
+                return percentage;
+        else

You can remove the "else" here, as you'll follow through.

@@ +519,3 @@
+                return percentage;
+        else
+                return -1;

I'd write "-1.0" to make sure it gets passed out as a double.
Comment 16 Bastien Nocera 2013-06-11 16:07:45 UTC
Review of attachment 246439 [details] [review]:

That looks fine, but I'd want some test cases for it.

test_action_multiple_batteries in plugins/power/test.py could do with checking the icon/percentage values for example.
Comment 17 Bastien Nocera 2013-06-11 16:09:19 UTC
Review of attachment 246434 [details] [review]:

That looks good, thanks.
Comment 18 Jasper St. Pierre (not reading bugmail) 2013-06-13 17:30:45 UTC
The tests fail when I run them:

g_dbus_connection_real_closed: Remote peer vanished with error: Underlying GIOStream returned 0 bytes on an async read (g-io-error-quark, 0). Exiting.

======================================================================
ERROR: test_action_critical_battery (__main__.PowerPluginTest)
action on critical battery
----------------------------------------------------------------------
Traceback (most recent call last):
  • File "./test.py", line 606 in test_action_critical_battery
    notify_log = self.p_notify.stdout.read()
IOError: [Errno 11] Resource temporarily unavailable

----------------------------------------------------------------------

Was this because of something I did?
Comment 19 Bastien Nocera 2013-06-14 16:47:28 UTC
(In reply to comment #18)
> The tests fail when I run them:

Yep, bisect says this broke it:
[4f5ec16c1287d963412ce8f5e0dc4de31290c1a4] power: Ensure that we always have a composite device

My guess is that we're relying on a property that didn't get copied/updated to the fake battery.
Comment 20 Bastien Nocera 2013-06-14 16:47:43 UTC
Created attachment 246829 [details] [review]
power: Update time_to_empty/time_to_full from the real batteries

So that we use upower's knowledge of that value instead of making
up our own. This fixes the test_action_critical_battery test failing.
Comment 21 Bastien Nocera 2013-06-14 16:49:52 UTC
(In reply to comment #20)
> Created an attachment (id=246829) [details] [review]
> power: Update time_to_empty/time_to_full from the real batteries
> 
> So that we use upower's knowledge of that value instead of making
> up our own. This fixes the test_action_critical_battery test failing.

Richard, why are we doing quick and dirty calculations of time-to-empty/time-to-full when creating a composite device, instead of adding those values from the different batteries?

Should we check n_batteries == 1 in those tests instead of time_to_full/time_to_empty being 0 in those conditionals?
Comment 22 Richard Hughes 2013-06-17 13:23:26 UTC
(In reply to comment #21)
> Richard, why are we doing quick and dirty calculations of
> time-to-empty/time-to-full when creating a composite device, instead of adding
> those values from the different batteries?

Most laptops with multiple batteries don't produce two sets of discharge values that always make sense. I think this was working around buggy firmware, and at least on my Lenovo T510 the batteries don't seem to produce discharge data for batteries in the pending state. I think that patch is probably okay.
Comment 23 Bastien Nocera 2013-06-17 13:44:52 UTC
I think that the problem is that the batteries discharge serially, not at the same time, in some cases, so you'd need to average time-to-empty based on the batteries' charges.

The patch needs a little work. If there's a buggy firmware though, the work-around to produce usable data should be in upower, or the kernel, not in gnome-settings-daemon (otherwise we'll have the exact same bug in gnome-control-center...).
Comment 24 Bastien Nocera 2013-06-17 16:47:20 UTC
After rebasing on top of a few more bug fixes.

Attachment 246434 [details] pushed as 3a9a004 - power: Ensure that we always have a composite device
Attachment 246435 [details] pushed as 5fd4b04 - power: Remove get_composite_device
Attachment 246436 [details] pushed as 67fd2e7 - power: Ensure that the composite device only represent battery devices
Attachment 246437 [details] pushed as 269c7f7 - power: Use is-present to mark whether the composite device is relevant
Attachment 246438 [details] pushed as c93c955 - power: Make the Percentage property always reflect the composite device
Attachment 246439 [details] pushed as eedfa80 - power: Make GetPrimaryDevice always return the composite device
Attachment 246829 [details] pushed as 6b463f7 - power: Update time_to_empty/time_to_full from the real batteries