Merge lp:~charlesk/indicator-power/custom-bus-for-upower into lp:indicator-power/15.04
- custom-bus-for-upower
- Merge into trunk.15.04
Status: | Approved |
---|---|
Approved by: | Ted Gould |
Approved revision: | 283 |
Proposed branch: | lp:~charlesk/indicator-power/custom-bus-for-upower |
Merge into: | lp:indicator-power/15.04 |
Diff against target: |
1005 lines (+556/-176) 7 files modified
README (+11/-0) src/CMakeLists.txt (+1/-0) src/brightness.c (+71/-30) src/bus.c (+195/-0) src/bus.h (+50/-0) src/device-provider-upower.c (+67/-23) src/service.c (+161/-123) |
To merge this branch: | bzr merge lp:~charlesk/indicator-power/custom-bus-for-upower |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ted Gould (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+246234@code.launchpad.net |
Commit message
Add support for finer-grained dbus service mocking
Description of the change
== Change Description
Add support for finer-grained dbus service mocking.
Use case: say we want to feed the indicator a dbusmocked upower, but don't want to mock the entire system bus because we also talk to powerd on the system bus. This lets us specify via environment variables where to look for each bus dependency.
== Checklist
> Are there any related MPs required for this MP to build/function as expected? Please list.
No
> Is your branch in sync with latest trunk? (e.g. bzr pull lp:trunk -> no changes)
Yes
> Did the code build without warnings?
Yes
> Did the tests run successfully?
Yes
> Did you perform an exploratory manual test run of your code change and any related functionality?
Yes
> If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A
> Did your component test plan pass? If on a device, what image number?
15.03 nexus 4 r63
> Please list which manual tests are germane for the reviewer in this MR.
This is QA scaffolding; no manual tests affected
> Did you provide a link to this page https:/
Yes
PS Jenkins bot (ps-jenkins) wrote : | # |
Ted Gould (ted) wrote : | # |
Have to say I'm a little nervous with abstracting the bus stuff out this much. I like the standardization of using g_bus_own_name() to setup the ordering of the callbacks and ensure that we're doing everything right there. Naturually, that loses some flexibility. I like sitting outside the process and using dbusmock better so that it can be the same name, on the bus configured to be DBUS_SYSTEM_
That said, I don't see anything wrong with this code and have no objection other than "not the way I would have done it."
Allan LeSage (allanlesage) wrote : | # |
Getting requests for this awesome new feature already (from paulliu), let's land 'er!
Unmerged revisions
- 283. By Charles Kerr
-
pass the G_DBUS_
CONNECTION_ FLAGS_AUTHENTIC ATION_CLIENT flag when calling g_dbus_ connection_ new_for_ address( ) on an arbitrary bus address - 282. By Charles Kerr
-
when connecting to a custom bus address, use G_DBUS_
CONNECTION_ FLAGS_MESSAGE_ BUS_CONNECTION - 281. By Charles Kerr
-
document the debugging environment variables
- 280. By Charles Kerr
-
move indicator_
power_get_ screen_ busname( ) to bus.c - 279. By Charles Kerr
-
use indicator_
power_get_ bus() for acquiring the bus that we look for powerd on - 278. By Charles Kerr
-
use indicator_
power_get_ bus() for acquiring the bus that we look for upower on - 277. By Charles Kerr
-
use indicator_
power_get_ bus() for acquiring the indicator's bus - 276. By Charles Kerr
-
add indicator_
power_get_ bus() which lets environment variables let a custom bus override other buses.
Preview Diff
1 | === added file 'README' |
2 | --- README 1970-01-01 00:00:00 +0000 |
3 | +++ README 2015-01-12 23:02:27 +0000 |
4 | @@ -0,0 +1,11 @@ |
5 | +Environment variables used for testing: |
6 | + |
7 | + - INDICATOR_POWER_BUS_ADDRESS_UPOWER overrides the system bus default |
8 | + - INDICATOR_POWER_BUS_NAME_UPOWER overrides the 'org.freedesktop.UPower' default |
9 | + |
10 | + - INDICATOR_POWER_BUS_ADDRESS_INDICATOR overrides the session bus default |
11 | + - INDICATOR_POWER_BUS_NAME_INDICATOR overrides the 'com.canonical.indicator.power' default |
12 | + |
13 | + - INDICATOR_POWER_BUS_ADDRESS_POWERD overrides the system bus default |
14 | + - INDICATOR_POWER_BUS_NAME_POWERD overrides the 'com.canonical.powerd' default |
15 | + |
16 | |
17 | === modified file 'src/CMakeLists.txt' |
18 | --- src/CMakeLists.txt 2014-10-14 19:09:32 +0000 |
19 | +++ src/CMakeLists.txt 2015-01-12 23:02:27 +0000 |
20 | @@ -6,6 +6,7 @@ |
21 | # handwritten sources |
22 | set(SERVICE_MANUAL_SOURCES |
23 | brightness.c |
24 | + bus.c |
25 | device-provider-mock.c |
26 | device-provider-upower.c |
27 | device-provider.c |
28 | |
29 | === modified file 'src/brightness.c' |
30 | --- src/brightness.c 2014-09-12 16:37:02 +0000 |
31 | +++ src/brightness.c 2015-01-12 23:02:27 +0000 |
32 | @@ -18,6 +18,7 @@ |
33 | */ |
34 | |
35 | #include "brightness.h" |
36 | +#include "bus.h" |
37 | |
38 | #include <gio/gio.h> |
39 | |
40 | @@ -40,11 +41,11 @@ |
41 | |
42 | typedef struct |
43 | { |
44 | - GDBusConnection * system_bus; |
45 | GCancellable * cancellable; |
46 | |
47 | GSettings * settings; |
48 | |
49 | + GDBusConnection * bus; |
50 | guint powerd_name_tag; |
51 | |
52 | double percentage; |
53 | @@ -124,6 +125,8 @@ |
54 | } |
55 | } |
56 | |
57 | +static void set_bus(IndicatorPowerBrightness * self, GDBusConnection * bus); |
58 | + |
59 | static void |
60 | my_dispose(GObject * o) |
61 | { |
62 | @@ -136,14 +139,9 @@ |
63 | g_clear_object(&p->cancellable); |
64 | } |
65 | |
66 | - if (p->powerd_name_tag) |
67 | - { |
68 | - g_bus_unwatch_name(p->powerd_name_tag); |
69 | - p->powerd_name_tag = 0; |
70 | - } |
71 | - |
72 | g_clear_object(&p->settings); |
73 | - g_clear_object(&p->system_bus); |
74 | + |
75 | + set_bus(self, NULL); |
76 | |
77 | G_OBJECT_CLASS(indicator_power_brightness_parent_class)->dispose(o); |
78 | } |
79 | @@ -269,8 +267,8 @@ |
80 | { |
81 | priv_t * p = get_priv(self); |
82 | |
83 | - g_dbus_connection_call(p->system_bus, |
84 | - "com.canonical.powerd", |
85 | + g_dbus_connection_call(p->bus, |
86 | + indicator_power_get_powerd_busname(), |
87 | "/com/canonical/powerd", |
88 | "com.canonical.powerd", |
89 | "getBrightnessParams", |
90 | @@ -284,20 +282,13 @@ |
91 | } |
92 | |
93 | static void |
94 | -on_powerd_appeared(GDBusConnection * connection, |
95 | +on_powerd_appeared(GDBusConnection * bus G_GNUC_UNUSED, |
96 | const gchar * bus_name G_GNUC_UNUSED, |
97 | const gchar * name_owner G_GNUC_UNUSED, |
98 | gpointer gself) |
99 | { |
100 | - IndicatorPowerBrightness * self = INDICATOR_POWER_BRIGHTNESS(gself); |
101 | - priv_t * p = get_priv(self); |
102 | - |
103 | - /* keep a handle to the system bus */ |
104 | - g_clear_object(&p->system_bus); |
105 | - p->system_bus = g_object_ref(connection); |
106 | - |
107 | /* update our cache of powerd's brightness params */ |
108 | - call_powerd_get_brightness_params(self); |
109 | + call_powerd_get_brightness_params(gself); |
110 | } |
111 | |
112 | static void |
113 | @@ -319,7 +310,7 @@ |
114 | /* setUserBrightness doesn't return anything, |
115 | so this function is just to check for bus error messages */ |
116 | static void |
117 | -on_set_uscreen_user_brightness_result(GObject * system_bus, |
118 | +on_set_uscreen_user_brightness_result(GObject * bus, |
119 | GAsyncResult * res, |
120 | gpointer gself G_GNUC_UNUSED) |
121 | { |
122 | @@ -327,7 +318,7 @@ |
123 | GVariant * v; |
124 | |
125 | error = NULL; |
126 | - v = g_dbus_connection_call_finish(G_DBUS_CONNECTION(system_bus), res, &error); |
127 | + v = g_dbus_connection_call_finish(G_DBUS_CONNECTION(bus), res, &error); |
128 | if (error != NULL) |
129 | { |
130 | if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) |
131 | @@ -345,8 +336,8 @@ |
132 | { |
133 | priv_t * p = get_priv(self); |
134 | |
135 | - g_dbus_connection_call(p->system_bus, |
136 | - "com.canonical.Unity.Screen", |
137 | + g_dbus_connection_call(p->bus, |
138 | + indicator_power_get_screen_busname(), |
139 | "/com/canonical/Unity/Screen", |
140 | "com.canonical.Unity.Screen", |
141 | "setUserBrightness", |
142 | @@ -399,6 +390,58 @@ |
143 | g_object_notify_by_pspec(G_OBJECT(self), properties[PROP_AUTO]); |
144 | } |
145 | |
146 | +/*** |
147 | +**** |
148 | +***/ |
149 | + |
150 | +static void |
151 | +set_bus (IndicatorPowerBrightness * self, GDBusConnection * bus) |
152 | +{ |
153 | + priv_t * p = get_priv(self); |
154 | + |
155 | + if (p->bus != NULL) |
156 | + { |
157 | + g_bus_unwatch_name(p->powerd_name_tag); |
158 | + p->powerd_name_tag = 0; |
159 | + |
160 | + g_clear_object(&p->bus); |
161 | + } |
162 | + |
163 | + if (bus != NULL) |
164 | + { |
165 | + p->bus = g_object_ref(bus); |
166 | + |
167 | + p->powerd_name_tag = g_bus_watch_name_on_connection(p->bus, |
168 | + indicator_power_get_powerd_busname(), |
169 | + G_BUS_NAME_WATCHER_FLAGS_NONE, |
170 | + on_powerd_appeared, |
171 | + on_powerd_vanished, |
172 | + self, |
173 | + NULL); |
174 | + } |
175 | +} |
176 | + |
177 | +static void |
178 | +on_bus_ready (GObject * unused G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) |
179 | +{ |
180 | + GDBusConnection * bus; |
181 | + GError * error = NULL; |
182 | + |
183 | + bus = indicator_power_get_bus_finish(res, &error); |
184 | + if (error != NULL) |
185 | + { |
186 | + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) |
187 | + g_warning ("Error getting bus: %s", error->message); |
188 | + |
189 | + g_error_free (error); |
190 | + } |
191 | + else |
192 | + { |
193 | + set_bus (INDICATOR_POWER_BRIGHTNESS(gself), bus); |
194 | + } |
195 | + |
196 | + g_clear_object(&bus); |
197 | +} |
198 | |
199 | /*** |
200 | **** Instantiation |
201 | @@ -433,13 +476,11 @@ |
202 | g_settings_schema_unref(schema); |
203 | } |
204 | |
205 | - p->powerd_name_tag = g_bus_watch_name(G_BUS_TYPE_SYSTEM, |
206 | - "com.canonical.powerd", |
207 | - G_BUS_NAME_WATCHER_FLAGS_NONE, |
208 | - on_powerd_appeared, |
209 | - on_powerd_vanished, |
210 | - self, |
211 | - NULL); |
212 | + indicator_power_get_bus(g_getenv("INDICATOR_POWER_BUS_ADDRESS_POWERD"), |
213 | + G_BUS_TYPE_SYSTEM, |
214 | + p->cancellable, |
215 | + on_bus_ready, |
216 | + self); |
217 | } |
218 | |
219 | static void |
220 | |
221 | === added file 'src/bus.c' |
222 | --- src/bus.c 1970-01-01 00:00:00 +0000 |
223 | +++ src/bus.c 2015-01-12 23:02:27 +0000 |
224 | @@ -0,0 +1,195 @@ |
225 | +/* |
226 | + * Copyright 2014 Canonical Ltd. |
227 | + * |
228 | + * This program is free software: you can redistribute it and/or modify it |
229 | + * under the terms of the GNU General Public License version 3, as published |
230 | + * by the Free Software Foundation. |
231 | + * |
232 | + * This program is distributed in the hope that it will be useful, but |
233 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
234 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
235 | + * PURPOSE. See the GNU General Public License for more details. |
236 | + * |
237 | + * You should have received a copy of the GNU General Public License along |
238 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
239 | + * |
240 | + * Authors: |
241 | + * Charles Kerr <charles.kerr@canonical.com> |
242 | + */ |
243 | + |
244 | +#include "bus.h" |
245 | + |
246 | +typedef GDBusConnection* (*FinishFunc)(GAsyncResult*, GError**); |
247 | + |
248 | +struct bus_data |
249 | +{ |
250 | + char * address; |
251 | + FinishFunc finish_func; |
252 | + GSimpleAsyncResult * result; |
253 | +}; |
254 | + |
255 | +GDBusConnection* |
256 | +indicator_power_get_bus_finish(GAsyncResult * result, |
257 | + GError ** error) |
258 | +{ |
259 | + GSimpleAsyncResult * simple; |
260 | + GDBusConnection * bus; |
261 | + |
262 | + g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, NULL), NULL); |
263 | + |
264 | + simple = (GSimpleAsyncResult *) result; |
265 | + |
266 | + if (g_simple_async_result_propagate_error (simple, error)) |
267 | + return NULL; |
268 | + |
269 | + bus = G_DBUS_CONNECTION(g_simple_async_result_get_op_res_gpointer (simple)); |
270 | + g_object_ref(bus); |
271 | + return bus; |
272 | +} |
273 | + |
274 | +static void |
275 | +on_bus_ready (GObject * unused G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) |
276 | +{ |
277 | + struct bus_data * data; |
278 | + GError * error = NULL; |
279 | + GDBusConnection * bus; |
280 | + |
281 | + data = gdata; |
282 | + error = NULL; |
283 | + bus = data->finish_func(res, &error); |
284 | + if (error != NULL) |
285 | + { |
286 | + if ((data->address != NULL) && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) |
287 | + g_simple_async_result_set_error (data->result, error->domain, error->code, "\"%s\" unreachable, %s", data->address, error->message); |
288 | + else |
289 | + g_simple_async_result_set_from_error (data->result, error); |
290 | + |
291 | + g_error_free (error); |
292 | + } |
293 | + |
294 | + if (bus != NULL) |
295 | + g_simple_async_result_set_op_res_gpointer(data->result, g_object_ref(bus), g_object_unref); |
296 | + g_simple_async_result_complete_in_idle(data->result); |
297 | + |
298 | + g_object_unref(data->result); |
299 | + g_free(data->address); |
300 | + g_free(data); |
301 | +} |
302 | + |
303 | +void indicator_power_get_bus(const char * address, |
304 | + GBusType bus_type, |
305 | + GCancellable * cancellable, |
306 | + GAsyncReadyCallback callback, |
307 | + gpointer user_data) |
308 | +{ |
309 | + GSimpleAsyncResult * result; |
310 | + |
311 | + result = g_simple_async_result_new(NULL, |
312 | + callback, |
313 | + user_data, |
314 | + NULL); |
315 | + g_simple_async_result_set_check_cancellable(result, cancellable); |
316 | + |
317 | + |
318 | + struct bus_data * data = g_new0(struct bus_data, 1); |
319 | + data->result = result; |
320 | + |
321 | + if ((address != NULL) && g_dbus_is_address(address)) |
322 | + { |
323 | + g_debug("Getting bus for address '%s'", address); |
324 | + data->address = g_strdup(address); |
325 | + data->finish_func = g_dbus_connection_new_for_address_finish; |
326 | + g_dbus_connection_new_for_address(address, |
327 | + G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION|G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, |
328 | + NULL /*GDBusAuthObserver*/, |
329 | + cancellable, |
330 | + on_bus_ready, |
331 | + data); |
332 | + } |
333 | + else |
334 | + { |
335 | + g_debug("Getting GBusType %d", (int)bus_type); |
336 | + data->finish_func = g_dbus_connection_new_for_address_finish; |
337 | + data->finish_func = g_bus_get_finish; |
338 | + g_bus_get(bus_type, |
339 | + cancellable, |
340 | + on_bus_ready, |
341 | + data); |
342 | + } |
343 | +} |
344 | + |
345 | +/*** |
346 | +**** |
347 | +***/ |
348 | + |
349 | +static const char* |
350 | +get_name_from_env_with_fallback (const char * env, const char * fallback) |
351 | +{ |
352 | + const char * name = g_getenv(env); |
353 | + |
354 | + if ((name == NULL) || !g_dbus_is_name(name)) |
355 | + name = fallback; |
356 | + |
357 | + return name; |
358 | +} |
359 | + |
360 | +const char* |
361 | +indicator_power_get_indicator_busname(void) |
362 | +{ |
363 | + static const char * name = NULL; |
364 | + |
365 | + if (G_UNLIKELY(name == NULL)) |
366 | + { |
367 | + name = get_name_from_env_with_fallback("INDICATOR_POWER_BUS_NAME_INDICATOR", |
368 | + "com.canonical.indicator.power"); |
369 | + g_debug("%s indicator busname is \"%s\"", G_STRLOC, name); |
370 | + } |
371 | + |
372 | + return name; |
373 | +} |
374 | + |
375 | +const char* |
376 | +indicator_power_get_upower_busname(void) |
377 | +{ |
378 | + static const char * name = NULL; |
379 | + |
380 | + if (G_UNLIKELY(name == NULL)) |
381 | + { |
382 | + name = get_name_from_env_with_fallback("INDICATOR_POWER_BUS_NAME_UPOWER", |
383 | + "org.freedesktop.UPower"); |
384 | + g_debug("%s upower busname is \"%s\"", G_STRLOC, name); |
385 | + } |
386 | + |
387 | + return name; |
388 | +} |
389 | + |
390 | +const char* |
391 | +indicator_power_get_powerd_busname(void) |
392 | +{ |
393 | + static const char * name = NULL; |
394 | + |
395 | + if (G_UNLIKELY(name == NULL)) |
396 | + { |
397 | + name = get_name_from_env_with_fallback("INDICATOR_POWER_BUS_NAME_POWERD", |
398 | + "com.canonical.powerd"); |
399 | + g_debug("%s powerd busname is \"%s\"", G_STRLOC, name); |
400 | + } |
401 | + |
402 | + return name; |
403 | +} |
404 | + |
405 | +const char* |
406 | +indicator_power_get_screen_busname(void) |
407 | +{ |
408 | + static const char * name = NULL; |
409 | + |
410 | + if (G_UNLIKELY(name == NULL)) |
411 | + { |
412 | + name = get_name_from_env_with_fallback("INDICATOR_POWER_BUS_NAME_SCREEN", |
413 | + "com.canonical.Unity.Screen"); |
414 | + g_debug("%s screen busname is \"%s\"", G_STRLOC, name); |
415 | + } |
416 | + |
417 | + return name; |
418 | +} |
419 | + |
420 | |
421 | === added file 'src/bus.h' |
422 | --- src/bus.h 1970-01-01 00:00:00 +0000 |
423 | +++ src/bus.h 2015-01-12 23:02:27 +0000 |
424 | @@ -0,0 +1,50 @@ |
425 | +/* |
426 | + * Copyright 2014 Canonical Ltd. |
427 | + * |
428 | + * This program is free software: you can redistribute it and/or modify it |
429 | + * under the terms of the GNU General Public License version 3, as published |
430 | + * by the Free Software Foundation. |
431 | + * |
432 | + * This program is distributed in the hope that it will be useful, but |
433 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
434 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
435 | + * PURPOSE. See the GNU General Public License for more details. |
436 | + * |
437 | + * You should have received a copy of the GNU General Public License along |
438 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
439 | + * |
440 | + * Authors: |
441 | + * Charles Kerr <charles.kerr@canonical.com> |
442 | + */ |
443 | + |
444 | +#ifndef __INDICATOR_POWER_BUS_H__ |
445 | +#define __INDICATOR_POWER_BUS_H__ |
446 | + |
447 | +#include <gio/gio.h> |
448 | + |
449 | +G_BEGIN_DECLS |
450 | + |
451 | +const char* indicator_power_get_indicator_busname (void); |
452 | +const char* indicator_power_get_powerd_busname (void); |
453 | +const char* indicator_power_get_screen_busname (void); |
454 | +const char* indicator_power_get_upower_busname (void); |
455 | + |
456 | +/** |
457 | + * Asynchronously get a bus connection. |
458 | + * |
459 | + * If address_name is a valid address, it's used. Otherwise, the bus_type is retrieved. |
460 | + * This can be used to let a debug bus address override another address; e.g. |
461 | + * indicator_power_get_bus(g_getenv("INDICATOR_POWER_BUS_ADDRESS_UPOWER"), G_BUS_TYPE_SYSTEM, ... |
462 | + */ |
463 | +void indicator_power_get_bus (const char * address_name, |
464 | + GBusType bus_type, |
465 | + GCancellable * cancellable, |
466 | + GAsyncReadyCallback callback, |
467 | + gpointer user_data); |
468 | + |
469 | +GDBusConnection* indicator_power_get_bus_finish (GAsyncResult * result, |
470 | + GError ** error); |
471 | + |
472 | +G_END_DECLS |
473 | + |
474 | +#endif /* __INDICATOR_POWER_BUS_H__ */ |
475 | |
476 | === modified file 'src/device-provider-upower.c' |
477 | --- src/device-provider-upower.c 2014-09-08 14:50:22 +0000 |
478 | +++ src/device-provider-upower.c 2015-01-12 23:02:27 +0000 |
479 | @@ -17,12 +17,11 @@ |
480 | * with this program. If not, see <http://www.gnu.org/licenses/>. |
481 | */ |
482 | |
483 | +#include "bus.h" |
484 | #include "device.h" |
485 | #include "device-provider.h" |
486 | #include "device-provider-upower.h" |
487 | |
488 | -#define BUS_NAME "org.freedesktop.UPower" |
489 | - |
490 | #define MGR_IFACE "org.freedesktop.UPower" |
491 | #define MGR_PATH "/org/freedesktop/UPower" |
492 | |
493 | @@ -175,7 +174,7 @@ |
494 | data->self = self; |
495 | |
496 | g_dbus_connection_call(p->bus, |
497 | - BUS_NAME, |
498 | + indicator_power_get_upower_busname(), |
499 | path, |
500 | "org.freedesktop.DBus.Properties", |
501 | "GetAll", |
502 | @@ -409,7 +408,7 @@ |
503 | |
504 | /* start listening for UPower events on the bus */ |
505 | static void |
506 | -on_bus_name_appeared(GDBusConnection * bus, |
507 | +on_bus_name_appeared(GDBusConnection * bus G_GNUC_UNUSED, |
508 | const gchar * name G_GNUC_UNUSED, |
509 | const gchar * name_owner, |
510 | gpointer gself) |
511 | @@ -420,7 +419,6 @@ |
512 | |
513 | self = INDICATOR_POWER_DEVICE_PROVIDER_UPOWER(gself); |
514 | p = get_priv(self); |
515 | - p->bus = G_DBUS_CONNECTION(g_object_ref(bus)); |
516 | |
517 | /* listen for signals from the boss */ |
518 | tag = g_dbus_connection_signal_subscribe(p->bus, |
519 | @@ -450,7 +448,7 @@ |
520 | |
521 | /* rebuild our devices list */ |
522 | g_dbus_connection_call(p->bus, |
523 | - BUS_NAME, |
524 | + indicator_power_get_upower_busname(), |
525 | MGR_PATH, |
526 | MGR_IFACE, |
527 | "EnumerateDevices", |
528 | @@ -490,9 +488,6 @@ |
529 | g_dbus_connection_signal_unsubscribe(p->bus, GPOINTER_TO_UINT(l->data)); |
530 | g_slist_free(p->subscriptions); |
531 | p->subscriptions = NULL; |
532 | - |
533 | - /* clear the bus */ |
534 | - g_clear_object(&p->bus); |
535 | } |
536 | |
537 | /*** |
538 | @@ -518,6 +513,8 @@ |
539 | **** GObject virtual functions |
540 | ***/ |
541 | |
542 | +static void set_bus (IndicatorPowerDeviceProviderUPower * self, GDBusConnection * connection); |
543 | + |
544 | static void |
545 | my_dispose (GObject * o) |
546 | { |
547 | @@ -541,13 +538,7 @@ |
548 | p->queued_paths_timer = 0; |
549 | } |
550 | |
551 | - if (p->name_tag != 0) |
552 | - { |
553 | - g_bus_unwatch_name(p->name_tag); |
554 | - on_bus_name_vanished(NULL, NULL, self); |
555 | - |
556 | - p->name_tag = 0; |
557 | - } |
558 | + set_bus (self, NULL); |
559 | |
560 | G_OBJECT_CLASS (indicator_power_device_provider_upower_parent_class)->dispose(o); |
561 | } |
562 | @@ -568,6 +559,61 @@ |
563 | } |
564 | |
565 | /*** |
566 | +**** Bus |
567 | +***/ |
568 | + |
569 | +static void |
570 | +set_bus (IndicatorPowerDeviceProviderUPower * self, GDBusConnection * bus) |
571 | +{ |
572 | + priv_t * p = get_priv(self); |
573 | + |
574 | + if (p->bus != NULL) |
575 | + { |
576 | + g_bus_unwatch_name(p->name_tag); |
577 | + on_bus_name_vanished(NULL, NULL, self); |
578 | + p->name_tag = 0; |
579 | + |
580 | + g_clear_object(&p->bus); |
581 | + } |
582 | + |
583 | + if (bus != NULL) |
584 | + { |
585 | + p->bus = g_object_ref(bus); |
586 | + g_debug("%s: using bus '%s'", G_STRFUNC, g_dbus_connection_get_unique_name(bus)); |
587 | + |
588 | + p->name_tag = g_bus_watch_name_on_connection(p->bus, |
589 | + indicator_power_get_upower_busname(), |
590 | + G_BUS_NAME_WATCHER_FLAGS_NONE, |
591 | + on_bus_name_appeared, |
592 | + on_bus_name_vanished, |
593 | + self, |
594 | + NULL); |
595 | + } |
596 | +} |
597 | + |
598 | +static void |
599 | +on_bus_ready (GObject * unused G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) |
600 | +{ |
601 | + GDBusConnection * bus; |
602 | + GError * error = NULL; |
603 | + |
604 | + bus = indicator_power_get_bus_finish(res, &error); |
605 | + if (error != NULL) |
606 | + { |
607 | + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) |
608 | + g_warning ("Error getting bus: %s", error->message); |
609 | + |
610 | + g_error_free (error); |
611 | + } |
612 | + else |
613 | + { |
614 | + set_bus (INDICATOR_POWER_DEVICE_PROVIDER_UPOWER(gself), bus); |
615 | + } |
616 | + |
617 | + g_clear_object(&bus); |
618 | +} |
619 | + |
620 | +/*** |
621 | **** Instantiation |
622 | ***/ |
623 | |
624 | @@ -603,13 +649,11 @@ |
625 | g_free, |
626 | NULL); |
627 | |
628 | - p->name_tag = g_bus_watch_name(G_BUS_TYPE_SYSTEM, |
629 | - BUS_NAME, |
630 | - G_BUS_NAME_WATCHER_FLAGS_NONE, |
631 | - on_bus_name_appeared, |
632 | - on_bus_name_vanished, |
633 | - self, |
634 | - NULL); |
635 | + indicator_power_get_bus(g_getenv("INDICATOR_POWER_BUS_ADDRESS_UPOWER"), |
636 | + G_BUS_TYPE_SYSTEM, |
637 | + p->cancellable, |
638 | + on_bus_ready, |
639 | + self); |
640 | } |
641 | |
642 | /*** |
643 | |
644 | === modified file 'src/service.c' |
645 | --- src/service.c 2014-10-14 19:07:50 +0000 |
646 | +++ src/service.c 2015-01-12 23:02:27 +0000 |
647 | @@ -22,6 +22,7 @@ |
648 | #include <gio/gio.h> |
649 | #include <url-dispatcher.h> |
650 | |
651 | +#include "bus.h" |
652 | #include "brightness.h" |
653 | #include "dbus-shared.h" |
654 | #include "device.h" |
655 | @@ -29,7 +30,6 @@ |
656 | #include "notifier.h" |
657 | #include "service.h" |
658 | |
659 | -#define BUS_NAME "com.canonical.indicator.power" |
660 | #define BUS_PATH "/com/canonical/indicator/power" |
661 | |
662 | #define SETTINGS_SHOW_TIME_S "show-time" |
663 | @@ -108,7 +108,7 @@ |
664 | |
665 | guint own_id; |
666 | guint actions_export_id; |
667 | - GDBusConnection * conn; |
668 | + GDBusConnection * bus; |
669 | |
670 | struct ProfileMenuInfo menus[N_PROFILES]; |
671 | |
672 | @@ -581,7 +581,7 @@ |
673 | g_simple_action_set_state (p->header_action, create_header_state (self)); |
674 | } |
675 | |
676 | - if (p->conn == NULL) /* we haven't built the menus yet */ |
677 | + if (p->bus == NULL) /* we haven't built the menus yet */ |
678 | return; |
679 | |
680 | if (sections & SECTION_DEVICES) |
681 | @@ -822,108 +822,6 @@ |
682 | } |
683 | |
684 | /*** |
685 | -**** GDBus Name Ownership & Menu / Action Exporting |
686 | -***/ |
687 | - |
688 | -static void |
689 | -on_bus_acquired (GDBusConnection * connection, |
690 | - const gchar * name, |
691 | - gpointer gself) |
692 | -{ |
693 | - int i; |
694 | - guint id; |
695 | - GError * err = NULL; |
696 | - IndicatorPowerService * self = INDICATOR_POWER_SERVICE(gself); |
697 | - priv_t * p = self->priv; |
698 | - GString * path = g_string_new (NULL); |
699 | - |
700 | - g_debug ("bus acquired: %s", name); |
701 | - |
702 | - p->conn = g_object_ref (G_OBJECT (connection)); |
703 | - g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_BUS]); |
704 | - |
705 | - /* export the battery properties */ |
706 | - indicator_power_notifier_set_bus (p->notifier, connection); |
707 | - |
708 | - /* export the actions */ |
709 | - if ((id = g_dbus_connection_export_action_group (connection, |
710 | - BUS_PATH, |
711 | - G_ACTION_GROUP (p->actions), |
712 | - &err))) |
713 | - { |
714 | - p->actions_export_id = id; |
715 | - } |
716 | - else |
717 | - { |
718 | - g_warning ("cannot export action group: %s", err->message); |
719 | - g_clear_error (&err); |
720 | - } |
721 | - |
722 | - /* export the menus */ |
723 | - for (i=0; i<N_PROFILES; ++i) |
724 | - { |
725 | - struct ProfileMenuInfo * menu = &p->menus[i]; |
726 | - |
727 | - g_string_printf (path, "%s/%s", BUS_PATH, menu_names[i]); |
728 | - |
729 | - if ((id = g_dbus_connection_export_menu_model (connection, |
730 | - path->str, |
731 | - G_MENU_MODEL (menu->menu), |
732 | - &err))) |
733 | - { |
734 | - menu->export_id = id; |
735 | - } |
736 | - else |
737 | - { |
738 | - g_warning ("cannot export %s menu: %s", path->str, err->message); |
739 | - g_clear_error (&err); |
740 | - } |
741 | - } |
742 | - |
743 | - g_string_free (path, TRUE); |
744 | -} |
745 | - |
746 | -static void |
747 | -unexport (IndicatorPowerService * self) |
748 | -{ |
749 | - int i; |
750 | - priv_t * p = self->priv; |
751 | - |
752 | - /* unexport the menus */ |
753 | - for (i=0; i<N_PROFILES; ++i) |
754 | - { |
755 | - guint * id = &self->priv->menus[i].export_id; |
756 | - |
757 | - if (*id) |
758 | - { |
759 | - g_dbus_connection_unexport_menu_model (p->conn, *id); |
760 | - *id = 0; |
761 | - } |
762 | - } |
763 | - |
764 | - /* unexport the actions */ |
765 | - if (p->actions_export_id) |
766 | - { |
767 | - g_dbus_connection_unexport_action_group (p->conn, p->actions_export_id); |
768 | - p->actions_export_id = 0; |
769 | - } |
770 | -} |
771 | - |
772 | -static void |
773 | -on_name_lost (GDBusConnection * connection G_GNUC_UNUSED, |
774 | - const gchar * name, |
775 | - gpointer gself) |
776 | -{ |
777 | - IndicatorPowerService * self = INDICATOR_POWER_SERVICE (gself); |
778 | - |
779 | - g_debug ("%s %s name lost %s", G_STRLOC, G_STRFUNC, name); |
780 | - |
781 | - unexport (self); |
782 | - |
783 | - g_signal_emit (self, signals[SIGNAL_NAME_LOST], 0, NULL); |
784 | -} |
785 | - |
786 | -/*** |
787 | **** Events |
788 | ***/ |
789 | |
790 | @@ -980,7 +878,7 @@ |
791 | switch (property_id) |
792 | { |
793 | case PROP_BUS: |
794 | - g_value_set_object (value, p->conn); |
795 | + g_value_set_object (value, p->bus); |
796 | break; |
797 | |
798 | case PROP_DEVICE_PROVIDER: |
799 | @@ -1011,19 +909,15 @@ |
800 | } |
801 | } |
802 | |
803 | +static void set_bus (IndicatorPowerService*, GDBusConnection*); |
804 | + |
805 | static void |
806 | my_dispose (GObject * o) |
807 | { |
808 | IndicatorPowerService * self = INDICATOR_POWER_SERVICE(o); |
809 | priv_t * p = self->priv; |
810 | |
811 | - if (p->own_id) |
812 | - { |
813 | - g_bus_unown_name (p->own_id); |
814 | - p->own_id = 0; |
815 | - } |
816 | - |
817 | - unexport (self); |
818 | + set_bus(self, NULL); |
819 | |
820 | if (p->cancellable != NULL) |
821 | { |
822 | @@ -1045,14 +939,161 @@ |
823 | g_clear_object (&p->header_action); |
824 | g_clear_object (&p->actions); |
825 | |
826 | - g_clear_object (&p->conn); |
827 | - |
828 | indicator_power_service_set_device_provider (self, NULL); |
829 | |
830 | G_OBJECT_CLASS (indicator_power_service_parent_class)->dispose (o); |
831 | } |
832 | |
833 | /*** |
834 | +**** |
835 | +***/ |
836 | + |
837 | +static void |
838 | +unexport (IndicatorPowerService * self) |
839 | +{ |
840 | + int i; |
841 | + priv_t * p = self->priv; |
842 | + |
843 | + /* unexport the menus */ |
844 | + for (i=0; i<N_PROFILES; ++i) |
845 | + { |
846 | + guint * id = &self->priv->menus[i].export_id; |
847 | + |
848 | + if (*id) |
849 | + { |
850 | + g_dbus_connection_unexport_menu_model (p->bus, *id); |
851 | + *id = 0; |
852 | + } |
853 | + } |
854 | + |
855 | + /* unexport the actions */ |
856 | + if (p->actions_export_id) |
857 | + { |
858 | + g_dbus_connection_unexport_action_group (p->bus, p->actions_export_id); |
859 | + p->actions_export_id = 0; |
860 | + } |
861 | +} |
862 | + |
863 | +static void |
864 | +on_name_lost (GDBusConnection * connection G_GNUC_UNUSED, |
865 | + const gchar * name, |
866 | + gpointer gself) |
867 | +{ |
868 | + IndicatorPowerService * self = INDICATOR_POWER_SERVICE (gself); |
869 | + |
870 | + g_debug ("%s %s name lost %s", G_STRLOC, G_STRFUNC, name); |
871 | + |
872 | + unexport (self); |
873 | + |
874 | + g_signal_emit (self, signals[SIGNAL_NAME_LOST], 0, NULL); |
875 | +} |
876 | + |
877 | +static void |
878 | +export (IndicatorPowerService * self) |
879 | +{ |
880 | + priv_t * p = self->priv; |
881 | + GString * path = g_string_new(NULL); |
882 | + GError * error; |
883 | + guint id; |
884 | + int i; |
885 | + |
886 | + p->own_id = g_bus_own_name_on_connection(p->bus, |
887 | + indicator_power_get_indicator_busname(), |
888 | + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, |
889 | + NULL, |
890 | + on_name_lost, |
891 | + self, |
892 | + NULL); |
893 | + |
894 | + /* export the battery properties */ |
895 | + indicator_power_notifier_set_bus(p->notifier, p->bus); |
896 | + |
897 | + /* export the actions */ |
898 | + error = NULL; |
899 | + if ((id = g_dbus_connection_export_action_group(p->bus, |
900 | + BUS_PATH, |
901 | + G_ACTION_GROUP(p->actions), |
902 | + &error))) |
903 | + { |
904 | + p->actions_export_id = id; |
905 | + } |
906 | + else |
907 | + { |
908 | + g_warning("cannot export action group: %s", error->message); |
909 | + g_clear_error(&error); |
910 | + } |
911 | + |
912 | + /* export the menus */ |
913 | + for (i=0; i<N_PROFILES; ++i) |
914 | + { |
915 | + struct ProfileMenuInfo * menu = &p->menus[i]; |
916 | + |
917 | + g_string_printf (path, "%s/%s", BUS_PATH, menu_names[i]); |
918 | + |
919 | + if ((id = g_dbus_connection_export_menu_model(p->bus, |
920 | + path->str, |
921 | + G_MENU_MODEL (menu->menu), |
922 | + &error))) |
923 | + { |
924 | + menu->export_id = id; |
925 | + } |
926 | + else |
927 | + { |
928 | + g_warning("cannot export %s menu: %s", path->str, error->message); |
929 | + g_clear_error(&error); |
930 | + } |
931 | + } |
932 | + |
933 | + g_string_free (path, TRUE); |
934 | +} |
935 | + |
936 | +static void |
937 | +set_bus (IndicatorPowerService * self, GDBusConnection * bus) |
938 | +{ |
939 | + priv_t * p = self->priv; |
940 | + |
941 | + if (p->bus != NULL) |
942 | + { |
943 | + unexport (self); |
944 | + |
945 | + g_bus_unown_name (p->own_id); |
946 | + p->own_id = 0; |
947 | + |
948 | + g_clear_object(&p->bus); |
949 | + } |
950 | + |
951 | + if (bus != NULL) |
952 | + { |
953 | + p->bus = g_object_ref(bus); |
954 | + g_object_notify_by_pspec(G_OBJECT(self), properties[PROP_BUS]); |
955 | + |
956 | + export(self); |
957 | + } |
958 | +} |
959 | + |
960 | +static void |
961 | +on_bus_ready (GObject * unused G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) |
962 | +{ |
963 | + GDBusConnection * bus; |
964 | + GError * error = NULL; |
965 | + |
966 | + bus = indicator_power_get_bus_finish(res, &error); |
967 | + if (error != NULL) |
968 | + { |
969 | + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) |
970 | + g_warning ("Error getting indicator bus: %s", error->message); |
971 | + |
972 | + g_error_free (error); |
973 | + } |
974 | + else |
975 | + { |
976 | + set_bus (INDICATOR_POWER_SERVICE(gself), bus); |
977 | + } |
978 | + |
979 | + g_clear_object(&bus); |
980 | +} |
981 | + |
982 | +/*** |
983 | **** Instantiation |
984 | ***/ |
985 | |
986 | @@ -1087,14 +1128,11 @@ |
987 | g_signal_connect_swapped(p->brightness, "notify::auto-brightness-supported", |
988 | G_CALLBACK(on_auto_brightness_supported_changed), self); |
989 | |
990 | - p->own_id = g_bus_own_name(G_BUS_TYPE_SESSION, |
991 | - BUS_NAME, |
992 | - G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, |
993 | - on_bus_acquired, |
994 | - NULL, |
995 | - on_name_lost, |
996 | - self, |
997 | - NULL); |
998 | + indicator_power_get_bus(g_getenv("INDICATOR_POWER_BUS_ADDRESS_INDICATOR"), |
999 | + G_BUS_TYPE_SESSION, |
1000 | + p->cancellable, |
1001 | + on_bus_ready, |
1002 | + self); |
1003 | } |
1004 | |
1005 | static void |
PASSED: Continuous integration, rev:283 jenkins. qa.ubuntu. com/job/ indicator- power-ci/ 145/ jenkins. qa.ubuntu. com/job/ indicator- power-vivid- amd64-ci/ 4 jenkins. qa.ubuntu. com/job/ indicator- power-vivid- armhf-ci/ 4 jenkins. qa.ubuntu. com/job/ indicator- power-vivid- armhf-ci/ 4/artifact/ work/output/ *zip*/output. zip
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/indicator- power-ci/ 145/rebuild
http://