Merge lp:~charlesk/indicator-power/custom-bus-for-upower into lp:indicator-power/15.04

Proposed by Charles Kerr
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
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://wiki.ubuntu.com/Process/Merges/Checklists/indicator-power

Yes

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
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_BUS_ADDRESS so that the indicator can be simpler.

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."

review: Approve
Revision history for this message
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_AUTHENTICATION_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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'README'
--- README 1970-01-01 00:00:00 +0000
+++ README 2015-01-12 23:02:27 +0000
@@ -0,0 +1,11 @@
1Environment variables used for testing:
2
3 - INDICATOR_POWER_BUS_ADDRESS_UPOWER overrides the system bus default
4 - INDICATOR_POWER_BUS_NAME_UPOWER overrides the 'org.freedesktop.UPower' default
5
6 - INDICATOR_POWER_BUS_ADDRESS_INDICATOR overrides the session bus default
7 - INDICATOR_POWER_BUS_NAME_INDICATOR overrides the 'com.canonical.indicator.power' default
8
9 - INDICATOR_POWER_BUS_ADDRESS_POWERD overrides the system bus default
10 - INDICATOR_POWER_BUS_NAME_POWERD overrides the 'com.canonical.powerd' default
11
012
=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 2014-10-14 19:09:32 +0000
+++ src/CMakeLists.txt 2015-01-12 23:02:27 +0000
@@ -6,6 +6,7 @@
6# handwritten sources6# handwritten sources
7set(SERVICE_MANUAL_SOURCES7set(SERVICE_MANUAL_SOURCES
8 brightness.c8 brightness.c
9 bus.c
9 device-provider-mock.c10 device-provider-mock.c
10 device-provider-upower.c11 device-provider-upower.c
11 device-provider.c12 device-provider.c
1213
=== modified file 'src/brightness.c'
--- src/brightness.c 2014-09-12 16:37:02 +0000
+++ src/brightness.c 2015-01-12 23:02:27 +0000
@@ -18,6 +18,7 @@
18 */18 */
1919
20#include "brightness.h"20#include "brightness.h"
21#include "bus.h"
2122
22#include <gio/gio.h>23#include <gio/gio.h>
2324
@@ -40,11 +41,11 @@
4041
41typedef struct42typedef struct
42{43{
43 GDBusConnection * system_bus;
44 GCancellable * cancellable;44 GCancellable * cancellable;
4545
46 GSettings * settings;46 GSettings * settings;
4747
48 GDBusConnection * bus;
48 guint powerd_name_tag;49 guint powerd_name_tag;
4950
50 double percentage;51 double percentage;
@@ -124,6 +125,8 @@
124 }125 }
125}126}
126127
128static void set_bus(IndicatorPowerBrightness * self, GDBusConnection * bus);
129
127static void130static void
128my_dispose(GObject * o)131my_dispose(GObject * o)
129{132{
@@ -136,14 +139,9 @@
136 g_clear_object(&p->cancellable);139 g_clear_object(&p->cancellable);
137 }140 }
138141
139 if (p->powerd_name_tag)
140 {
141 g_bus_unwatch_name(p->powerd_name_tag);
142 p->powerd_name_tag = 0;
143 }
144
145 g_clear_object(&p->settings);142 g_clear_object(&p->settings);
146 g_clear_object(&p->system_bus);143
144 set_bus(self, NULL);
147145
148 G_OBJECT_CLASS(indicator_power_brightness_parent_class)->dispose(o);146 G_OBJECT_CLASS(indicator_power_brightness_parent_class)->dispose(o);
149}147}
@@ -269,8 +267,8 @@
269{267{
270 priv_t * p = get_priv(self);268 priv_t * p = get_priv(self);
271269
272 g_dbus_connection_call(p->system_bus,270 g_dbus_connection_call(p->bus,
273 "com.canonical.powerd",271 indicator_power_get_powerd_busname(),
274 "/com/canonical/powerd",272 "/com/canonical/powerd",
275 "com.canonical.powerd",273 "com.canonical.powerd",
276 "getBrightnessParams",274 "getBrightnessParams",
@@ -284,20 +282,13 @@
284}282}
285283
286static void284static void
287on_powerd_appeared(GDBusConnection * connection,285on_powerd_appeared(GDBusConnection * bus G_GNUC_UNUSED,
288 const gchar * bus_name G_GNUC_UNUSED,286 const gchar * bus_name G_GNUC_UNUSED,
289 const gchar * name_owner G_GNUC_UNUSED,287 const gchar * name_owner G_GNUC_UNUSED,
290 gpointer gself)288 gpointer gself)
291{289{
292 IndicatorPowerBrightness * self = INDICATOR_POWER_BRIGHTNESS(gself);
293 priv_t * p = get_priv(self);
294
295 /* keep a handle to the system bus */
296 g_clear_object(&p->system_bus);
297 p->system_bus = g_object_ref(connection);
298
299 /* update our cache of powerd's brightness params */290 /* update our cache of powerd's brightness params */
300 call_powerd_get_brightness_params(self);291 call_powerd_get_brightness_params(gself);
301}292}
302293
303static void294static void
@@ -319,7 +310,7 @@
319/* setUserBrightness doesn't return anything,310/* setUserBrightness doesn't return anything,
320 so this function is just to check for bus error messages */311 so this function is just to check for bus error messages */
321static void312static void
322on_set_uscreen_user_brightness_result(GObject * system_bus,313on_set_uscreen_user_brightness_result(GObject * bus,
323 GAsyncResult * res,314 GAsyncResult * res,
324 gpointer gself G_GNUC_UNUSED)315 gpointer gself G_GNUC_UNUSED)
325{316{
@@ -327,7 +318,7 @@
327 GVariant * v;318 GVariant * v;
328319
329 error = NULL;320 error = NULL;
330 v = g_dbus_connection_call_finish(G_DBUS_CONNECTION(system_bus), res, &error);321 v = g_dbus_connection_call_finish(G_DBUS_CONNECTION(bus), res, &error);
331 if (error != NULL)322 if (error != NULL)
332 {323 {
333 if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))324 if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
@@ -345,8 +336,8 @@
345{336{
346 priv_t * p = get_priv(self);337 priv_t * p = get_priv(self);
347338
348 g_dbus_connection_call(p->system_bus,339 g_dbus_connection_call(p->bus,
349 "com.canonical.Unity.Screen",340 indicator_power_get_screen_busname(),
350 "/com/canonical/Unity/Screen",341 "/com/canonical/Unity/Screen",
351 "com.canonical.Unity.Screen",342 "com.canonical.Unity.Screen",
352 "setUserBrightness",343 "setUserBrightness",
@@ -399,6 +390,58 @@
399 g_object_notify_by_pspec(G_OBJECT(self), properties[PROP_AUTO]);390 g_object_notify_by_pspec(G_OBJECT(self), properties[PROP_AUTO]);
400}391}
401392
393/***
394****
395***/
396
397static void
398set_bus (IndicatorPowerBrightness * self, GDBusConnection * bus)
399{
400 priv_t * p = get_priv(self);
401
402 if (p->bus != NULL)
403 {
404 g_bus_unwatch_name(p->powerd_name_tag);
405 p->powerd_name_tag = 0;
406
407 g_clear_object(&p->bus);
408 }
409
410 if (bus != NULL)
411 {
412 p->bus = g_object_ref(bus);
413
414 p->powerd_name_tag = g_bus_watch_name_on_connection(p->bus,
415 indicator_power_get_powerd_busname(),
416 G_BUS_NAME_WATCHER_FLAGS_NONE,
417 on_powerd_appeared,
418 on_powerd_vanished,
419 self,
420 NULL);
421 }
422}
423
424static void
425on_bus_ready (GObject * unused G_GNUC_UNUSED, GAsyncResult * res, gpointer gself)
426{
427 GDBusConnection * bus;
428 GError * error = NULL;
429
430 bus = indicator_power_get_bus_finish(res, &error);
431 if (error != NULL)
432 {
433 if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
434 g_warning ("Error getting bus: %s", error->message);
435
436 g_error_free (error);
437 }
438 else
439 {
440 set_bus (INDICATOR_POWER_BRIGHTNESS(gself), bus);
441 }
442
443 g_clear_object(&bus);
444}
402445
403/***446/***
404**** Instantiation447**** Instantiation
@@ -433,13 +476,11 @@
433 g_settings_schema_unref(schema);476 g_settings_schema_unref(schema);
434 }477 }
435478
436 p->powerd_name_tag = g_bus_watch_name(G_BUS_TYPE_SYSTEM,479 indicator_power_get_bus(g_getenv("INDICATOR_POWER_BUS_ADDRESS_POWERD"),
437 "com.canonical.powerd",480 G_BUS_TYPE_SYSTEM,
438 G_BUS_NAME_WATCHER_FLAGS_NONE,481 p->cancellable,
439 on_powerd_appeared,482 on_bus_ready,
440 on_powerd_vanished,483 self);
441 self,
442 NULL);
443}484}
444485
445static void486static void
446487
=== added file 'src/bus.c'
--- src/bus.c 1970-01-01 00:00:00 +0000
+++ src/bus.c 2015-01-12 23:02:27 +0000
@@ -0,0 +1,195 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Charles Kerr <charles.kerr@canonical.com>
18 */
19
20#include "bus.h"
21
22typedef GDBusConnection* (*FinishFunc)(GAsyncResult*, GError**);
23
24struct bus_data
25{
26 char * address;
27 FinishFunc finish_func;
28 GSimpleAsyncResult * result;
29};
30
31GDBusConnection*
32indicator_power_get_bus_finish(GAsyncResult * result,
33 GError ** error)
34{
35 GSimpleAsyncResult * simple;
36 GDBusConnection * bus;
37
38 g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, NULL), NULL);
39
40 simple = (GSimpleAsyncResult *) result;
41
42 if (g_simple_async_result_propagate_error (simple, error))
43 return NULL;
44
45 bus = G_DBUS_CONNECTION(g_simple_async_result_get_op_res_gpointer (simple));
46 g_object_ref(bus);
47 return bus;
48}
49
50static void
51on_bus_ready (GObject * unused G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata)
52{
53 struct bus_data * data;
54 GError * error = NULL;
55 GDBusConnection * bus;
56
57 data = gdata;
58 error = NULL;
59 bus = data->finish_func(res, &error);
60 if (error != NULL)
61 {
62 if ((data->address != NULL) && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
63 g_simple_async_result_set_error (data->result, error->domain, error->code, "\"%s\" unreachable, %s", data->address, error->message);
64 else
65 g_simple_async_result_set_from_error (data->result, error);
66
67 g_error_free (error);
68 }
69
70 if (bus != NULL)
71 g_simple_async_result_set_op_res_gpointer(data->result, g_object_ref(bus), g_object_unref);
72 g_simple_async_result_complete_in_idle(data->result);
73
74 g_object_unref(data->result);
75 g_free(data->address);
76 g_free(data);
77}
78
79void indicator_power_get_bus(const char * address,
80 GBusType bus_type,
81 GCancellable * cancellable,
82 GAsyncReadyCallback callback,
83 gpointer user_data)
84{
85 GSimpleAsyncResult * result;
86
87 result = g_simple_async_result_new(NULL,
88 callback,
89 user_data,
90 NULL);
91 g_simple_async_result_set_check_cancellable(result, cancellable);
92
93
94 struct bus_data * data = g_new0(struct bus_data, 1);
95 data->result = result;
96
97 if ((address != NULL) && g_dbus_is_address(address))
98 {
99 g_debug("Getting bus for address '%s'", address);
100 data->address = g_strdup(address);
101 data->finish_func = g_dbus_connection_new_for_address_finish;
102 g_dbus_connection_new_for_address(address,
103 G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION|G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
104 NULL /*GDBusAuthObserver*/,
105 cancellable,
106 on_bus_ready,
107 data);
108 }
109 else
110 {
111 g_debug("Getting GBusType %d", (int)bus_type);
112 data->finish_func = g_dbus_connection_new_for_address_finish;
113 data->finish_func = g_bus_get_finish;
114 g_bus_get(bus_type,
115 cancellable,
116 on_bus_ready,
117 data);
118 }
119}
120
121/***
122****
123***/
124
125static const char*
126get_name_from_env_with_fallback (const char * env, const char * fallback)
127{
128 const char * name = g_getenv(env);
129
130 if ((name == NULL) || !g_dbus_is_name(name))
131 name = fallback;
132
133 return name;
134}
135
136const char*
137indicator_power_get_indicator_busname(void)
138{
139 static const char * name = NULL;
140
141 if (G_UNLIKELY(name == NULL))
142 {
143 name = get_name_from_env_with_fallback("INDICATOR_POWER_BUS_NAME_INDICATOR",
144 "com.canonical.indicator.power");
145 g_debug("%s indicator busname is \"%s\"", G_STRLOC, name);
146 }
147
148 return name;
149}
150
151const char*
152indicator_power_get_upower_busname(void)
153{
154 static const char * name = NULL;
155
156 if (G_UNLIKELY(name == NULL))
157 {
158 name = get_name_from_env_with_fallback("INDICATOR_POWER_BUS_NAME_UPOWER",
159 "org.freedesktop.UPower");
160 g_debug("%s upower busname is \"%s\"", G_STRLOC, name);
161 }
162
163 return name;
164}
165
166const char*
167indicator_power_get_powerd_busname(void)
168{
169 static const char * name = NULL;
170
171 if (G_UNLIKELY(name == NULL))
172 {
173 name = get_name_from_env_with_fallback("INDICATOR_POWER_BUS_NAME_POWERD",
174 "com.canonical.powerd");
175 g_debug("%s powerd busname is \"%s\"", G_STRLOC, name);
176 }
177
178 return name;
179}
180
181const char*
182indicator_power_get_screen_busname(void)
183{
184 static const char * name = NULL;
185
186 if (G_UNLIKELY(name == NULL))
187 {
188 name = get_name_from_env_with_fallback("INDICATOR_POWER_BUS_NAME_SCREEN",
189 "com.canonical.Unity.Screen");
190 g_debug("%s screen busname is \"%s\"", G_STRLOC, name);
191 }
192
193 return name;
194}
195
0196
=== added file 'src/bus.h'
--- src/bus.h 1970-01-01 00:00:00 +0000
+++ src/bus.h 2015-01-12 23:02:27 +0000
@@ -0,0 +1,50 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Charles Kerr <charles.kerr@canonical.com>
18 */
19
20#ifndef __INDICATOR_POWER_BUS_H__
21#define __INDICATOR_POWER_BUS_H__
22
23#include <gio/gio.h>
24
25G_BEGIN_DECLS
26
27const char* indicator_power_get_indicator_busname (void);
28const char* indicator_power_get_powerd_busname (void);
29const char* indicator_power_get_screen_busname (void);
30const char* indicator_power_get_upower_busname (void);
31
32/**
33 * Asynchronously get a bus connection.
34 *
35 * If address_name is a valid address, it's used. Otherwise, the bus_type is retrieved.
36 * This can be used to let a debug bus address override another address; e.g.
37 * indicator_power_get_bus(g_getenv("INDICATOR_POWER_BUS_ADDRESS_UPOWER"), G_BUS_TYPE_SYSTEM, ...
38 */
39void indicator_power_get_bus (const char * address_name,
40 GBusType bus_type,
41 GCancellable * cancellable,
42 GAsyncReadyCallback callback,
43 gpointer user_data);
44
45GDBusConnection* indicator_power_get_bus_finish (GAsyncResult * result,
46 GError ** error);
47
48G_END_DECLS
49
50#endif /* __INDICATOR_POWER_BUS_H__ */
051
=== modified file 'src/device-provider-upower.c'
--- src/device-provider-upower.c 2014-09-08 14:50:22 +0000
+++ src/device-provider-upower.c 2015-01-12 23:02:27 +0000
@@ -17,12 +17,11 @@
17 * with this program. If not, see <http://www.gnu.org/licenses/>.17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */18 */
1919
20#include "bus.h"
20#include "device.h"21#include "device.h"
21#include "device-provider.h"22#include "device-provider.h"
22#include "device-provider-upower.h"23#include "device-provider-upower.h"
2324
24#define BUS_NAME "org.freedesktop.UPower"
25
26#define MGR_IFACE "org.freedesktop.UPower"25#define MGR_IFACE "org.freedesktop.UPower"
27#define MGR_PATH "/org/freedesktop/UPower"26#define MGR_PATH "/org/freedesktop/UPower"
2827
@@ -175,7 +174,7 @@
175 data->self = self;174 data->self = self;
176175
177 g_dbus_connection_call(p->bus,176 g_dbus_connection_call(p->bus,
178 BUS_NAME,177 indicator_power_get_upower_busname(),
179 path,178 path,
180 "org.freedesktop.DBus.Properties",179 "org.freedesktop.DBus.Properties",
181 "GetAll",180 "GetAll",
@@ -409,7 +408,7 @@
409408
410/* start listening for UPower events on the bus */409/* start listening for UPower events on the bus */
411static void410static void
412on_bus_name_appeared(GDBusConnection * bus,411on_bus_name_appeared(GDBusConnection * bus G_GNUC_UNUSED,
413 const gchar * name G_GNUC_UNUSED,412 const gchar * name G_GNUC_UNUSED,
414 const gchar * name_owner,413 const gchar * name_owner,
415 gpointer gself)414 gpointer gself)
@@ -420,7 +419,6 @@
420419
421 self = INDICATOR_POWER_DEVICE_PROVIDER_UPOWER(gself);420 self = INDICATOR_POWER_DEVICE_PROVIDER_UPOWER(gself);
422 p = get_priv(self);421 p = get_priv(self);
423 p->bus = G_DBUS_CONNECTION(g_object_ref(bus));
424422
425 /* listen for signals from the boss */423 /* listen for signals from the boss */
426 tag = g_dbus_connection_signal_subscribe(p->bus,424 tag = g_dbus_connection_signal_subscribe(p->bus,
@@ -450,7 +448,7 @@
450448
451 /* rebuild our devices list */449 /* rebuild our devices list */
452 g_dbus_connection_call(p->bus,450 g_dbus_connection_call(p->bus,
453 BUS_NAME,451 indicator_power_get_upower_busname(),
454 MGR_PATH,452 MGR_PATH,
455 MGR_IFACE,453 MGR_IFACE,
456 "EnumerateDevices",454 "EnumerateDevices",
@@ -490,9 +488,6 @@
490 g_dbus_connection_signal_unsubscribe(p->bus, GPOINTER_TO_UINT(l->data));488 g_dbus_connection_signal_unsubscribe(p->bus, GPOINTER_TO_UINT(l->data));
491 g_slist_free(p->subscriptions);489 g_slist_free(p->subscriptions);
492 p->subscriptions = NULL;490 p->subscriptions = NULL;
493
494 /* clear the bus */
495 g_clear_object(&p->bus);
496}491}
497492
498/***493/***
@@ -518,6 +513,8 @@
518**** GObject virtual functions513**** GObject virtual functions
519***/514***/
520515
516static void set_bus (IndicatorPowerDeviceProviderUPower * self, GDBusConnection * connection);
517
521static void518static void
522my_dispose (GObject * o)519my_dispose (GObject * o)
523{520{
@@ -541,13 +538,7 @@
541 p->queued_paths_timer = 0;538 p->queued_paths_timer = 0;
542 }539 }
543540
544 if (p->name_tag != 0)541 set_bus (self, NULL);
545 {
546 g_bus_unwatch_name(p->name_tag);
547 on_bus_name_vanished(NULL, NULL, self);
548
549 p->name_tag = 0;
550 }
551542
552 G_OBJECT_CLASS (indicator_power_device_provider_upower_parent_class)->dispose(o);543 G_OBJECT_CLASS (indicator_power_device_provider_upower_parent_class)->dispose(o);
553}544}
@@ -568,6 +559,61 @@
568}559}
569560
570/***561/***
562**** Bus
563***/
564
565static void
566set_bus (IndicatorPowerDeviceProviderUPower * self, GDBusConnection * bus)
567{
568 priv_t * p = get_priv(self);
569
570 if (p->bus != NULL)
571 {
572 g_bus_unwatch_name(p->name_tag);
573 on_bus_name_vanished(NULL, NULL, self);
574 p->name_tag = 0;
575
576 g_clear_object(&p->bus);
577 }
578
579 if (bus != NULL)
580 {
581 p->bus = g_object_ref(bus);
582 g_debug("%s: using bus '%s'", G_STRFUNC, g_dbus_connection_get_unique_name(bus));
583
584 p->name_tag = g_bus_watch_name_on_connection(p->bus,
585 indicator_power_get_upower_busname(),
586 G_BUS_NAME_WATCHER_FLAGS_NONE,
587 on_bus_name_appeared,
588 on_bus_name_vanished,
589 self,
590 NULL);
591 }
592}
593
594static void
595on_bus_ready (GObject * unused G_GNUC_UNUSED, GAsyncResult * res, gpointer gself)
596{
597 GDBusConnection * bus;
598 GError * error = NULL;
599
600 bus = indicator_power_get_bus_finish(res, &error);
601 if (error != NULL)
602 {
603 if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
604 g_warning ("Error getting bus: %s", error->message);
605
606 g_error_free (error);
607 }
608 else
609 {
610 set_bus (INDICATOR_POWER_DEVICE_PROVIDER_UPOWER(gself), bus);
611 }
612
613 g_clear_object(&bus);
614}
615
616/***
571**** Instantiation617**** Instantiation
572***/618***/
573619
@@ -603,13 +649,11 @@
603 g_free,649 g_free,
604 NULL);650 NULL);
605651
606 p->name_tag = g_bus_watch_name(G_BUS_TYPE_SYSTEM,652 indicator_power_get_bus(g_getenv("INDICATOR_POWER_BUS_ADDRESS_UPOWER"),
607 BUS_NAME,653 G_BUS_TYPE_SYSTEM,
608 G_BUS_NAME_WATCHER_FLAGS_NONE,654 p->cancellable,
609 on_bus_name_appeared,655 on_bus_ready,
610 on_bus_name_vanished,656 self);
611 self,
612 NULL);
613}657}
614658
615/***659/***
616660
=== modified file 'src/service.c'
--- src/service.c 2014-10-14 19:07:50 +0000
+++ src/service.c 2015-01-12 23:02:27 +0000
@@ -22,6 +22,7 @@
22#include <gio/gio.h>22#include <gio/gio.h>
23#include <url-dispatcher.h>23#include <url-dispatcher.h>
2424
25#include "bus.h"
25#include "brightness.h"26#include "brightness.h"
26#include "dbus-shared.h"27#include "dbus-shared.h"
27#include "device.h"28#include "device.h"
@@ -29,7 +30,6 @@
29#include "notifier.h"30#include "notifier.h"
30#include "service.h"31#include "service.h"
3132
32#define BUS_NAME "com.canonical.indicator.power"
33#define BUS_PATH "/com/canonical/indicator/power"33#define BUS_PATH "/com/canonical/indicator/power"
3434
35#define SETTINGS_SHOW_TIME_S "show-time"35#define SETTINGS_SHOW_TIME_S "show-time"
@@ -108,7 +108,7 @@
108108
109 guint own_id;109 guint own_id;
110 guint actions_export_id;110 guint actions_export_id;
111 GDBusConnection * conn;111 GDBusConnection * bus;
112112
113 struct ProfileMenuInfo menus[N_PROFILES];113 struct ProfileMenuInfo menus[N_PROFILES];
114114
@@ -581,7 +581,7 @@
581 g_simple_action_set_state (p->header_action, create_header_state (self));581 g_simple_action_set_state (p->header_action, create_header_state (self));
582 }582 }
583583
584 if (p->conn == NULL) /* we haven't built the menus yet */584 if (p->bus == NULL) /* we haven't built the menus yet */
585 return;585 return;
586586
587 if (sections & SECTION_DEVICES)587 if (sections & SECTION_DEVICES)
@@ -822,108 +822,6 @@
822}822}
823823
824/***824/***
825**** GDBus Name Ownership & Menu / Action Exporting
826***/
827
828static void
829on_bus_acquired (GDBusConnection * connection,
830 const gchar * name,
831 gpointer gself)
832{
833 int i;
834 guint id;
835 GError * err = NULL;
836 IndicatorPowerService * self = INDICATOR_POWER_SERVICE(gself);
837 priv_t * p = self->priv;
838 GString * path = g_string_new (NULL);
839
840 g_debug ("bus acquired: %s", name);
841
842 p->conn = g_object_ref (G_OBJECT (connection));
843 g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_BUS]);
844
845 /* export the battery properties */
846 indicator_power_notifier_set_bus (p->notifier, connection);
847
848 /* export the actions */
849 if ((id = g_dbus_connection_export_action_group (connection,
850 BUS_PATH,
851 G_ACTION_GROUP (p->actions),
852 &err)))
853 {
854 p->actions_export_id = id;
855 }
856 else
857 {
858 g_warning ("cannot export action group: %s", err->message);
859 g_clear_error (&err);
860 }
861
862 /* export the menus */
863 for (i=0; i<N_PROFILES; ++i)
864 {
865 struct ProfileMenuInfo * menu = &p->menus[i];
866
867 g_string_printf (path, "%s/%s", BUS_PATH, menu_names[i]);
868
869 if ((id = g_dbus_connection_export_menu_model (connection,
870 path->str,
871 G_MENU_MODEL (menu->menu),
872 &err)))
873 {
874 menu->export_id = id;
875 }
876 else
877 {
878 g_warning ("cannot export %s menu: %s", path->str, err->message);
879 g_clear_error (&err);
880 }
881 }
882
883 g_string_free (path, TRUE);
884}
885
886static void
887unexport (IndicatorPowerService * self)
888{
889 int i;
890 priv_t * p = self->priv;
891
892 /* unexport the menus */
893 for (i=0; i<N_PROFILES; ++i)
894 {
895 guint * id = &self->priv->menus[i].export_id;
896
897 if (*id)
898 {
899 g_dbus_connection_unexport_menu_model (p->conn, *id);
900 *id = 0;
901 }
902 }
903
904 /* unexport the actions */
905 if (p->actions_export_id)
906 {
907 g_dbus_connection_unexport_action_group (p->conn, p->actions_export_id);
908 p->actions_export_id = 0;
909 }
910}
911
912static void
913on_name_lost (GDBusConnection * connection G_GNUC_UNUSED,
914 const gchar * name,
915 gpointer gself)
916{
917 IndicatorPowerService * self = INDICATOR_POWER_SERVICE (gself);
918
919 g_debug ("%s %s name lost %s", G_STRLOC, G_STRFUNC, name);
920
921 unexport (self);
922
923 g_signal_emit (self, signals[SIGNAL_NAME_LOST], 0, NULL);
924}
925
926/***
927**** Events825**** Events
928***/826***/
929827
@@ -980,7 +878,7 @@
980 switch (property_id)878 switch (property_id)
981 {879 {
982 case PROP_BUS:880 case PROP_BUS:
983 g_value_set_object (value, p->conn);881 g_value_set_object (value, p->bus);
984 break;882 break;
985883
986 case PROP_DEVICE_PROVIDER:884 case PROP_DEVICE_PROVIDER:
@@ -1011,19 +909,15 @@
1011 }909 }
1012}910}
1013911
912static void set_bus (IndicatorPowerService*, GDBusConnection*);
913
1014static void914static void
1015my_dispose (GObject * o)915my_dispose (GObject * o)
1016{916{
1017 IndicatorPowerService * self = INDICATOR_POWER_SERVICE(o);917 IndicatorPowerService * self = INDICATOR_POWER_SERVICE(o);
1018 priv_t * p = self->priv;918 priv_t * p = self->priv;
1019919
1020 if (p->own_id)920 set_bus(self, NULL);
1021 {
1022 g_bus_unown_name (p->own_id);
1023 p->own_id = 0;
1024 }
1025
1026 unexport (self);
1027921
1028 if (p->cancellable != NULL)922 if (p->cancellable != NULL)
1029 {923 {
@@ -1045,14 +939,161 @@
1045 g_clear_object (&p->header_action);939 g_clear_object (&p->header_action);
1046 g_clear_object (&p->actions);940 g_clear_object (&p->actions);
1047941
1048 g_clear_object (&p->conn);
1049
1050 indicator_power_service_set_device_provider (self, NULL);942 indicator_power_service_set_device_provider (self, NULL);
1051943
1052 G_OBJECT_CLASS (indicator_power_service_parent_class)->dispose (o);944 G_OBJECT_CLASS (indicator_power_service_parent_class)->dispose (o);
1053}945}
1054946
1055/***947/***
948****
949***/
950
951static void
952unexport (IndicatorPowerService * self)
953{
954 int i;
955 priv_t * p = self->priv;
956
957 /* unexport the menus */
958 for (i=0; i<N_PROFILES; ++i)
959 {
960 guint * id = &self->priv->menus[i].export_id;
961
962 if (*id)
963 {
964 g_dbus_connection_unexport_menu_model (p->bus, *id);
965 *id = 0;
966 }
967 }
968
969 /* unexport the actions */
970 if (p->actions_export_id)
971 {
972 g_dbus_connection_unexport_action_group (p->bus, p->actions_export_id);
973 p->actions_export_id = 0;
974 }
975}
976
977static void
978on_name_lost (GDBusConnection * connection G_GNUC_UNUSED,
979 const gchar * name,
980 gpointer gself)
981{
982 IndicatorPowerService * self = INDICATOR_POWER_SERVICE (gself);
983
984 g_debug ("%s %s name lost %s", G_STRLOC, G_STRFUNC, name);
985
986 unexport (self);
987
988 g_signal_emit (self, signals[SIGNAL_NAME_LOST], 0, NULL);
989}
990
991static void
992export (IndicatorPowerService * self)
993{
994 priv_t * p = self->priv;
995 GString * path = g_string_new(NULL);
996 GError * error;
997 guint id;
998 int i;
999
1000 p->own_id = g_bus_own_name_on_connection(p->bus,
1001 indicator_power_get_indicator_busname(),
1002 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,
1003 NULL,
1004 on_name_lost,
1005 self,
1006 NULL);
1007
1008 /* export the battery properties */
1009 indicator_power_notifier_set_bus(p->notifier, p->bus);
1010
1011 /* export the actions */
1012 error = NULL;
1013 if ((id = g_dbus_connection_export_action_group(p->bus,
1014 BUS_PATH,
1015 G_ACTION_GROUP(p->actions),
1016 &error)))
1017 {
1018 p->actions_export_id = id;
1019 }
1020 else
1021 {
1022 g_warning("cannot export action group: %s", error->message);
1023 g_clear_error(&error);
1024 }
1025
1026 /* export the menus */
1027 for (i=0; i<N_PROFILES; ++i)
1028 {
1029 struct ProfileMenuInfo * menu = &p->menus[i];
1030
1031 g_string_printf (path, "%s/%s", BUS_PATH, menu_names[i]);
1032
1033 if ((id = g_dbus_connection_export_menu_model(p->bus,
1034 path->str,
1035 G_MENU_MODEL (menu->menu),
1036 &error)))
1037 {
1038 menu->export_id = id;
1039 }
1040 else
1041 {
1042 g_warning("cannot export %s menu: %s", path->str, error->message);
1043 g_clear_error(&error);
1044 }
1045 }
1046
1047 g_string_free (path, TRUE);
1048}
1049
1050static void
1051set_bus (IndicatorPowerService * self, GDBusConnection * bus)
1052{
1053 priv_t * p = self->priv;
1054
1055 if (p->bus != NULL)
1056 {
1057 unexport (self);
1058
1059 g_bus_unown_name (p->own_id);
1060 p->own_id = 0;
1061
1062 g_clear_object(&p->bus);
1063 }
1064
1065 if (bus != NULL)
1066 {
1067 p->bus = g_object_ref(bus);
1068 g_object_notify_by_pspec(G_OBJECT(self), properties[PROP_BUS]);
1069
1070 export(self);
1071 }
1072}
1073
1074static void
1075on_bus_ready (GObject * unused G_GNUC_UNUSED, GAsyncResult * res, gpointer gself)
1076{
1077 GDBusConnection * bus;
1078 GError * error = NULL;
1079
1080 bus = indicator_power_get_bus_finish(res, &error);
1081 if (error != NULL)
1082 {
1083 if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
1084 g_warning ("Error getting indicator bus: %s", error->message);
1085
1086 g_error_free (error);
1087 }
1088 else
1089 {
1090 set_bus (INDICATOR_POWER_SERVICE(gself), bus);
1091 }
1092
1093 g_clear_object(&bus);
1094}
1095
1096/***
1056**** Instantiation1097**** Instantiation
1057***/1098***/
10581099
@@ -1087,14 +1128,11 @@
1087 g_signal_connect_swapped(p->brightness, "notify::auto-brightness-supported",1128 g_signal_connect_swapped(p->brightness, "notify::auto-brightness-supported",
1088 G_CALLBACK(on_auto_brightness_supported_changed), self);1129 G_CALLBACK(on_auto_brightness_supported_changed), self);
10891130
1090 p->own_id = g_bus_own_name(G_BUS_TYPE_SESSION,1131 indicator_power_get_bus(g_getenv("INDICATOR_POWER_BUS_ADDRESS_INDICATOR"),
1091 BUS_NAME,1132 G_BUS_TYPE_SESSION,
1092 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,1133 p->cancellable,
1093 on_bus_acquired,1134 on_bus_ready,
1094 NULL,1135 self);
1095 on_name_lost,
1096 self,
1097 NULL);
1098}1136}
10991137
1100static void1138static void

Subscribers

People subscribed via source and target branches