Merge lp:~charlesk/indicator-power/lp-1075192 into lp:indicator-power/13.04

Proposed by Charles Kerr
Status: Merged
Approved by: Lars Karlitski
Approved revision: 158
Merged at revision: 153
Proposed branch: lp:~charlesk/indicator-power/lp-1075192
Merge into: lp:indicator-power/13.04
Diff against target: 139 lines (+60/-14)
3 files modified
src/device.c (+1/-1)
src/indicator-power.c (+42/-1)
tests/test-device.cc (+17/-12)
To merge this branch: bzr merge lp:~charlesk/indicator-power/lp-1075192
Reviewer Review Type Date Requested Status
Lars Karlitski (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+133139@code.launchpad.net

Commit message

Handle choosing a primary device when no device is charging nor discharging.

Description of the change

Handle choosing a primary device when no device is charging nor discharging.

Full description at https://bugs.launchpad.net/ubuntu/+source/indicator-power/+bug/1075192/comments/4

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

While this looks like a worthwhile fix in its own right, I'm not sure how this fixes bug 1075192.

(a) according to your explanation in comment 4 on the bug, I should experience the same problem -- but I am not able to reproduce this at all

(b) a label should *never* be displayed, no matter how the devices are sorted

(c) with this fix, the label would still appear when there's only line power available (although we don't show the indicator in that case)

review: Needs Information
Revision history for this message
Charles Kerr (charlesk) wrote :

> I'm not sure how this fixes bug 1075192.

Well, there are two parts to this bug -- the general case of the sorting, and the specific case of the AC Adapter's label. This patch fixes the first part, and since this should prevent an AC Adapter from ever being chosen as a primary device, the second part won't ever arise.

> (a) according to your explanation in comment 4 on the bug, I should experience the same problem -- but I am not able to reproduce this at all

Running i-power 12.10.4 on a laptop with a fully-charged battery should trigger the behavior. You can also mockup an equivalent configuration by hardwiring it in indicator_power_set_devices():

   + /* for testing only -- forcing a specific configuration */
   + devices = NULL;
   + devices = g_slist_append (devices, indicator_power_device_new (
   + "/org/freedesktop/UPower/devices/line_power_AC",
   + UP_DEVICE_KIND_LINE_POWER, 0, UP_DEVICE_STATE_UNKNOWN, 0));
   + devices = g_slist_append (devices, indicator_power_device_new (
   + "/org/freedesktop/UPower/devices/battery_BAT0",
   + UP_DEVICE_KIND_BATTERY, 100, UP_DEVICE_STATE_FULLY_CHARGED, 0));

> (b) a label should *never* be displayed, no matter how the devices are sorted

The AC Adapter is the only device where this happens, and with proper sorting we'll never choose that device as a primary.

Still, it's a fair point that the code should be correct.

I've added unit tests for this case in r157 and the fix in r158.

> (c) with this fix, the label would still appear when there's only line power available (although we don't show the indicator in that case)

This seems to be the same as (b)?

157. By Charles Kerr

modify DeviceTest.Labels s.t. it fails (currently failing) if the 'short' string for an AC Adapter is nonempty.

158. By Charles Kerr

change indicator_power_device_get_time_details() s.t. the 'short details' for an AC Adapter is an empty string.

Revision history for this message
Lars Karlitski (larsu) wrote :

> > I'm not sure how this fixes bug 1075192.
>
> Well, there are two parts to this bug -- the general case of the sorting, and
> the specific case of the AC Adapter's label. This patch fixes the first part,
> and since this should prevent an AC Adapter from ever being chosen as a
> primary device, the second part won't ever arise.

Got it. Makes me a little uneasy, though ;)

> > (a) according to your explanation in comment 4 on the bug, I should
> experience the same problem -- but I am not able to reproduce this at all
>
> Running i-power 12.10.4 on a laptop with a fully-charged battery should
> trigger the behavior. You can also mockup an equivalent configuration by
> hardwiring it in indicator_power_set_devices():
> [...]

... and it does. I wasn't running 12.10.4 before - sorry about that.

> > (b) a label should *never* be displayed, no matter how the devices are
> sorted
>
> The AC Adapter is the only device where this happens, and with proper sorting
> we'll never choose that device as a primary.
>
> Still, it's a fair point that the code should be correct.
>
> I've added unit tests for this case in r157 and the fix in r158.

Thanks! Makes me feel much less uneasy :)

