Merge lp:~psusi/ubuntu/natty/gnome-power-manager/fix-duplicate-battery into lp:ubuntu/natty/gnome-power-manager
- Natty (11.04)
- fix-duplicate-battery
- Merge into natty
Proposed by
Phillip Susi
Status: | Merged |
---|---|
Merge reported by: | Phillip Susi |
Merged at revision: | not available |
Proposed branch: | lp:~psusi/ubuntu/natty/gnome-power-manager/fix-duplicate-battery |
Merge into: | lp:ubuntu/natty/gnome-power-manager |
Diff against target: |
1358 lines (+1308/-3) 6 files modified
.pc/16-fix-duplicate-battery.patch/src/gpm-engine.c (+1277/-0) .pc/applied-patches (+1/-0) debian/changelog (+8/-0) debian/patches/16-fix-duplicate-battery.patch (+20/-0) debian/patches/series (+2/-0) src/gpm-engine.c (+0/-3) |
To merge this branch: | bzr merge lp:~psusi/ubuntu/natty/gnome-power-manager/fix-duplicate-battery |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Marc Deslauriers | Approve | ||
Michele Damiano Torelli (community) | Approve | ||
Luke Yelavich | Pending | ||
Ubuntu branches | Pending | ||
Review via email: mp+67466@code.launchpad.net |
This proposal supersedes a proposal from 2011-06-26.
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Luke Yelavich (themuso) wrote : Posted in a previous version of this proposal | # |
review:
Needs Fixing
Revision history for this message
Michele Damiano Torelli (s3th) : | # |
review:
Approve
Revision history for this message
Marc Deslauriers (mdeslaur) wrote : | # |
This looks good. I've uploaded it to -proposed with a simple change to debian/changelog to use a better version number, and to specify the right pocket.
Thanks!
review:
Approve
Revision history for this message
Scott Moser (smoser) wrote : | # |
If you are able to, please mark this as Merged.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added directory '.pc/16-fix-duplicate-battery.patch' |
2 | === added file '.pc/16-fix-duplicate-battery.patch/.timestamp' |
3 | === added directory '.pc/16-fix-duplicate-battery.patch/src' |
4 | === added file '.pc/16-fix-duplicate-battery.patch/src/gpm-engine.c' |
5 | --- .pc/16-fix-duplicate-battery.patch/src/gpm-engine.c 1970-01-01 00:00:00 +0000 |
6 | +++ .pc/16-fix-duplicate-battery.patch/src/gpm-engine.c 2011-07-10 20:29:23 +0000 |
7 | @@ -0,0 +1,1277 @@ |
8 | +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- |
9 | + * |
10 | + * Copyright (C) 2007-2008 Richard Hughes <richard@hughsie.com> |
11 | + * |
12 | + * Licensed under the GNU General Public License Version 2 |
13 | + * |
14 | + * This program is free software; you can redistribute it and/or modify |
15 | + * it under the terms of the GNU General Public License as published by |
16 | + * the Free Software Foundation; either version 2 of the License, or |
17 | + * (at your option) any later version. |
18 | + * |
19 | + * This program is distributed in the hope that it will be useful, |
20 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
21 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22 | + * GNU General Public License for more details. |
23 | + * |
24 | + * You should have received a copy of the GNU General Public License |
25 | + * along with this program; if not, write to the Free Software |
26 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
27 | + */ |
28 | + |
29 | +#include "config.h" |
30 | + |
31 | +#include <string.h> |
32 | +#include <glib.h> |
33 | +#include <glib/gi18n.h> |
34 | +#include <gconf/gconf-client.h> |
35 | +#include <libupower-glib/upower.h> |
36 | + |
37 | +#include "egg-debug.h" |
38 | + |
39 | +#include "gpm-common.h" |
40 | +#include "gpm-upower.h" |
41 | +#include "gpm-marshal.h" |
42 | +#include "gpm-engine.h" |
43 | +#include "gpm-stock-icons.h" |
44 | +#include "gpm-prefs-server.h" |
45 | +#include "gpm-phone.h" |
46 | + |
47 | +static void gpm_engine_finalize (GObject *object); |
48 | + |
49 | +#define GPM_ENGINE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_ENGINE, GpmEnginePrivate)) |
50 | +#define GPM_ENGINE_RESUME_DELAY 2*1000 |
51 | +#define GPM_ENGINE_WARN_ACCURACY 20 |
52 | + |
53 | +struct GpmEnginePrivate |
54 | +{ |
55 | + GConfClient *conf; |
56 | + UpClient *client; |
57 | + UpDevice *battery_composite; |
58 | + GPtrArray *array; |
59 | + GpmPhone *phone; |
60 | + GpmIconPolicy icon_policy; |
61 | + gchar *previous_icon; |
62 | + gchar *previous_summary; |
63 | + |
64 | + gboolean use_time_primary; |
65 | + gboolean time_is_accurate; |
66 | + |
67 | + guint low_percentage; |
68 | + guint critical_percentage; |
69 | + guint action_percentage; |
70 | + guint low_time; |
71 | + guint critical_time; |
72 | + guint action_time; |
73 | +}; |
74 | + |
75 | +enum { |
76 | + ICON_CHANGED, |
77 | + SUMMARY_CHANGED, |
78 | + FULLY_CHARGED, |
79 | + CHARGE_LOW, |
80 | + CHARGE_CRITICAL, |
81 | + CHARGE_ACTION, |
82 | + DISCHARGING, |
83 | + LOW_CAPACITY, |
84 | + PERHAPS_RECALL, |
85 | + DEVICES_CHANGED, |
86 | + LAST_SIGNAL |
87 | +}; |
88 | + |
89 | +static guint signals [LAST_SIGNAL] = { 0 }; |
90 | +static gpointer gpm_engine_object = NULL; |
91 | + |
92 | +G_DEFINE_TYPE (GpmEngine, gpm_engine, G_TYPE_OBJECT) |
93 | + |
94 | +static UpDevice *gpm_engine_get_composite_device (GpmEngine *engine, UpDevice *original_device); |
95 | +static UpDevice *gpm_engine_update_composite_device (GpmEngine *engine, UpDevice *original_device); |
96 | + |
97 | +typedef enum { |
98 | + GPM_ENGINE_WARNING_NONE = 0, |
99 | + GPM_ENGINE_WARNING_DISCHARGING = 1, |
100 | + GPM_ENGINE_WARNING_LOW = 2, |
101 | + GPM_ENGINE_WARNING_CRITICAL = 3, |
102 | + GPM_ENGINE_WARNING_ACTION = 4 |
103 | +} GpmEngineWarning; |
104 | + |
105 | +/** |
106 | + * gpm_engine_get_warning_csr: |
107 | + **/ |
108 | +static GpmEngineWarning |
109 | +gpm_engine_get_warning_csr (GpmEngine *engine, UpDevice *device) |
110 | +{ |
111 | + gdouble percentage; |
112 | + |
113 | + /* get device properties */ |
114 | + g_object_get (device, "percentage", &percentage, NULL); |
115 | + |
116 | + if (percentage < 26.0f) |
117 | + return GPM_ENGINE_WARNING_LOW; |
118 | + else if (percentage < 13.0f) |
119 | + return GPM_ENGINE_WARNING_CRITICAL; |
120 | + return GPM_ENGINE_WARNING_NONE; |
121 | +} |
122 | + |
123 | +/** |
124 | + * gpm_engine_get_warning_percentage: |
125 | + **/ |
126 | +static GpmEngineWarning |
127 | +gpm_engine_get_warning_percentage (GpmEngine *engine, UpDevice *device) |
128 | +{ |
129 | + gdouble percentage; |
130 | + |
131 | + /* get device properties */ |
132 | + g_object_get (device, "percentage", &percentage, NULL); |
133 | + |
134 | + if (percentage <= engine->priv->action_percentage) |
135 | + return GPM_ENGINE_WARNING_ACTION; |
136 | + if (percentage <= engine->priv->critical_percentage) |
137 | + return GPM_ENGINE_WARNING_CRITICAL; |
138 | + if (percentage <= engine->priv->low_percentage) |
139 | + return GPM_ENGINE_WARNING_LOW; |
140 | + return GPM_ENGINE_WARNING_NONE; |
141 | +} |
142 | + |
143 | +/** |
144 | + * gpm_engine_get_warning_time: |
145 | + **/ |
146 | +static GpmEngineWarning |
147 | +gpm_engine_get_warning_time (GpmEngine *engine, UpDevice *device) |
148 | +{ |
149 | + UpDeviceKind kind; |
150 | + gint64 time_to_empty; |
151 | + |
152 | + /* get device properties */ |
153 | + g_object_get (device, |
154 | + "kind", &kind, |
155 | + "time-to-empty", &time_to_empty, |
156 | + NULL); |
157 | + |
158 | + /* this is probably an error condition */ |
159 | + if (time_to_empty == 0) { |
160 | + egg_debug ("time zero, falling back to percentage for %s", up_device_kind_to_string (kind)); |
161 | + return gpm_engine_get_warning_percentage (engine, device); |
162 | + } |
163 | + |
164 | + if (time_to_empty <= engine->priv->action_time) |
165 | + return GPM_ENGINE_WARNING_ACTION; |
166 | + if (time_to_empty <= engine->priv->critical_time) |
167 | + return GPM_ENGINE_WARNING_CRITICAL; |
168 | + if (time_to_empty <= engine->priv->low_time) |
169 | + return GPM_ENGINE_WARNING_LOW; |
170 | + return GPM_ENGINE_WARNING_NONE; |
171 | +} |
172 | + |
173 | +/** |
174 | + * gpm_engine_get_warning: |
175 | + * |
176 | + * This gets the possible engine state for the device according to the |
177 | + * policy, which could be per-percent, or per-time. |
178 | + * |
179 | + * Return value: A GpmEngine state, e.g. GPM_ENGINE_WARNING_DISCHARGING |
180 | + **/ |
181 | +static GpmEngineWarning |
182 | +gpm_engine_get_warning (GpmEngine *engine, UpDevice *device) |
183 | +{ |
184 | + UpDeviceKind kind; |
185 | + UpDeviceState state; |
186 | + GpmEngineWarning warning_type; |
187 | + |
188 | + /* get device properties */ |
189 | + g_object_get (device, |
190 | + "kind", &kind, |
191 | + "state", &state, |
192 | + NULL); |
193 | + |
194 | + /* default to no engine */ |
195 | + warning_type = GPM_ENGINE_WARNING_NONE; |
196 | + |
197 | + /* if the device in question is on ac, don't give a warning */ |
198 | + if (state == UP_DEVICE_STATE_CHARGING) |
199 | + goto out; |
200 | + |
201 | + if (kind == UP_DEVICE_KIND_MOUSE || |
202 | + kind == UP_DEVICE_KIND_KEYBOARD) { |
203 | + |
204 | + warning_type = gpm_engine_get_warning_csr (engine, device); |
205 | + |
206 | + } else if (kind == UP_DEVICE_KIND_UPS || |
207 | +#if UP_CHECK_VERSION(0,9,5) |
208 | + kind == UP_DEVICE_KIND_MEDIA_PLAYER || |
209 | + kind == UP_DEVICE_KIND_TABLET || |
210 | + kind == UP_DEVICE_KIND_COMPUTER || |
211 | +#endif |
212 | + kind == UP_DEVICE_KIND_PDA) { |
213 | + |
214 | + warning_type = gpm_engine_get_warning_percentage (engine, device); |
215 | + |
216 | + } else if (kind == UP_DEVICE_KIND_PHONE) { |
217 | + |
218 | + warning_type = gpm_engine_get_warning_percentage (engine, device); |
219 | + |
220 | + } else if (kind == UP_DEVICE_KIND_BATTERY) { |
221 | + /* only use the time when it is accurate, and GConf is not disabled */ |
222 | + if (engine->priv->use_time_primary) |
223 | + warning_type = gpm_engine_get_warning_time (engine, device); |
224 | + else |
225 | + warning_type = gpm_engine_get_warning_percentage (engine, device); |
226 | + } |
227 | + |
228 | + /* If we have no important engines, we should test for discharging */ |
229 | + if (warning_type == GPM_ENGINE_WARNING_NONE) { |
230 | + if (state == UP_DEVICE_STATE_DISCHARGING) |
231 | + warning_type = GPM_ENGINE_WARNING_DISCHARGING; |
232 | + } |
233 | + |
234 | + out: |
235 | + return warning_type; |
236 | +} |
237 | + |
238 | +/** |
239 | + * gpm_engine_get_summary: |
240 | + * @engine: This engine class instance |
241 | + * @string: The returned string |
242 | + * |
243 | + * Returns the complete tooltip ready for display |
244 | + **/ |
245 | +gchar * |
246 | +gpm_engine_get_summary (GpmEngine *engine) |
247 | +{ |
248 | + guint i; |
249 | + GPtrArray *array; |
250 | + UpDevice *device; |
251 | + UpDeviceState state; |
252 | + GString *tooltip = NULL; |
253 | + gchar *part; |
254 | + gboolean is_present; |
255 | + |
256 | + g_return_val_if_fail (GPM_IS_ENGINE (engine), NULL); |
257 | + |
258 | + /* need to get AC state */ |
259 | + tooltip = g_string_new (""); |
260 | + |
261 | + /* do we have specific device types? */ |
262 | + array = engine->priv->array; |
263 | + for (i=0;i<array->len;i++) { |
264 | + device = g_ptr_array_index (engine->priv->array, i); |
265 | + g_object_get (device, |
266 | + "is-present", &is_present, |
267 | + "state", &state, |
268 | + NULL); |
269 | + if (!is_present) |
270 | + continue; |
271 | + if (state == UP_DEVICE_STATE_EMPTY) |
272 | + continue; |
273 | + part = gpm_upower_get_device_summary (device); |
274 | + if (part != NULL) |
275 | + g_string_append_printf (tooltip, "%s\n", part); |
276 | + g_free (part); |
277 | + } |
278 | + |
279 | + /* remove the last \n */ |
280 | + g_string_truncate (tooltip, tooltip->len-1); |
281 | + |
282 | + egg_debug ("tooltip: %s", tooltip->str); |
283 | + |
284 | + return g_string_free (tooltip, FALSE); |
285 | +} |
286 | + |
287 | +/** |
288 | + * gpm_engine_get_icon_priv: |
289 | + * |
290 | + * Returns the icon |
291 | + **/ |
292 | +static gchar * |
293 | +gpm_engine_get_icon_priv (GpmEngine *engine, UpDeviceKind device_kind, GpmEngineWarning warning, gboolean use_state) |
294 | +{ |
295 | + guint i; |
296 | + GPtrArray *array; |
297 | + UpDevice *device; |
298 | + GpmEngineWarning warning_temp; |
299 | + UpDeviceKind kind; |
300 | + UpDeviceState state; |
301 | + gboolean is_present; |
302 | + |
303 | + /* do we have specific device types? */ |
304 | + array = engine->priv->array; |
305 | + for (i=0;i<array->len;i++) { |
306 | + device = g_ptr_array_index (engine->priv->array, i); |
307 | + |
308 | + /* get device properties */ |
309 | + g_object_get (device, |
310 | + "kind", &kind, |
311 | + "state", &state, |
312 | + "is-present", &is_present, |
313 | + NULL); |
314 | + |
315 | + /* if battery then use composite device to cope with multiple batteries */ |
316 | + if (kind == UP_DEVICE_KIND_BATTERY) |
317 | + device = gpm_engine_get_composite_device (engine, device); |
318 | + |
319 | + warning_temp = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(device), "engine-warning-old")); |
320 | + if (kind == device_kind && is_present) { |
321 | + if (warning != GPM_ENGINE_WARNING_NONE) { |
322 | + if (warning_temp == warning) |
323 | + return gpm_upower_get_device_icon (device); |
324 | + continue; |
325 | + } |
326 | + if (use_state) { |
327 | + if (state == UP_DEVICE_STATE_CHARGING || state == UP_DEVICE_STATE_DISCHARGING) |
328 | + return gpm_upower_get_device_icon (device); |
329 | + continue; |
330 | + } |
331 | + return gpm_upower_get_device_icon (device); |
332 | + } |
333 | + } |
334 | + return NULL; |
335 | +} |
336 | + |
337 | +/** |
338 | + * gpm_engine_get_icon: |
339 | + * |
340 | + * Returns the icon |
341 | + **/ |
342 | +gchar * |
343 | +gpm_engine_get_icon (GpmEngine *engine) |
344 | +{ |
345 | + gchar *icon = NULL; |
346 | + |
347 | + g_return_val_if_fail (GPM_IS_ENGINE (engine), NULL); |
348 | + |
349 | + /* policy */ |
350 | + if (engine->priv->icon_policy == GPM_ICON_POLICY_NEVER) { |
351 | + egg_debug ("no icon allowed, so no icon will be displayed."); |
352 | + return NULL; |
353 | + } |
354 | + |
355 | + /* we try CRITICAL: BATTERY, UPS, MOUSE, KEYBOARD */ |
356 | + icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_BATTERY, GPM_ENGINE_WARNING_CRITICAL, FALSE); |
357 | + if (icon != NULL) |
358 | + return icon; |
359 | + icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_UPS, GPM_ENGINE_WARNING_CRITICAL, FALSE); |
360 | + if (icon != NULL) |
361 | + return icon; |
362 | + icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_MOUSE, GPM_ENGINE_WARNING_CRITICAL, FALSE); |
363 | + if (icon != NULL) |
364 | + return icon; |
365 | + icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_KEYBOARD, GPM_ENGINE_WARNING_CRITICAL, FALSE); |
366 | + if (icon != NULL) |
367 | + return icon; |
368 | + |
369 | + /* policy */ |
370 | + if (engine->priv->icon_policy == GPM_ICON_POLICY_CRITICAL) { |
371 | + egg_debug ("no devices critical, so no icon will be displayed."); |
372 | + return NULL; |
373 | + } |
374 | + |
375 | + /* we try CRITICAL: BATTERY, UPS, MOUSE, KEYBOARD */ |
376 | + icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_BATTERY, GPM_ENGINE_WARNING_LOW, FALSE); |
377 | + if (icon != NULL) |
378 | + return icon; |
379 | + icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_UPS, GPM_ENGINE_WARNING_LOW, FALSE); |
380 | + if (icon != NULL) |
381 | + return icon; |
382 | + icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_MOUSE, GPM_ENGINE_WARNING_LOW, FALSE); |
383 | + if (icon != NULL) |
384 | + return icon; |
385 | + icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_KEYBOARD, GPM_ENGINE_WARNING_LOW, FALSE); |
386 | + if (icon != NULL) |
387 | + return icon; |
388 | + |
389 | + /* policy */ |
390 | + if (engine->priv->icon_policy == GPM_ICON_POLICY_LOW) { |
391 | + egg_debug ("no devices low, so no icon will be displayed."); |
392 | + return NULL; |
393 | + } |
394 | + |
395 | + /* we try (DIS)CHARGING: BATTERY, UPS */ |
396 | + icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_BATTERY, GPM_ENGINE_WARNING_NONE, TRUE); |
397 | + if (icon != NULL) |
398 | + return icon; |
399 | + icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_UPS, GPM_ENGINE_WARNING_NONE, TRUE); |
400 | + if (icon != NULL) |
401 | + return icon; |
402 | + |
403 | + /* policy */ |
404 | + if (engine->priv->icon_policy == GPM_ICON_POLICY_CHARGE) { |
405 | + egg_debug ("no devices (dis)charging, so no icon will be displayed."); |
406 | + return NULL; |
407 | + } |
408 | + |
409 | + /* we try PRESENT: BATTERY, UPS */ |
410 | + icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_BATTERY, GPM_ENGINE_WARNING_NONE, FALSE); |
411 | + if (icon != NULL) |
412 | + return icon; |
413 | + icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_UPS, GPM_ENGINE_WARNING_NONE, FALSE); |
414 | + if (icon != NULL) |
415 | + return icon; |
416 | + |
417 | + /* policy */ |
418 | + if (engine->priv->icon_policy == GPM_ICON_POLICY_PRESENT) { |
419 | + egg_debug ("no devices present, so no icon will be displayed."); |
420 | + return NULL; |
421 | + } |
422 | + |
423 | + /* we fallback to the ac_adapter icon */ |
424 | + egg_debug ("Using fallback"); |
425 | + return g_strdup (GPM_STOCK_AC_ADAPTER); |
426 | +} |
427 | + |
428 | +/** |
429 | + * gpm_engine_recalculate_state_icon: |
430 | + */ |
431 | +static gboolean |
432 | +gpm_engine_recalculate_state_icon (GpmEngine *engine) |
433 | +{ |
434 | + gchar *icon; |
435 | + |
436 | + g_return_val_if_fail (engine != NULL, FALSE); |
437 | + g_return_val_if_fail (GPM_IS_ENGINE (engine), FALSE); |
438 | + |
439 | + /* show a different icon if we are disconnected */ |
440 | + icon = gpm_engine_get_icon (engine); |
441 | + if (icon == NULL) { |
442 | + /* none before, now none */ |
443 | + if (engine->priv->previous_icon == NULL) |
444 | + return FALSE; |
445 | + /* icon before, now none */ |
446 | + egg_debug ("** EMIT: icon-changed: none"); |
447 | + g_signal_emit (engine, signals [ICON_CHANGED], 0, NULL); |
448 | + |
449 | + g_free (engine->priv->previous_icon); |
450 | + engine->priv->previous_icon = NULL; |
451 | + return TRUE; |
452 | + } |
453 | + |
454 | + /* no icon before, now icon */ |
455 | + if (engine->priv->previous_icon == NULL) { |
456 | + egg_debug ("** EMIT: icon-changed: %s", icon); |
457 | + g_signal_emit (engine, signals [ICON_CHANGED], 0, icon); |
458 | + engine->priv->previous_icon = icon; |
459 | + return TRUE; |
460 | + } |
461 | + |
462 | + /* icon before, now different */ |
463 | + if (strcmp (engine->priv->previous_icon, icon) != 0) { |
464 | + g_free (engine->priv->previous_icon); |
465 | + engine->priv->previous_icon = icon; |
466 | + egg_debug ("** EMIT: icon-changed: %s", icon); |
467 | + g_signal_emit (engine, signals [ICON_CHANGED], 0, icon); |
468 | + return TRUE; |
469 | + } |
470 | + |
471 | + egg_debug ("no change"); |
472 | + /* nothing to do */ |
473 | + g_free (icon); |
474 | + return FALSE; |
475 | +} |
476 | + |
477 | +/** |
478 | + * gpm_engine_recalculate_state_summary: |
479 | + */ |
480 | +static gboolean |
481 | +gpm_engine_recalculate_state_summary (GpmEngine *engine) |
482 | +{ |
483 | + gchar *summary; |
484 | + |
485 | + summary = gpm_engine_get_summary (engine); |
486 | + if (engine->priv->previous_summary == NULL) { |
487 | + engine->priv->previous_summary = summary; |
488 | + egg_debug ("** EMIT: summary-changed(1): %s", summary); |
489 | + g_signal_emit (engine, signals [SUMMARY_CHANGED], 0, summary); |
490 | + return TRUE; |
491 | + } |
492 | + |
493 | + if (strcmp (engine->priv->previous_summary, summary) != 0) { |
494 | + g_free (engine->priv->previous_summary); |
495 | + engine->priv->previous_summary = summary; |
496 | + egg_debug ("** EMIT: summary-changed(2): %s", summary); |
497 | + g_signal_emit (engine, signals [SUMMARY_CHANGED], 0, summary); |
498 | + return TRUE; |
499 | + } |
500 | + egg_debug ("no change"); |
501 | + /* nothing to do */ |
502 | + g_free (summary); |
503 | + return FALSE; |
504 | +} |
505 | + |
506 | +/** |
507 | + * gpm_engine_recalculate_state: |
508 | + */ |
509 | +static void |
510 | +gpm_engine_recalculate_state (GpmEngine *engine) |
511 | +{ |
512 | + |
513 | + g_return_if_fail (engine != NULL); |
514 | + g_return_if_fail (GPM_IS_ENGINE (engine)); |
515 | + |
516 | + gpm_engine_recalculate_state_icon (engine); |
517 | + gpm_engine_recalculate_state_summary (engine); |
518 | + |
519 | + g_signal_emit (engine, signals [DEVICES_CHANGED], 0); |
520 | +} |
521 | + |
522 | +/** |
523 | + * gpm_engine_conf_key_changed_cb: |
524 | + **/ |
525 | +static void |
526 | +gpm_engine_conf_key_changed_cb (GConfClient *conf, guint cnxn_id, GConfEntry *entry, GpmEngine *engine) |
527 | +{ |
528 | + GConfValue *value; |
529 | + gchar *icon_policy; |
530 | + |
531 | + if (entry == NULL) |
532 | + return; |
533 | + value = gconf_entry_get_value (entry); |
534 | + if (value == NULL) |
535 | + return; |
536 | + |
537 | + if (strcmp (entry->key, GPM_CONF_USE_TIME_POLICY) == 0) { |
538 | + |
539 | + engine->priv->use_time_primary = gconf_value_get_bool (value); |
540 | + |
541 | + } else if (strcmp (entry->key, GPM_CONF_UI_ICON_POLICY) == 0) { |
542 | + |
543 | + /* do we want to display the icon in the tray */ |
544 | + icon_policy = gconf_client_get_string (conf, GPM_CONF_UI_ICON_POLICY, NULL); |
545 | + engine->priv->icon_policy = gpm_icon_policy_from_string (icon_policy); |
546 | + g_free (icon_policy); |
547 | + |
548 | + /* perhaps change icon */ |
549 | + gpm_engine_recalculate_state_icon (engine); |
550 | + } |
551 | +} |
552 | + |
553 | +/** |
554 | + * gpm_engine_device_check_capacity: |
555 | + **/ |
556 | +static gboolean |
557 | +gpm_engine_device_check_capacity (GpmEngine *engine, UpDevice *device) |
558 | +{ |
559 | + gboolean ret; |
560 | + UpDeviceKind kind; |
561 | + gdouble capacity; |
562 | + |
563 | + /* get device properties */ |
564 | + g_object_get (device, |
565 | + "kind", &kind, |
566 | + "capacity", &capacity, |
567 | + NULL); |
568 | + |
569 | + /* not laptop battery */ |
570 | + if (kind != UP_DEVICE_KIND_BATTERY) |
571 | + return FALSE; |
572 | + |
573 | + /* capacity okay */ |
574 | + if (capacity > 50.0f) |
575 | + return FALSE; |
576 | + |
577 | + /* capacity invalid */ |
578 | + if (capacity < 1.0f) |
579 | + return FALSE; |
580 | + |
581 | + /* only emit this if specified in gconf */ |
582 | + ret = gconf_client_get_bool (engine->priv->conf, GPM_CONF_NOTIFY_LOW_CAPACITY, NULL); |
583 | + if (ret) { |
584 | + egg_debug ("** EMIT: low-capacity"); |
585 | + g_signal_emit (engine, signals [LOW_CAPACITY], 0, device); |
586 | + } |
587 | + return TRUE; |
588 | +} |
589 | + |
590 | +/** |
591 | + * gpm_engine_get_composite_device: |
592 | + **/ |
593 | +static UpDevice * |
594 | +gpm_engine_get_composite_device (GpmEngine *engine, UpDevice *original_device) |
595 | +{ |
596 | + guint battery_devices = 0; |
597 | + GPtrArray *array; |
598 | + UpDevice *device; |
599 | + UpDeviceKind kind; |
600 | + guint i; |
601 | + |
602 | + /* find out how many batteries in the system */ |
603 | + array = engine->priv->array; |
604 | + for (i=0;i<array->len;i++) { |
605 | + device = g_ptr_array_index (engine->priv->array, i); |
606 | + g_object_get (device, |
607 | + "kind", &kind, |
608 | + NULL); |
609 | + if (kind == UP_DEVICE_KIND_BATTERY) |
610 | + battery_devices++; |
611 | + } |
612 | + |
613 | + /* just use the original device if only one primary battery */ |
614 | + if (battery_devices <= 1) { |
615 | + egg_debug ("using original device as only one primary battery"); |
616 | + device = original_device; |
617 | + goto out; |
618 | + } |
619 | + |
620 | + /* use the composite device */ |
621 | + device = engine->priv->battery_composite; |
622 | +out: |
623 | + /* return composite device or original device */ |
624 | + return device; |
625 | +} |
626 | + |
627 | +/** |
628 | + * gpm_engine_update_composite_device: |
629 | + **/ |
630 | +static UpDevice * |
631 | +gpm_engine_update_composite_device (GpmEngine *engine, UpDevice *original_device) |
632 | +{ |
633 | + guint i; |
634 | + gdouble percentage = 0.0; |
635 | + gdouble energy = 0.0; |
636 | + gdouble energy_full = 0.0; |
637 | + gdouble energy_rate = 0.0; |
638 | + gdouble energy_total = 0.0; |
639 | + gdouble energy_full_total = 0.0; |
640 | + gdouble energy_rate_total = 0.0; |
641 | + gint64 time_to_empty = 0; |
642 | + gint64 time_to_full = 0; |
643 | + guint battery_devices = 0; |
644 | + gboolean is_charging = FALSE; |
645 | + gboolean is_discharging = FALSE; |
646 | + gboolean is_fully_charged = TRUE; |
647 | + GPtrArray *array; |
648 | + UpDevice *device; |
649 | + UpDeviceState state; |
650 | + UpDeviceKind kind; |
651 | + gboolean debug; |
652 | + gchar *text; |
653 | + |
654 | + /* are we printing to console? */ |
655 | + debug = egg_debug_enabled (); |
656 | + |
657 | + /* update the composite device */ |
658 | + array = engine->priv->array; |
659 | + for (i=0;i<array->len;i++) { |
660 | + device = g_ptr_array_index (engine->priv->array, i); |
661 | + g_object_get (device, |
662 | + "kind", &kind, |
663 | + "state", &state, |
664 | + "energy", &energy, |
665 | + "energy-full", &energy_full, |
666 | + "energy-rate", &energy_rate, |
667 | + NULL); |
668 | + if (kind != UP_DEVICE_KIND_BATTERY) |
669 | + continue; |
670 | + |
671 | + if (debug) { |
672 | + text = up_device_to_text (device); |
673 | + egg_debug ("printing device %i:\n%s", i, text); |
674 | + g_free (text); |
675 | + } |
676 | + |
677 | + /* one of these will be charging or discharging */ |
678 | + if (state == UP_DEVICE_STATE_CHARGING) |
679 | + is_charging = TRUE; |
680 | + if (state == UP_DEVICE_STATE_DISCHARGING) |
681 | + is_discharging = TRUE; |
682 | + if (state != UP_DEVICE_STATE_FULLY_CHARGED) |
683 | + is_fully_charged = FALSE; |
684 | + |
685 | + /* sum up composite */ |
686 | + energy_total += energy; |
687 | + energy_full_total += energy_full; |
688 | + energy_rate_total += energy_rate; |
689 | + battery_devices++; |
690 | + } |
691 | + |
692 | + /* just use the original device if only one primary battery */ |
693 | + if (battery_devices == 1) { |
694 | + egg_debug ("using original device as only one primary battery"); |
695 | + device = original_device; |
696 | + goto out; |
697 | + } |
698 | + |
699 | + /* use percentage weighted for each battery capacity */ |
700 | + percentage = 100.0 * energy_total / energy_full_total; |
701 | + |
702 | + /* set composite state */ |
703 | + if (is_charging) |
704 | + state = UP_DEVICE_STATE_CHARGING; |
705 | + else if (is_discharging) |
706 | + state = UP_DEVICE_STATE_DISCHARGING; |
707 | + else if (is_fully_charged) |
708 | + state = UP_DEVICE_STATE_FULLY_CHARGED; |
709 | + else |
710 | + state = UP_DEVICE_STATE_UNKNOWN; |
711 | + |
712 | + /* calculate a quick and dirty time remaining value */ |
713 | + if (energy_rate_total > 0) { |
714 | + if (state == UP_DEVICE_STATE_DISCHARGING) |
715 | + time_to_empty = 3600 * (energy_total / energy_rate_total); |
716 | + else if (state == UP_DEVICE_STATE_CHARGING) |
717 | + time_to_full = 3600 * ((energy_full_total - energy_total) / energy_rate_total); |
718 | + } |
719 | + |
720 | + /* okay, we can use the composite device */ |
721 | + device = engine->priv->battery_composite; |
722 | + |
723 | + egg_debug ("printing composite device"); |
724 | + g_object_set (device, |
725 | + "energy", energy, |
726 | + "energy-full", energy_full, |
727 | + "energy-rate", energy_rate, |
728 | + "time-to-empty", time_to_empty, |
729 | + "time-to-full", time_to_full, |
730 | + "percentage", percentage, |
731 | + "state", state, |
732 | + NULL); |
733 | + if (debug) { |
734 | + text = up_device_to_text (device); |
735 | + egg_debug ("composite:\n%s", text); |
736 | + g_free (text); |
737 | + } |
738 | + |
739 | + /* force update of icon */ |
740 | + gpm_engine_recalculate_state_icon (engine); |
741 | +out: |
742 | + /* return composite device or original device */ |
743 | + return device; |
744 | +} |
745 | + |
746 | +/** |
747 | + * gpm_engine_device_add: |
748 | + **/ |
749 | +static void |
750 | +gpm_engine_device_add (GpmEngine *engine, UpDevice *device) |
751 | +{ |
752 | + GpmEngineWarning warning; |
753 | + UpDeviceState state; |
754 | + UpDeviceKind kind; |
755 | + UpDevice *composite; |
756 | + |
757 | + /* assign warning */ |
758 | + warning = gpm_engine_get_warning (engine, device); |
759 | + g_object_set_data (G_OBJECT(device), "engine-warning-old", GUINT_TO_POINTER(warning)); |
760 | + |
761 | + /* check capacity */ |
762 | + gpm_engine_device_check_capacity (engine, device); |
763 | + |
764 | + /* get device properties */ |
765 | + g_object_get (device, |
766 | + "kind", &kind, |
767 | + "state", &state, |
768 | + NULL); |
769 | + |
770 | + /* add old state for transitions */ |
771 | + egg_debug ("adding %s with state %s", up_device_get_object_path (device), up_device_state_to_string (state)); |
772 | + g_object_set_data (G_OBJECT(device), "engine-state-old", GUINT_TO_POINTER(state)); |
773 | + |
774 | + if (kind == UP_DEVICE_KIND_BATTERY) { |
775 | + egg_debug ("updating because we added a device"); |
776 | + composite = gpm_engine_update_composite_device (engine, device); |
777 | + |
778 | + /* get the same values for the composite device */ |
779 | + warning = gpm_engine_get_warning (engine, composite); |
780 | + g_object_set_data (G_OBJECT(composite), "engine-warning-old", GUINT_TO_POINTER(warning)); |
781 | + g_object_get (composite, "state", &state, NULL); |
782 | + g_object_set_data (G_OBJECT(composite), "engine-state-old", GUINT_TO_POINTER(state)); |
783 | + } |
784 | +} |
785 | + |
786 | +/** |
787 | + * gpm_engine_check_recall: |
788 | + **/ |
789 | +static gboolean |
790 | +gpm_engine_check_recall (GpmEngine *engine, UpDevice *device) |
791 | +{ |
792 | + UpDeviceKind kind; |
793 | + gboolean recall_notice = FALSE; |
794 | + gchar *recall_vendor = NULL; |
795 | + gchar *recall_url = NULL; |
796 | + |
797 | + /* get device properties */ |
798 | + g_object_get (device, |
799 | + "kind", &kind, |
800 | + "recall-notice", &recall_notice, |
801 | + "recall-vendor", &recall_vendor, |
802 | + "recall-url", &recall_url, |
803 | + NULL); |
804 | + |
805 | + /* not battery */ |
806 | + if (kind != UP_DEVICE_KIND_BATTERY) |
807 | + goto out; |
808 | + |
809 | + /* no recall data */ |
810 | + if (!recall_notice) |
811 | + goto out; |
812 | + |
813 | + /* emit signal for manager */ |
814 | + egg_debug ("** EMIT: perhaps-recall"); |
815 | + g_signal_emit (engine, signals [PERHAPS_RECALL], 0, device, recall_vendor, recall_url); |
816 | +out: |
817 | + g_free (recall_vendor); |
818 | + g_free (recall_url); |
819 | + return recall_notice; |
820 | +} |
821 | + |
822 | +/** |
823 | + * gpm_engine_coldplug_idle_cb: |
824 | + **/ |
825 | +static gboolean |
826 | +gpm_engine_coldplug_idle_cb (GpmEngine *engine) |
827 | +{ |
828 | + guint i; |
829 | + GPtrArray *array; |
830 | + gboolean has_battery = FALSE; |
831 | + gboolean has_ups = FALSE; |
832 | + GpmPrefsServer *prefs_server; |
833 | + UpDevice *device; |
834 | + UpDeviceKind kind; |
835 | + gboolean ret; |
836 | + GError *error = NULL; |
837 | + |
838 | + g_return_val_if_fail (engine != NULL, FALSE); |
839 | + g_return_val_if_fail (GPM_IS_ENGINE (engine), FALSE); |
840 | + |
841 | + /* get devices from UPower */ |
842 | + ret = up_client_enumerate_devices_sync (engine->priv->client, NULL, &error); |
843 | + if (!ret) { |
844 | + egg_error ("failed to get device list: %s", error->message); |
845 | + g_error_free (error); |
846 | + goto out; |
847 | + } |
848 | + engine->priv->array = up_client_get_devices (engine->priv->client); |
849 | + |
850 | + /* do we have specific device types? */ |
851 | + array = engine->priv->array; |
852 | + for (i=0;i<array->len;i++) { |
853 | + device = g_ptr_array_index (engine->priv->array, i); |
854 | + |
855 | + /* get device properties */ |
856 | + g_object_get (device, |
857 | + "kind", &kind, |
858 | + NULL); |
859 | + |
860 | + if (kind == UP_DEVICE_KIND_BATTERY) |
861 | + has_battery = TRUE; |
862 | + else if (kind == UP_DEVICE_KIND_UPS) |
863 | + has_ups = TRUE; |
864 | + } |
865 | + |
866 | + /* only show the battery prefs section if we have batteries */ |
867 | + prefs_server = gpm_prefs_server_new (); |
868 | + if (has_battery) |
869 | + gpm_prefs_server_set_capability (prefs_server, GPM_PREFS_SERVER_BATTERY); |
870 | + if (has_ups) |
871 | + gpm_prefs_server_set_capability (prefs_server, GPM_PREFS_SERVER_UPS); |
872 | + g_object_unref (prefs_server); |
873 | + |
874 | + /* connected mobile phones */ |
875 | + gpm_phone_coldplug (engine->priv->phone); |
876 | + |
877 | + gpm_engine_recalculate_state (engine); |
878 | + |
879 | + /* add to database */ |
880 | + for (i=0;i<array->len;i++) { |
881 | + device = g_ptr_array_index (engine->priv->array, i); |
882 | + gpm_engine_device_add (engine, device); |
883 | + gpm_engine_check_recall (engine, device); |
884 | + } |
885 | +out: |
886 | + /* never repeat */ |
887 | + return FALSE; |
888 | +} |
889 | + |
890 | +/** |
891 | + * gpm_engine_device_added_cb: |
892 | + **/ |
893 | +static void |
894 | +gpm_engine_device_added_cb (UpClient *client, UpDevice *device, GpmEngine *engine) |
895 | +{ |
896 | + /* add to list */ |
897 | + g_ptr_array_add (engine->priv->array, g_object_ref (device)); |
898 | + gpm_engine_check_recall (engine, device); |
899 | + |
900 | + gpm_engine_recalculate_state (engine); |
901 | +} |
902 | + |
903 | +/** |
904 | + * gpm_engine_device_removed_cb: |
905 | + **/ |
906 | +static void |
907 | +gpm_engine_device_removed_cb (UpClient *client, UpDevice *device, GpmEngine *engine) |
908 | +{ |
909 | + gboolean ret; |
910 | + ret = g_ptr_array_remove (engine->priv->array, device); |
911 | + if (!ret) |
912 | + return; |
913 | + gpm_engine_recalculate_state (engine); |
914 | +} |
915 | + |
916 | + |
917 | +/** |
918 | + * gpm_engine_device_changed_cb: |
919 | + **/ |
920 | +static void |
921 | +gpm_engine_device_changed_cb (UpClient *client, UpDevice *device, GpmEngine *engine) |
922 | +{ |
923 | + UpDeviceKind kind; |
924 | + UpDeviceState state; |
925 | + UpDeviceState state_old; |
926 | + GpmEngineWarning warning_old; |
927 | + GpmEngineWarning warning; |
928 | + |
929 | + /* get device properties */ |
930 | + g_object_get (device, |
931 | + "kind", &kind, |
932 | + NULL); |
933 | + |
934 | + /* if battery then use composite device to cope with multiple batteries */ |
935 | + if (kind == UP_DEVICE_KIND_BATTERY) { |
936 | + egg_debug ("updating because %s changed", up_device_get_object_path (device)); |
937 | + device = gpm_engine_update_composite_device (engine, device); |
938 | + } |
939 | + |
940 | + /* get device properties (may be composite) */ |
941 | + g_object_get (device, |
942 | + "state", &state, |
943 | + NULL); |
944 | + |
945 | + egg_debug ("%s state is now %s", up_device_get_object_path (device), up_device_state_to_string (state)); |
946 | + |
947 | + /* see if any interesting state changes have happened */ |
948 | + state_old = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(device), "engine-state-old")); |
949 | + if (state_old != state) { |
950 | + if (state == UP_DEVICE_STATE_DISCHARGING) { |
951 | + egg_debug ("** EMIT: discharging"); |
952 | + g_signal_emit (engine, signals [DISCHARGING], 0, device); |
953 | + } else if (state == UP_DEVICE_STATE_FULLY_CHARGED) { |
954 | + egg_debug ("** EMIT: fully charged"); |
955 | + g_signal_emit (engine, signals [FULLY_CHARGED], 0, device); |
956 | + } |
957 | + |
958 | + /* save new state */ |
959 | + g_object_set_data (G_OBJECT(device), "engine-state-old", GUINT_TO_POINTER(state)); |
960 | + } |
961 | + |
962 | + /* check the warning state has not changed */ |
963 | + warning_old = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(device), "engine-warning-old")); |
964 | + warning = gpm_engine_get_warning (engine, device); |
965 | + if (warning != warning_old) { |
966 | + if (warning == GPM_ENGINE_WARNING_LOW) { |
967 | + egg_debug ("** EMIT: charge-low"); |
968 | + g_signal_emit (engine, signals [CHARGE_LOW], 0, device); |
969 | + } else if (warning == GPM_ENGINE_WARNING_CRITICAL) { |
970 | + egg_debug ("** EMIT: charge-critical"); |
971 | + g_signal_emit (engine, signals [CHARGE_CRITICAL], 0, device); |
972 | + } else if (warning == GPM_ENGINE_WARNING_ACTION) { |
973 | + egg_debug ("** EMIT: charge-action"); |
974 | + g_signal_emit (engine, signals [CHARGE_ACTION], 0, device); |
975 | + } |
976 | + /* save new state */ |
977 | + g_object_set_data (G_OBJECT(device), "engine-warning-old", GUINT_TO_POINTER(warning)); |
978 | + } |
979 | + |
980 | + gpm_engine_recalculate_state (engine); |
981 | +} |
982 | + |
983 | +/** |
984 | + * gpm_engine_get_devices: |
985 | + * |
986 | + * Return value: the UpDevice array, free with g_ptr_array_unref() |
987 | + **/ |
988 | +GPtrArray * |
989 | +gpm_engine_get_devices (GpmEngine *engine) |
990 | +{ |
991 | + return g_ptr_array_ref (engine->priv->array); |
992 | +} |
993 | + |
994 | +/** |
995 | + * phone_device_added_cb: |
996 | + **/ |
997 | +static void |
998 | +phone_device_added_cb (GpmPhone *phone, guint idx, GpmEngine *engine) |
999 | +{ |
1000 | + UpDevice *device; |
1001 | + device = up_device_new (); |
1002 | + |
1003 | + egg_debug ("phone added %i", idx); |
1004 | + |
1005 | + /* get device properties */ |
1006 | + g_object_set (device, |
1007 | + "kind", UP_DEVICE_KIND_PHONE, |
1008 | + "is-rechargeable", TRUE, |
1009 | + "native-path", g_strdup_printf ("dummy:phone_%i", idx), |
1010 | + "is-present", TRUE, |
1011 | + NULL); |
1012 | + |
1013 | + /* state changed */ |
1014 | + gpm_engine_device_add (engine, device); |
1015 | + g_ptr_array_add (engine->priv->array, g_object_ref (device)); |
1016 | + gpm_engine_recalculate_state (engine); |
1017 | +} |
1018 | + |
1019 | +/** |
1020 | + * phone_device_removed_cb: |
1021 | + **/ |
1022 | +static void |
1023 | +phone_device_removed_cb (GpmPhone *phone, guint idx, GpmEngine *engine) |
1024 | +{ |
1025 | + guint i; |
1026 | + UpDevice *device; |
1027 | + UpDeviceKind kind; |
1028 | + |
1029 | + egg_debug ("phone removed %i", idx); |
1030 | + |
1031 | + for (i=0; i<engine->priv->array->len; i++) { |
1032 | + device = g_ptr_array_index (engine->priv->array, i); |
1033 | + |
1034 | + /* get device properties */ |
1035 | + g_object_get (device, |
1036 | + "kind", &kind, |
1037 | + NULL); |
1038 | + |
1039 | + if (kind == UP_DEVICE_KIND_PHONE) { |
1040 | + g_ptr_array_remove_index (engine->priv->array, i); |
1041 | + break; |
1042 | + } |
1043 | + } |
1044 | + |
1045 | + /* state changed */ |
1046 | + gpm_engine_recalculate_state (engine); |
1047 | +} |
1048 | + |
1049 | +/** |
1050 | + * phone_device_refresh_cb: |
1051 | + **/ |
1052 | +static void |
1053 | +phone_device_refresh_cb (GpmPhone *phone, guint idx, GpmEngine *engine) |
1054 | +{ |
1055 | + guint i; |
1056 | + UpDevice *device; |
1057 | + UpDeviceKind kind; |
1058 | + UpDeviceState state; |
1059 | + gboolean is_present; |
1060 | + gdouble percentage; |
1061 | + |
1062 | + egg_debug ("phone refresh %i", idx); |
1063 | + |
1064 | + for (i=0; i<engine->priv->array->len; i++) { |
1065 | + device = g_ptr_array_index (engine->priv->array, i); |
1066 | + |
1067 | + /* get device properties */ |
1068 | + g_object_get (device, |
1069 | + "kind", &kind, |
1070 | + "state", &state, |
1071 | + "percentage", &percentage, |
1072 | + "is-present", &is_present, |
1073 | + NULL); |
1074 | + |
1075 | + if (kind == UP_DEVICE_KIND_PHONE) { |
1076 | + is_present = gpm_phone_get_present (phone, idx); |
1077 | + state = gpm_phone_get_on_ac (phone, idx) ? UP_DEVICE_STATE_CHARGING : UP_DEVICE_STATE_DISCHARGING; |
1078 | + percentage = gpm_phone_get_percentage (phone, idx); |
1079 | + break; |
1080 | + } |
1081 | + } |
1082 | + |
1083 | + /* state changed */ |
1084 | + gpm_engine_recalculate_state (engine); |
1085 | +} |
1086 | + |
1087 | +/** |
1088 | + * gpm_engine_init: |
1089 | + * @engine: This class instance |
1090 | + **/ |
1091 | +static void |
1092 | +gpm_engine_init (GpmEngine *engine) |
1093 | +{ |
1094 | + gchar *icon_policy; |
1095 | + |
1096 | + engine->priv = GPM_ENGINE_GET_PRIVATE (engine); |
1097 | + |
1098 | + engine->priv->array = g_ptr_array_new_with_free_func (g_object_unref); |
1099 | + engine->priv->client = up_client_new (); |
1100 | + g_signal_connect (engine->priv->client, "device-added", |
1101 | + G_CALLBACK (gpm_engine_device_added_cb), engine); |
1102 | + g_signal_connect (engine->priv->client, "device-removed", |
1103 | + G_CALLBACK (gpm_engine_device_removed_cb), engine); |
1104 | + g_signal_connect (engine->priv->client, "device-changed", |
1105 | + G_CALLBACK (gpm_engine_device_changed_cb), engine); |
1106 | + |
1107 | + engine->priv->conf = gconf_client_get_default (); |
1108 | + gconf_client_notify_add (engine->priv->conf, GPM_CONF_DIR, |
1109 | + (GConfClientNotifyFunc) gpm_engine_conf_key_changed_cb, |
1110 | + engine, NULL, NULL); |
1111 | + |
1112 | + engine->priv->phone = gpm_phone_new (); |
1113 | + g_signal_connect (engine->priv->phone, "device-added", |
1114 | + G_CALLBACK (phone_device_added_cb), engine); |
1115 | + g_signal_connect (engine->priv->phone, "device-removed", |
1116 | + G_CALLBACK (phone_device_removed_cb), engine); |
1117 | + g_signal_connect (engine->priv->phone, "device-refresh", |
1118 | + G_CALLBACK (phone_device_refresh_cb), engine); |
1119 | + |
1120 | + /* create a fake virtual composite battery */ |
1121 | + engine->priv->battery_composite = up_device_new (); |
1122 | + g_object_set (engine->priv->battery_composite, |
1123 | + "kind", UP_DEVICE_KIND_BATTERY, |
1124 | + "is-rechargeable", TRUE, |
1125 | + "native-path", "dummy:composite_battery", |
1126 | + "power-supply", TRUE, |
1127 | + "is-present", TRUE, |
1128 | + NULL); |
1129 | + |
1130 | + engine->priv->previous_icon = NULL; |
1131 | + engine->priv->previous_summary = NULL; |
1132 | + |
1133 | + /* do we want to display the icon in the tray */ |
1134 | + icon_policy = gconf_client_get_string (engine->priv->conf, GPM_CONF_UI_ICON_POLICY, NULL); |
1135 | + engine->priv->icon_policy = gpm_icon_policy_from_string (icon_policy); |
1136 | + g_free (icon_policy); |
1137 | + |
1138 | + /* get percentage policy */ |
1139 | + engine->priv->low_percentage = gconf_client_get_int (engine->priv->conf, GPM_CONF_THRESH_PERCENTAGE_LOW, NULL); |
1140 | + engine->priv->critical_percentage = gconf_client_get_int (engine->priv->conf, GPM_CONF_THRESH_PERCENTAGE_CRITICAL, NULL); |
1141 | + engine->priv->action_percentage = gconf_client_get_int (engine->priv->conf, GPM_CONF_THRESH_PERCENTAGE_ACTION, NULL); |
1142 | + |
1143 | + /* get time policy */ |
1144 | + engine->priv->low_time = gconf_client_get_int (engine->priv->conf, GPM_CONF_THRESH_TIME_LOW, NULL); |
1145 | + engine->priv->critical_time = gconf_client_get_int (engine->priv->conf, GPM_CONF_THRESH_TIME_CRITICAL, NULL); |
1146 | + engine->priv->action_time = gconf_client_get_int (engine->priv->conf, GPM_CONF_THRESH_TIME_ACTION, NULL); |
1147 | + |
1148 | + /* we can disable this if the time remaining is inaccurate or just plain wrong */ |
1149 | + engine->priv->use_time_primary = gconf_client_get_bool (engine->priv->conf, GPM_CONF_USE_TIME_POLICY, NULL); |
1150 | + if (engine->priv->use_time_primary) |
1151 | + egg_debug ("Using per-time notification policy"); |
1152 | + else |
1153 | + egg_debug ("Using percentage notification policy"); |
1154 | + |
1155 | + g_idle_add ((GSourceFunc) gpm_engine_coldplug_idle_cb, engine); |
1156 | +} |
1157 | + |
1158 | +/** |
1159 | + * gpm_engine_class_init: |
1160 | + * @engine: This class instance |
1161 | + **/ |
1162 | +static void |
1163 | +gpm_engine_class_init (GpmEngineClass *klass) |
1164 | +{ |
1165 | + GObjectClass *object_class = G_OBJECT_CLASS (klass); |
1166 | + object_class->finalize = gpm_engine_finalize; |
1167 | + g_type_class_add_private (klass, sizeof (GpmEnginePrivate)); |
1168 | + |
1169 | + signals [ICON_CHANGED] = |
1170 | + g_signal_new ("icon-changed", |
1171 | + G_TYPE_FROM_CLASS (object_class), |
1172 | + G_SIGNAL_RUN_LAST, |
1173 | + G_STRUCT_OFFSET (GpmEngineClass, icon_changed), |
1174 | + NULL, NULL, g_cclosure_marshal_VOID__STRING, |
1175 | + G_TYPE_NONE, 1, G_TYPE_STRING); |
1176 | + signals [SUMMARY_CHANGED] = |
1177 | + g_signal_new ("summary-changed", |
1178 | + G_TYPE_FROM_CLASS (object_class), |
1179 | + G_SIGNAL_RUN_LAST, |
1180 | + G_STRUCT_OFFSET (GpmEngineClass, summary_changed), |
1181 | + NULL, NULL, g_cclosure_marshal_VOID__STRING, |
1182 | + G_TYPE_NONE, 1, G_TYPE_STRING); |
1183 | + signals [LOW_CAPACITY] = |
1184 | + g_signal_new ("low-capacity", |
1185 | + G_TYPE_FROM_CLASS (object_class), |
1186 | + G_SIGNAL_RUN_LAST, |
1187 | + G_STRUCT_OFFSET (GpmEngineClass, low_capacity), |
1188 | + NULL, NULL, g_cclosure_marshal_VOID__POINTER, |
1189 | + G_TYPE_NONE, 1, G_TYPE_POINTER); |
1190 | + signals [PERHAPS_RECALL] = |
1191 | + g_signal_new ("perhaps-recall", |
1192 | + G_TYPE_FROM_CLASS (object_class), |
1193 | + G_SIGNAL_RUN_LAST, |
1194 | + G_STRUCT_OFFSET (GpmEngineClass, perhaps_recall), |
1195 | + NULL, NULL, gpm_marshal_VOID__POINTER_STRING_STRING, |
1196 | + G_TYPE_NONE, |
1197 | + 3, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING); |
1198 | + signals [FULLY_CHARGED] = |
1199 | + g_signal_new ("fully-charged", |
1200 | + G_TYPE_FROM_CLASS (object_class), |
1201 | + G_SIGNAL_RUN_LAST, |
1202 | + G_STRUCT_OFFSET (GpmEngineClass, fully_charged), |
1203 | + NULL, NULL, g_cclosure_marshal_VOID__POINTER, |
1204 | + G_TYPE_NONE, 1, G_TYPE_POINTER); |
1205 | + signals [DISCHARGING] = |
1206 | + g_signal_new ("discharging", |
1207 | + G_TYPE_FROM_CLASS (object_class), |
1208 | + G_SIGNAL_RUN_LAST, |
1209 | + G_STRUCT_OFFSET (GpmEngineClass, discharging), |
1210 | + NULL, NULL, g_cclosure_marshal_VOID__POINTER, |
1211 | + G_TYPE_NONE, 1, G_TYPE_POINTER); |
1212 | + signals [CHARGE_ACTION] = |
1213 | + g_signal_new ("charge-action", |
1214 | + G_TYPE_FROM_CLASS (object_class), |
1215 | + G_SIGNAL_RUN_LAST, |
1216 | + G_STRUCT_OFFSET (GpmEngineClass, charge_action), |
1217 | + NULL, NULL, g_cclosure_marshal_VOID__POINTER, |
1218 | + G_TYPE_NONE, 1, G_TYPE_POINTER); |
1219 | + signals [CHARGE_LOW] = |
1220 | + g_signal_new ("charge-low", |
1221 | + G_TYPE_FROM_CLASS (object_class), |
1222 | + G_SIGNAL_RUN_LAST, |
1223 | + G_STRUCT_OFFSET (GpmEngineClass, charge_low), |
1224 | + NULL, NULL, g_cclosure_marshal_VOID__POINTER, |
1225 | + G_TYPE_NONE, 1, G_TYPE_POINTER); |
1226 | + signals [CHARGE_CRITICAL] = |
1227 | + g_signal_new ("charge-critical", |
1228 | + G_TYPE_FROM_CLASS (object_class), |
1229 | + G_SIGNAL_RUN_LAST, |
1230 | + G_STRUCT_OFFSET (GpmEngineClass, charge_critical), |
1231 | + NULL, NULL, g_cclosure_marshal_VOID__POINTER, |
1232 | + G_TYPE_NONE, 1, G_TYPE_POINTER); |
1233 | + signals [DEVICES_CHANGED] = |
1234 | + g_signal_new ("devices-changed", |
1235 | + G_TYPE_FROM_CLASS (object_class), |
1236 | + G_SIGNAL_RUN_LAST, |
1237 | + G_STRUCT_OFFSET (GpmEngineClass, devices_changed), |
1238 | + NULL, NULL, g_cclosure_marshal_VOID__VOID, |
1239 | + G_TYPE_NONE, 0); |
1240 | +} |
1241 | + |
1242 | +/** |
1243 | + * gpm_engine_finalize: |
1244 | + * @object: This class instance |
1245 | + **/ |
1246 | +static void |
1247 | +gpm_engine_finalize (GObject *object) |
1248 | +{ |
1249 | + GpmEngine *engine; |
1250 | + |
1251 | + g_return_if_fail (object != NULL); |
1252 | + g_return_if_fail (GPM_IS_ENGINE (object)); |
1253 | + |
1254 | + engine = GPM_ENGINE (object); |
1255 | + engine->priv = GPM_ENGINE_GET_PRIVATE (engine); |
1256 | + |
1257 | + g_ptr_array_unref (engine->priv->array); |
1258 | + g_object_unref (engine->priv->client); |
1259 | + g_object_unref (engine->priv->phone); |
1260 | + g_object_unref (engine->priv->battery_composite); |
1261 | + |
1262 | + g_free (engine->priv->previous_icon); |
1263 | + g_free (engine->priv->previous_summary); |
1264 | + |
1265 | + G_OBJECT_CLASS (gpm_engine_parent_class)->finalize (object); |
1266 | +} |
1267 | + |
1268 | +/** |
1269 | + * gpm_engine_new: |
1270 | + * Return value: new class instance. |
1271 | + **/ |
1272 | +GpmEngine * |
1273 | +gpm_engine_new (void) |
1274 | +{ |
1275 | + if (gpm_engine_object != NULL) { |
1276 | + g_object_ref (gpm_engine_object); |
1277 | + } else { |
1278 | + gpm_engine_object = g_object_new (GPM_TYPE_ENGINE, NULL); |
1279 | + g_object_add_weak_pointer (gpm_engine_object, &gpm_engine_object); |
1280 | + } |
1281 | + return GPM_ENGINE (gpm_engine_object); |
1282 | + |
1283 | +} |
1284 | + |
1285 | |
1286 | === modified file '.pc/applied-patches' |
1287 | --- .pc/applied-patches 2011-03-15 01:04:40 +0000 |
1288 | +++ .pc/applied-patches 2011-07-10 20:29:23 +0000 |
1289 | @@ -6,3 +6,4 @@ |
1290 | 14_fix_no_xbacklight_crash.patch |
1291 | 14-critical-message-timeout.patch |
1292 | 15-keyboard-backlight-support.patch |
1293 | +16-fix-duplicate-battery.patch |
1294 | |
1295 | === modified file 'debian/changelog' |
1296 | --- debian/changelog 2011-03-15 01:04:40 +0000 |
1297 | +++ debian/changelog 2011-07-10 20:29:23 +0000 |
1298 | @@ -1,3 +1,11 @@ |
1299 | +gnome-power-manager (2.32.0-2ubuntu3) natty; urgency=low |
1300 | + |
1301 | + * 16-fix-duplicate-battery.patch: Don't add hot-added battery to device |
1302 | + list, because libupower-glib already does that (LP: #675108) |
1303 | + [ Maxim Levitsky <maximlevitsky@gmail.com> ] |
1304 | + |
1305 | + -- Phillip Susi <psusi@ubuntu.com> Mon, 13 Jun 2011 14:04:01 -0400 |
1306 | + |
1307 | gnome-power-manager (2.32.0-2ubuntu2) natty; urgency=low |
1308 | |
1309 | [ Alex Murray <murray.alex@gmail.com> ] |
1310 | |
1311 | === added file 'debian/patches/16-fix-duplicate-battery.patch' |
1312 | --- debian/patches/16-fix-duplicate-battery.patch 1970-01-01 00:00:00 +0000 |
1313 | +++ debian/patches/16-fix-duplicate-battery.patch 2011-07-10 20:29:23 +0000 |
1314 | @@ -0,0 +1,20 @@ |
1315 | +Description: Don't add hot-added battery to device list, because libupower-glib |
1316 | + already does that (LP: #616443) |
1317 | +Author: Maxim Levitsky <maximlevitsky@gmail.com> |
1318 | +Bug-Ubuntu: https://launchpad.net/bugs/616443 |
1319 | +Forwarded: no |
1320 | +Last-Update: <2011-06-13> |
1321 | + |
1322 | +--- gnome-power-manager-2.32.0.orig/src/gpm-engine.c |
1323 | ++++ gnome-power-manager-2.32.0/src/gpm-engine.c |
1324 | +@@ -886,10 +886,7 @@ out: |
1325 | + static void |
1326 | + gpm_engine_device_added_cb (UpClient *client, UpDevice *device, GpmEngine *engine) |
1327 | + { |
1328 | +- /* add to list */ |
1329 | +- g_ptr_array_add (engine->priv->array, g_object_ref (device)); |
1330 | + gpm_engine_check_recall (engine, device); |
1331 | +- |
1332 | + gpm_engine_recalculate_state (engine); |
1333 | + } |
1334 | + |
1335 | |
1336 | === modified file 'debian/patches/series' |
1337 | --- debian/patches/series 2011-03-15 01:04:40 +0000 |
1338 | +++ debian/patches/series 2011-07-10 20:29:23 +0000 |
1339 | @@ -6,3 +6,5 @@ |
1340 | 14_fix_no_xbacklight_crash.patch |
1341 | 14-critical-message-timeout.patch |
1342 | 15-keyboard-backlight-support.patch |
1343 | +16-fix-duplicate-battery.patch |
1344 | + |
1345 | |
1346 | === modified file 'src/gpm-engine.c' |
1347 | --- src/gpm-engine.c 2011-01-26 17:20:06 +0000 |
1348 | +++ src/gpm-engine.c 2011-07-10 20:29:23 +0000 |
1349 | @@ -886,10 +886,7 @@ |
1350 | static void |
1351 | gpm_engine_device_added_cb (UpClient *client, UpDevice *device, GpmEngine *engine) |
1352 | { |
1353 | - /* add to list */ |
1354 | - g_ptr_array_add (engine->priv->array, g_object_ref (device)); |
1355 | gpm_engine_check_recall (engine, device); |
1356 | - |
1357 | gpm_engine_recalculate_state (engine); |
1358 | } |
1359 |
See comments in above referenced bug re SRU paperwork and oneiric fix.