> > (c) with this fix, the label would still appear when there's only line power
> available (although we don't show the indicator in that case)
>
> This seems to be the same as (b)?

The fix is the same, yes. I was just describing a different scenario when this might have turned up.

Thanks for the fixes!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/device.c'
2--- src/device.c 2012-10-26 08:53:51 +0000
3+++ src/device.c 2012-11-07 17:37:25 +0000
4@@ -612,7 +612,7 @@
5 {
6 *details = g_strdup (device_name);
7 *accessible_name = g_strdup (device_name);
8- *short_details = g_strdup (device_name);
9+ *short_details = g_strdup ("");
10 }
11 else
12 {
13
14=== modified file 'src/indicator-power.c'
15--- src/indicator-power.c 2012-10-29 10:59:09 +0000
16+++ src/indicator-power.c 2012-11-07 17:37:25 +0000
17@@ -352,12 +352,38 @@
18 gtk_widget_show_all (GTK_WIDGET (priv->menu));
19 }
20
21+/* the higher the weight, the more interesting the device */
22+static int
23+get_device_kind_weight (const IndicatorPowerDevice * device)
24+{
25+ UpDeviceKind kind;
26+ static gboolean initialized = FALSE;
27+ static int weights[UP_DEVICE_KIND_LAST];
28+
29+ kind = indicator_power_device_get_kind (device);
30+ g_return_val_if_fail (0<=kind && kind<UP_DEVICE_KIND_LAST, 0);
31+
32+ if (G_UNLIKELY(!initialized))
33+ {
34+ int i;
35+
36+ initialized = TRUE;
37+
38+ for (i=0; i<UP_DEVICE_KIND_LAST; i++)
39+ weights[i] = 1;
40+ weights[UP_DEVICE_KIND_BATTERY] = 2;
41+ weights[UP_DEVICE_KIND_LINE_POWER] = 0;
42+ }
43+
44+ return weights[kind];
45+}
46+
47 /* sort devices from most interesting to least interesting on this criteria:
48 1. discharging items from least time remaining until most time remaining
49 2. discharging items with an unknown time remaining
50 3. charging items from most time left to charge to least time left to charge
51 4. charging items with an unknown time remaining
52- 5. everything else */
53+ 5. batteries, then non-line power, then line-power */
54 static gint
55 device_compare_func (gconstpointer ga, gconstpointer gb)
56 {
57@@ -418,6 +444,21 @@
58 }
59 }
60
61+ if (!ret) /* neither device is charging nor discharging... */
62+ {
63+ const int weight_a = get_device_kind_weight (a);
64+ const int weight_b = get_device_kind_weight (b);
65+
66+ if (weight_a > weight_b)
67+ {
68+ ret = -1;
69+ }
70+ else if (weight_a < weight_b)
71+ {
72+ ret = 1;
73+ }
74+ }
75+
76 if (!ret)
77 ret = a_state - b_state;
78
79
80=== modified file 'tests/test-device.cc'
81--- tests/test-device.cc 2012-10-28 07:40:44 +0000
82+++ tests/test-device.cc 2012-11-07 17:37:25 +0000
83@@ -555,7 +555,7 @@
84 INDICATOR_POWER_DEVICE_PERCENTAGE, 0.0,
85 INDICATOR_POWER_DEVICE_TIME, guint64(0),
86 NULL);
87- check_strings (device, "AC Adapter", "AC Adapter", "AC Adapter");
88+ check_strings (device, "", "AC Adapter", "AC Adapter");
89
90 // cleanup
91 g_object_unref(o);
92@@ -587,19 +587,22 @@
93 sorted in order of preference wrt the spec's criteria.
94 So tests[i] should be picked over any test with an index greater than i */
95 struct {
96+ int kind;
97 int state;
98 guint64 time;
99 double percentage;
100 } tests[] = {
101- { UP_DEVICE_STATE_DISCHARGING, 49, 50.0 },
102- { UP_DEVICE_STATE_DISCHARGING, 50, 50.0 },
103- { UP_DEVICE_STATE_DISCHARGING, 50, 100.0 },
104- { UP_DEVICE_STATE_DISCHARGING, 51, 50.0 },
105- { UP_DEVICE_STATE_CHARGING, 50, 50.0 },
106- { UP_DEVICE_STATE_CHARGING, 49, 50.0 },
107- { UP_DEVICE_STATE_CHARGING, 49, 100.0 },
108- { UP_DEVICE_STATE_CHARGING, 48, 50.0 },
109- { UP_DEVICE_STATE_FULLY_CHARGED, 0, 50.0 }
110+ { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 49, 50.0 },
111+ { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 50, 50.0 },
112+ { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 50, 100.0 },
113+ { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 51, 50.0 },
114+ { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 50, 50.0 },
115+ { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 49, 50.0 },
116+ { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 49, 100.0 },
117+ { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 48, 50.0 },
118+ { UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_FULLY_CHARGED, 0, 50.0 },
119+ { UP_DEVICE_KIND_KEYBOARD, UP_DEVICE_STATE_FULLY_CHARGED, 0, 50.0 },
120+ { UP_DEVICE_KIND_LINE_POWER, UP_DEVICE_STATE_UNKNOWN, 0, 0.0 }
121 };
122
123 device_list = NULL;
124@@ -610,11 +613,13 @@
125 {
126 for (int j=i+1; j<n; j++)
127 {
128- g_object_set (a, INDICATOR_POWER_DEVICE_STATE, tests[i].state,
129+ g_object_set (a, INDICATOR_POWER_DEVICE_KIND, tests[i].kind,
130+ INDICATOR_POWER_DEVICE_STATE, tests[i].state,
131 INDICATOR_POWER_DEVICE_TIME, guint64(tests[i].time),
132 INDICATOR_POWER_DEVICE_PERCENTAGE, tests[i].percentage,
133 NULL);
134- g_object_set (b, INDICATOR_POWER_DEVICE_STATE, tests[j].state,
135+ g_object_set (b, INDICATOR_POWER_DEVICE_KIND, tests[j].kind,
136+ INDICATOR_POWER_DEVICE_STATE, tests[j].state,
137 INDICATOR_POWER_DEVICE_TIME, guint64(tests[j].time),
138 INDICATOR_POWER_DEVICE_PERCENTAGE, tests[j].percentage,
139 NULL);

Subscribers

People subscribed via source and target branches