Merge lp://qastaging/~ted/libindicator/service-management into lp://qastaging/libindicator/0.4
- service-management
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp://qastaging/~ted/libindicator/service-management |
Merge into: | lp://qastaging/libindicator/0.4 |
Diff against target: |
1386 lines 18 files modified
.bzrignore (+14/-0) libindicator/Makefile.am (+37/-2) libindicator/dbus-shared.h (+6/-0) libindicator/indicator-object.c (+3/-3) libindicator/indicator-object.h (+2/-2) libindicator/indicator-service-manager.c (+334/-0) libindicator/indicator-service-manager.h (+63/-0) libindicator/indicator-service.c (+334/-0) libindicator/indicator-service.h (+60/-0) libindicator/indicator-service.xml (+17/-0) libindicator/indicator.pc.in (+1/-1) tests/Makefile.am (+104/-7) tests/service-manager-connect-service.c (+46/-0) tests/service-manager-connect.c (+47/-0) tests/service-manager-connect.service.in (+3/-0) tests/service-manager-no-connect.c (+47/-0) tests/service-shutdown-timeout.c (+46/-0) tests/session.conf.in (+40/-0) |
To merge this branch: | bzr merge lp://qastaging/~ted/libindicator/service-management |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Robert Collins (community) | Abstain | ||
Review via email:
|
Commit message
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ted Gould (ted) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Robert Collins (lifeless) wrote : | # |
On Wed, 2009-11-04 at 02:35 +0000, Ted Gould wrote:
>
> === modified file '.bzrignore'
> --- .bzrignore 2009-10-12 03:06:46 +0000
> +++ .bzrignore 2009-11-04 02:35:19 +0000
> @@ -117,3 +117,17 @@
These two:
> +libindicator/
> +libindicator/
Look bogus. I realise they aren't, but it would be nice if we could make
them clearly trash in the tree - e.g. put them in a 'generated' or
'temp' or 'local' or something directory.
> +static void
> +indicator_
> +{
> + IndicatorServic
> INDICATOR_
> +
> + /* If we were connected we need to make sure to
> + tell people that it's no longer the case. */
> + if (priv->connected) {
This:
> + priv->connected = FALSE;
> + g_signal_
> FALSE, TRUE);
> + }
Looks like something to factor out into a private helper for
disconnections that aren't disposals.
...
> + }
> +
> + return;
> +}
:(. :)
> +static void
> +watch_cb (DBusGProxy * proxy, gint version, GError * error, gpointer
> user_data)
perhaps s/version/
> + /* Buffer */
> + void (*indicator_
> + void (*indicator_
> + void (*indicator_
> + void (*indicator_
> +};
Perhaps here and below would be nicer as:
void (*reserved)[4] or
void (*indicator_
> + } else {
> + g_warning("Name is a string bud.");
+loader-tester: test-loader libdummy-
libdummy-
> + @echo "#!/bin/sh" > loader-tester
> + @echo gtester -k --verbose -o=$(XML_REPORT) ./test-loader >>
> loader-tester
> + @chmod +x loader-tester
Whats this indirection for ? seems like a simple
check-local: test-loader libdummy-
libdummy-
gtester -k --verbose -o=$(XML_REPORT) ./test-loader >> loader-tester
would be a lot cleaner
Other than that, +1
review: abstain
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ted Gould (ted) wrote : | # |
On Wed, 2009-11-04 at 04:12 +0000, Robert Collins wrote:
> On Wed, 2009-11-04 at 02:35 +0000, Ted Gould wrote:
> > === modified file '.bzrignore'
> > --- .bzrignore 2009-10-12 03:06:46 +0000
> > +++ .bzrignore 2009-11-04 02:35:19 +0000
> > @@ -117,3 +117,17 @@
> These two:
> > +libindicator/
> > +libindicator/
>
> Look bogus. I realise they aren't, but it would be nice if we could make
> them clearly trash in the tree - e.g. put them in a 'generated' or
> 'temp' or 'local' or something directory.
Honestly, I'm not sure how to make automake do that. Patches welcome :)
The problem is the names are generated off of the xml file name and I'm
not sure how to do paths with all that.
> > +static void
> > +indicator_
> > +{
> > + IndicatorServic
> > INDICATOR_
> > +
> > + /* If we were connected we need to make sure to
> > + tell people that it's no longer the case. */
> > + if (priv->connected) {
>
> This:
>
> > + priv->connected = FALSE;
> > + g_signal_
> > FALSE, TRUE);
> > + }
>
> Looks like something to factor out into a private helper for
> disconnections that aren't disposals.
I think that'd be a premature optimization at this point. I'm not
entirely sure how all the DBus watcher stuff is going to work out when
it's complete, so it's probably not worth optimizing quite yet.
> > +static void
> > +watch_cb (DBusGProxy * proxy, gint version, GError * error, gpointer
> > user_data)
>
> perhaps s/version/
Fixed r370.
> > + /* Buffer */
> > + void (*indicator_
> > + void (*indicator_
> > + void (*indicator_
> > + void (*indicator_
> > +};
>
> Perhaps here and below would be nicer as:
> void (*reserved)[4] or
> void (*indicator_
I'm not sure why it's done this way, but this matches the style that is
in GTK pretty much everywhere.
Cody, do know if there's a reason for this?
> > + } else {
> > + g_warning("Name is a string bud.");
>
> ^^^^ ???
Short for "buddy". Fixed r371 -- support i18n of English :)
> +loader-tester: test-loader libdummy-
> libdummy-
> > + @echo "#!/bin/sh" > loader-tester
> > + @echo gtester -k --verbose -o=$(XML_REPORT) ./test-loader >>
> > loader-tester
> > + @chmod +x loader-tester
>
> Whats this indirection for ? seems like a simple
> check-local: test-loader libdummy-
> libdummy-
> gtester -k --verbose -o=$(XML_REPORT) ./test-loader >> loader-tester
>
> would be a lot cleaner
The problem is that if you use gtester with other tests then your
reporting kinda sucks. If you use it through TESTS then you get the
nice "1 of 3...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Robert Collins (lifeless) wrote : | # |
On Wed, 2009-11-04 at 04:48 +0000, Ted Gould wrote:
>
> The problem is that if you use gtester with other tests then your
> reporting kinda sucks. If you use it through TESTS then you get the
> nice "1 of 3 failed" or some other information from autotest. If you
> want to use TESTS then they have to be shell scripts.
Do you mean 'If we have some gtester and some non-gtester tests' ?
I think the indirection through a shell script is much less clear than
runnning the test directly, and the gain (autotester knows how many
groups of tests are being run) is minimal. If you have multiple
directories with tests, or complex environments, then autotester loses
this data anyway. If we want consolidated reporting, generating subunit
logs and reporting from them is probably a lot saner.
For now I think its better to keep things as clear and shallow as
possible: as long as the test fails causes a build failure, thats the
key thing.
-Rob
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ted Gould (ted) wrote : | # |
On Wed, 2009-11-04 at 05:24 +0000, Robert Collins wrote:
> On Wed, 2009-11-04 at 04:48 +0000, Ted Gould wrote:
> > The problem is that if you use gtester with other tests then your
> > reporting kinda sucks. If you use it through TESTS then you get the
> > nice "1 of 3 failed" or some other information from autotest. If you
> > want to use TESTS then they have to be shell scripts.
>
> Do you mean 'If we have some gtester and some non-gtester tests' ?
No, we have this situation for anything that uses dbus as we have to run
them under dbus-test-runner to setup unique busses for the testing. And
that's why it changed in this version as this is the first that does
dbus testing.
> I think the indirection through a shell script is much less clear than
> runnning the test directly, and the gain (autotester knows how many
> groups of tests are being run) is minimal. If you have multiple
> directories with tests, or complex environments, then autotester loses
> this data anyway. If we want consolidated reporting, generating subunit
> logs and reporting from them is probably a lot saner.
Sure, I'm not sure how to achieve that. I'm just looking for them
running and giving me readable errors :)
Preview Diff
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2009-10-12 03:06:46 +0000 |
3 | +++ .bzrignore 2009-11-04 04:44:10 +0000 |
4 | @@ -117,3 +117,17 @@ |
5 | tests/libdummy_indicator_blank_la-dummy-indicator-blank.lo |
6 | libindicator-[0-9].[0-9].[0-9].tar.gz |
7 | libindicator-[0-9].[0-9].[0-9].tar.gz.asc |
8 | +libindicator/indicator-service-client.h |
9 | +libindicator/indicator-service-server.h |
10 | +libindicator/libindicator_la-indicator-service.lo |
11 | +libindicator/libindicator_la-indicator-service-manager.lo |
12 | +tests/service-shutdown-timeout |
13 | +tests/loader-tester |
14 | +tests/service-shutdown-timeout-tester |
15 | +tests/service-manager-no-connect |
16 | +tests/service-manager-no-connect-tester |
17 | +tests/service-manager-connect |
18 | +tests/service-manager-connect-service |
19 | +tests/service-manager-connect-tester |
20 | +tests/session.conf |
21 | +tests/service-manager-connect.service |
22 | |
23 | === modified file 'libindicator/Makefile.am' |
24 | --- libindicator/Makefile.am 2009-10-06 20:32:23 +0000 |
25 | +++ libindicator/Makefile.am 2009-11-04 04:44:10 +0000 |
26 | @@ -1,3 +1,5 @@ |
27 | +BUILT_SOURCES = |
28 | +CLEANFILES = |
29 | EXTRA_DIST = \ |
30 | indicator.pc.in |
31 | |
32 | @@ -5,7 +7,9 @@ |
33 | |
34 | indicator_headers = \ |
35 | indicator.h \ |
36 | - indicator-object.h |
37 | + indicator-object.h \ |
38 | + indicator-service.h \ |
39 | + indicator-service-manager.h |
40 | |
41 | libindicatorinclude_HEADERS = \ |
42 | $(indicator_headers) |
43 | @@ -15,7 +19,10 @@ |
44 | |
45 | libindicator_la_SOURCES = \ |
46 | $(indicator_headers) \ |
47 | - indicator-object.c |
48 | + dbus-shared.h \ |
49 | + indicator-object.c \ |
50 | + indicator-service.c \ |
51 | + indicator-service-manager.c |
52 | |
53 | libindicator_la_CFLAGS = \ |
54 | $(LIBINDICATOR_CFLAGS) \ |
55 | @@ -27,3 +34,31 @@ |
56 | pkgconfig_DATA = indicator.pc |
57 | pkgconfigdir = $(libdir)/pkgconfig |
58 | |
59 | +################################## |
60 | +# DBus Specs |
61 | +################################## |
62 | + |
63 | +DBUS_SPECS = \ |
64 | + indicator-service.xml |
65 | + |
66 | +%-client.h: %.xml |
67 | + dbus-binding-tool \ |
68 | + --prefix=_$(subst -,_,$(basename $(notdir $<)))_client \ |
69 | + --mode=glib-client \ |
70 | + --output=$@ \ |
71 | + $< |
72 | + |
73 | +%-server.h: %.xml |
74 | + dbus-binding-tool \ |
75 | + --prefix=_$(subst -,_,$(basename $(notdir $<)))_server \ |
76 | + --mode=glib-server \ |
77 | + --output=$@ \ |
78 | + $< |
79 | + |
80 | +BUILT_SOURCES += \ |
81 | + $(DBUS_SPECS:.xml=-client.h) \ |
82 | + $(DBUS_SPECS:.xml=-server.h) |
83 | + |
84 | +CLEANFILES += $(BUILT_SOURCES) |
85 | + |
86 | +EXTRA_DIST += $(DBUS_SPECS) |
87 | |
88 | === added file 'libindicator/dbus-shared.h' |
89 | --- libindicator/dbus-shared.h 1970-01-01 00:00:00 +0000 |
90 | +++ libindicator/dbus-shared.h 2009-11-04 04:44:10 +0000 |
91 | @@ -0,0 +1,6 @@ |
92 | + |
93 | +#define INDICATOR_SERVICE_INTERFACE "org.ayatana.indicator.service" |
94 | +#define INDICATOR_SERVICE_OBJECT "/org/ayatana/indicator/service" |
95 | + |
96 | +#define INDICATOR_SERVICE_VERSION 1 |
97 | + |
98 | |
99 | === modified file 'libindicator/indicator-object.c' |
100 | --- libindicator/indicator-object.c 2009-11-03 23:06:39 +0000 |
101 | +++ libindicator/indicator-object.c 2009-11-04 04:44:10 +0000 |
102 | @@ -248,7 +248,7 @@ |
103 | GtkLabel * |
104 | indicator_object_get_label (IndicatorObject * io) |
105 | { |
106 | - g_return_val_if_fail(IS_INDICATOR_OBJECT(io), NULL); |
107 | + g_return_val_if_fail(INDICATOR_IS_OBJECT(io), NULL); |
108 | IndicatorObjectPrivate * priv = INDICATOR_OBJECT_GET_PRIVATE(io); |
109 | return priv->label; |
110 | } |
111 | @@ -266,7 +266,7 @@ |
112 | GtkImage * |
113 | indicator_object_get_icon (IndicatorObject * io) |
114 | { |
115 | - g_return_val_if_fail(IS_INDICATOR_OBJECT(io), NULL); |
116 | + g_return_val_if_fail(INDICATOR_IS_OBJECT(io), NULL); |
117 | IndicatorObjectPrivate * priv = INDICATOR_OBJECT_GET_PRIVATE(io); |
118 | return priv->icon; |
119 | } |
120 | @@ -284,7 +284,7 @@ |
121 | GtkMenu * |
122 | indicator_object_get_menu (IndicatorObject * io) |
123 | { |
124 | - g_return_val_if_fail(IS_INDICATOR_OBJECT(io), NULL); |
125 | + g_return_val_if_fail(INDICATOR_IS_OBJECT(io), NULL); |
126 | IndicatorObjectPrivate * priv = INDICATOR_OBJECT_GET_PRIVATE(io); |
127 | return priv->menu; |
128 | } |
129 | |
130 | === modified file 'libindicator/indicator-object.h' |
131 | --- libindicator/indicator-object.h 2009-11-03 15:31:53 +0000 |
132 | +++ libindicator/indicator-object.h 2009-11-04 04:44:10 +0000 |
133 | @@ -32,8 +32,8 @@ |
134 | #define INDICATOR_OBJECT_TYPE (indicator_object_get_type ()) |
135 | #define INDICATOR_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_OBJECT_TYPE, IndicatorObject)) |
136 | #define INDICATOR_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_OBJECT_TYPE, IndicatorObjectClass)) |
137 | -#define IS_INDICATOR_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_OBJECT_TYPE)) |
138 | -#define IS_INDICATOR_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_OBJECT_TYPE)) |
139 | +#define INDICATOR_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_OBJECT_TYPE)) |
140 | +#define INDICATOR_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_OBJECT_TYPE)) |
141 | #define INDICATOR_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_OBJECT_TYPE, IndicatorObjectClass)) |
142 | |
143 | typedef struct _IndicatorObject IndicatorObject; |
144 | |
145 | === added file 'libindicator/indicator-service-manager.c' |
146 | --- libindicator/indicator-service-manager.c 1970-01-01 00:00:00 +0000 |
147 | +++ libindicator/indicator-service-manager.c 2009-11-04 04:44:10 +0000 |
148 | @@ -0,0 +1,334 @@ |
149 | +#ifdef HAVE_CONFIG_H |
150 | +#include "config.h" |
151 | +#endif |
152 | + |
153 | +#include <dbus/dbus-glib-bindings.h> |
154 | +#include <dbus/dbus-glib-lowlevel.h> |
155 | + |
156 | +#include "indicator-service-manager.h" |
157 | +#include "indicator-service-client.h" |
158 | +#include "dbus-shared.h" |
159 | + |
160 | +/* Private Stuff */ |
161 | +typedef struct _IndicatorServiceManagerPrivate IndicatorServiceManagerPrivate; |
162 | +struct _IndicatorServiceManagerPrivate { |
163 | + gchar * name; |
164 | + DBusGProxy * dbus_proxy; |
165 | + DBusGProxy * service_proxy; |
166 | + gboolean connected; |
167 | +}; |
168 | + |
169 | +/* Signals Stuff */ |
170 | +enum { |
171 | + CONNECTION_CHANGE, |
172 | + LAST_SIGNAL |
173 | +}; |
174 | + |
175 | +static guint signals[LAST_SIGNAL] = { 0 }; |
176 | + |
177 | + |
178 | +/* Properties */ |
179 | +/* Enum for the properties so that they can be quickly |
180 | + found and looked up. */ |
181 | +enum { |
182 | + PROP_0, |
183 | + PROP_NAME, |
184 | +}; |
185 | + |
186 | +/* The strings so that they can be slowly looked up. */ |
187 | +#define PROP_NAME_S "name" |
188 | + |
189 | +/* GObject Stuff */ |
190 | +#define INDICATOR_SERVICE_MANAGER_GET_PRIVATE(o) \ |
191 | +(G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_SERVICE_MANAGER_TYPE, IndicatorServiceManagerPrivate)) |
192 | + |
193 | +static void indicator_service_manager_class_init (IndicatorServiceManagerClass *klass); |
194 | +static void indicator_service_manager_init (IndicatorServiceManager *self); |
195 | +static void indicator_service_manager_dispose (GObject *object); |
196 | +static void indicator_service_manager_finalize (GObject *object); |
197 | + |
198 | +/* Prototypes */ |
199 | +static void set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); |
200 | +static void get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); |
201 | +static void start_service (IndicatorServiceManager * service); |
202 | + |
203 | +G_DEFINE_TYPE (IndicatorServiceManager, indicator_service_manager, G_TYPE_OBJECT); |
204 | + |
205 | +static void |
206 | +indicator_service_manager_class_init (IndicatorServiceManagerClass *klass) |
207 | +{ |
208 | + GObjectClass *object_class = G_OBJECT_CLASS (klass); |
209 | + |
210 | + g_type_class_add_private (klass, sizeof (IndicatorServiceManagerPrivate)); |
211 | + |
212 | + object_class->dispose = indicator_service_manager_dispose; |
213 | + object_class->finalize = indicator_service_manager_finalize; |
214 | + |
215 | + /* Property funcs */ |
216 | + object_class->set_property = set_property; |
217 | + object_class->get_property = get_property; |
218 | + |
219 | + /** |
220 | + IndicatorServiceManager::connecton-change: |
221 | + @arg0: The #IndicatorServiceManager object |
222 | + @arg1: The state of the connection, TRUE is connected. |
223 | + |
224 | + Signaled when the service is connected or disconnected |
225 | + depending on it's previous state. |
226 | + */ |
227 | + signals[CONNECTION_CHANGE] = g_signal_new (INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, |
228 | + G_TYPE_FROM_CLASS(klass), |
229 | + G_SIGNAL_RUN_LAST, |
230 | + G_STRUCT_OFFSET (IndicatorServiceManagerClass, connection_change), |
231 | + NULL, NULL, |
232 | + g_cclosure_marshal_VOID__BOOLEAN, |
233 | + G_TYPE_NONE, 1, G_TYPE_BOOLEAN, G_TYPE_NONE); |
234 | + |
235 | + /* Properties */ |
236 | + g_object_class_install_property(object_class, PROP_NAME, |
237 | + g_param_spec_string(PROP_NAME_S, |
238 | + "The DBus name for the service to monitor", |
239 | + "This is the name that should be used to start a service.", |
240 | + NULL, |
241 | + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
242 | + |
243 | + return; |
244 | +} |
245 | + |
246 | +static void |
247 | +indicator_service_manager_init (IndicatorServiceManager *self) |
248 | +{ |
249 | + IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(self); |
250 | + |
251 | + /* Get the private variables in a decent state */ |
252 | + priv->name = NULL; |
253 | + priv->dbus_proxy = NULL; |
254 | + priv->service_proxy = NULL; |
255 | + priv->connected = FALSE; |
256 | + |
257 | + /* Start talkin' dbus */ |
258 | + GError * error = NULL; |
259 | + DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); |
260 | + if (error != NULL) { |
261 | + g_error("Unable to get session bus: %s", error->message); |
262 | + g_error_free(error); |
263 | + return; |
264 | + } |
265 | + |
266 | + priv->dbus_proxy = dbus_g_proxy_new_for_name_owner(session_bus, |
267 | + DBUS_SERVICE_DBUS, |
268 | + DBUS_PATH_DBUS, |
269 | + DBUS_INTERFACE_DBUS, |
270 | + &error); |
271 | + if (error != NULL) { |
272 | + g_error("Unable to get the proxy to DBus: %s", error->message); |
273 | + g_error_free(error); |
274 | + return; |
275 | + } |
276 | + |
277 | + return; |
278 | +} |
279 | + |
280 | +static void |
281 | +indicator_service_manager_dispose (GObject *object) |
282 | +{ |
283 | + IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(object); |
284 | + |
285 | + /* If we were connected we need to make sure to |
286 | + tell people that it's no longer the case. */ |
287 | + if (priv->connected) { |
288 | + priv->connected = FALSE; |
289 | + g_signal_emit(object, signals[CONNECTION_CHANGE], 0, FALSE, TRUE); |
290 | + } |
291 | + |
292 | + /* Destory our DBus proxy, we won't need it. */ |
293 | + if (priv->dbus_proxy != NULL) { |
294 | + g_object_unref(G_OBJECT(priv->dbus_proxy)); |
295 | + priv->dbus_proxy = NULL; |
296 | + } |
297 | + |
298 | + /* Destory our service proxy, we won't need it. */ |
299 | + if (priv->service_proxy != NULL) { |
300 | + g_object_unref(G_OBJECT(priv->service_proxy)); |
301 | + priv->service_proxy = NULL; |
302 | + } |
303 | + |
304 | + /* Let's see if our parents want to do anything. */ |
305 | + G_OBJECT_CLASS (indicator_service_manager_parent_class)->dispose (object); |
306 | + return; |
307 | +} |
308 | + |
309 | +static void |
310 | +indicator_service_manager_finalize (GObject *object) |
311 | +{ |
312 | + IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(object); |
313 | + |
314 | + if (priv->name != NULL) { |
315 | + g_free(priv->name); |
316 | + priv->name = NULL; |
317 | + } |
318 | + |
319 | + G_OBJECT_CLASS (indicator_service_manager_parent_class)->finalize (object); |
320 | + return; |
321 | +} |
322 | + |
323 | +static void |
324 | +set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) |
325 | +{ |
326 | + IndicatorServiceManager * self = INDICATOR_SERVICE_MANAGER(object); |
327 | + g_return_if_fail(self != NULL); |
328 | + |
329 | + IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(self); |
330 | + g_return_if_fail(priv != NULL); |
331 | + |
332 | + switch (prop_id) { |
333 | + /* *********************** */ |
334 | + case PROP_NAME: |
335 | + if (G_VALUE_HOLDS_STRING(value)) { |
336 | + if (priv->name != NULL) { |
337 | + g_error("Name can not be set twice!"); |
338 | + return; |
339 | + } |
340 | + priv->name = g_value_dup_string(value); |
341 | + start_service(self); |
342 | + } else { |
343 | + g_warning("Name is a string bud."); |
344 | + } |
345 | + break; |
346 | + /* *********************** */ |
347 | + default: |
348 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
349 | + break; |
350 | + } |
351 | + |
352 | + return; |
353 | +} |
354 | + |
355 | +static void |
356 | +get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) |
357 | +{ |
358 | + IndicatorServiceManager * self = INDICATOR_SERVICE_MANAGER(object); |
359 | + g_return_if_fail(self != NULL); |
360 | + |
361 | + IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(self); |
362 | + g_return_if_fail(priv != NULL); |
363 | + |
364 | + switch (prop_id) { |
365 | + /* *********************** */ |
366 | + case PROP_NAME: |
367 | + if (G_VALUE_HOLDS_STRING(value)) { |
368 | + g_value_set_string(value, priv->name); |
369 | + } else { |
370 | + g_warning("Name is a string bud."); |
371 | + } |
372 | + break; |
373 | + /* *********************** */ |
374 | + default: |
375 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
376 | + break; |
377 | + } |
378 | + |
379 | + return; |
380 | +} |
381 | + |
382 | +static void |
383 | +watch_cb (DBusGProxy * proxy, gint service_version, GError * error, gpointer user_data) |
384 | +{ |
385 | + IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(user_data); |
386 | + |
387 | + if (error != NULL) { |
388 | + g_warning("Unable to set watch on '%s': '%s'", priv->name, error->message); |
389 | + g_error_free(error); |
390 | + return; |
391 | + } |
392 | + |
393 | + if (service_version != INDICATOR_SERVICE_VERSION) { |
394 | + g_warning("Service is using a different version of the service interface. Expecting %d and got %d.", INDICATOR_SERVICE_VERSION, service_version); |
395 | + return; |
396 | + } |
397 | + |
398 | + if (!priv->connected) { |
399 | + priv->connected = TRUE; |
400 | + g_signal_emit(G_OBJECT(user_data), signals[CONNECTION_CHANGE], 0, TRUE, TRUE); |
401 | + } |
402 | + |
403 | + return; |
404 | +} |
405 | + |
406 | +static void |
407 | +start_service_cb (DBusGProxy * proxy, guint status, GError * error, gpointer user_data) |
408 | +{ |
409 | + IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(user_data); |
410 | + |
411 | + if (error != NULL) { |
412 | + g_warning("Unable to start service '%s': %s", priv->name, error->message); |
413 | + return; |
414 | + } |
415 | + |
416 | + if (status != DBUS_START_REPLY_SUCCESS && status != DBUS_START_REPLY_ALREADY_RUNNING) { |
417 | + g_warning("Status of starting the process '%s' was an error: %d", priv->name, status); |
418 | + return; |
419 | + } |
420 | + |
421 | + /* Woot! it's running. Let's do it some more. */ |
422 | + DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); |
423 | + if (error != NULL) { |
424 | + g_error("Unable to get session bus: %s", error->message); |
425 | + g_error_free(error); |
426 | + return; |
427 | + } |
428 | + |
429 | + priv->service_proxy = dbus_g_proxy_new_for_name_owner(session_bus, |
430 | + priv->name, |
431 | + INDICATOR_SERVICE_OBJECT, |
432 | + INDICATOR_SERVICE_INTERFACE, |
433 | + &error); |
434 | + |
435 | + org_ayatana_indicator_service_watch_async(priv->service_proxy, |
436 | + watch_cb, |
437 | + user_data); |
438 | + |
439 | + return; |
440 | +} |
441 | + |
442 | +static void |
443 | +start_service (IndicatorServiceManager * service) |
444 | +{ |
445 | + IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(service); |
446 | + |
447 | + g_return_if_fail(priv->dbus_proxy != NULL); |
448 | + g_return_if_fail(priv->name != NULL); |
449 | + |
450 | + org_freedesktop_DBus_start_service_by_name_async (priv->dbus_proxy, |
451 | + priv->name, |
452 | + 0, |
453 | + start_service_cb, |
454 | + service); |
455 | + |
456 | + return; |
457 | +} |
458 | + |
459 | +/* API */ |
460 | +IndicatorServiceManager * |
461 | +indicator_service_manager_new (gchar * dbus_name) |
462 | +{ |
463 | + GObject * obj = g_object_new(INDICATOR_SERVICE_MANAGER_TYPE, |
464 | + PROP_NAME_S, dbus_name, |
465 | + NULL); |
466 | + |
467 | + return INDICATOR_SERVICE_MANAGER(obj); |
468 | +} |
469 | + |
470 | +gboolean |
471 | +indicator_service_manager_connected (IndicatorServiceManager * sm) |
472 | +{ |
473 | + |
474 | + return FALSE; |
475 | +} |
476 | + |
477 | +void |
478 | +indicator_service_manager_set_refresh (IndicatorServiceManager * sm, guint time_in_ms) |
479 | +{ |
480 | + |
481 | + return; |
482 | +} |
483 | |
484 | === added file 'libindicator/indicator-service-manager.h' |
485 | --- libindicator/indicator-service-manager.h 1970-01-01 00:00:00 +0000 |
486 | +++ libindicator/indicator-service-manager.h 2009-11-04 04:44:10 +0000 |
487 | @@ -0,0 +1,63 @@ |
488 | +#ifndef __INDICATOR_SERVICE_MANAGER_H__ |
489 | +#define __INDICATOR_SERVICE_MANAGER_H__ |
490 | + |
491 | +#include <glib.h> |
492 | +#include <glib-object.h> |
493 | + |
494 | +G_BEGIN_DECLS |
495 | + |
496 | +#define INDICATOR_SERVICE_MANAGER_TYPE (indicator_service_manager_get_type ()) |
497 | +#define INDICATOR_SERVICE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_SERVICE_MANAGER_TYPE, IndicatorServiceManager)) |
498 | +#define INDICATOR_SERVICE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_SERVICE_MANAGER_TYPE, IndicatorServiceManagerClass)) |
499 | +#define INDICATOR_IS_SERVICE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_SERVICE_MANAGER_TYPE)) |
500 | +#define INDICATOR_IS_SERVICE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_SERVICE_MANAGER_TYPE)) |
501 | +#define INDICATOR_SERVICE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_SERVICE_MANAGER_TYPE, IndicatorServiceManagerClass)) |
502 | + |
503 | +#define INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE "connection-change" |
504 | + |
505 | +typedef struct _IndicatorServiceManager IndicatorServiceManager; |
506 | +typedef struct _IndicatorServiceManagerClass IndicatorServiceManagerClass; |
507 | + |
508 | +/** |
509 | + IndicatorServiceManagerClass: |
510 | + @parent: #GObjectClass |
511 | + @connection_changed: Slot for #IndicatorServiceManager::connection-changed. |
512 | + @indicator_service_manager_reserved1: Reserved for future use. |
513 | + @indicator_service_manager_reserved2: Reserved for future use. |
514 | + @indicator_service_manager_reserved3: Reserved for future use. |
515 | + @indicator_service_manager_reserved4: Reserved for future use. |
516 | + |
517 | +*/ |
518 | +struct _IndicatorServiceManagerClass { |
519 | + GObjectClass parent_class; |
520 | + |
521 | + /* Signals */ |
522 | + void (*connection_change) (IndicatorServiceManager * sm, gboolean connected, gpointer user_data); |
523 | + |
524 | + /* Buffer */ |
525 | + void (*indicator_service_manager_reserved1) (void); |
526 | + void (*indicator_service_manager_reserved2) (void); |
527 | + void (*indicator_service_manager_reserved3) (void); |
528 | + void (*indicator_service_manager_reserved4) (void); |
529 | +}; |
530 | + |
531 | +/** |
532 | + IndicatorServiceManager: |
533 | + @parent: #GObject |
534 | + |
535 | +*/ |
536 | +struct _IndicatorServiceManager { |
537 | + GObject parent; |
538 | + |
539 | +}; |
540 | + |
541 | +GType indicator_service_manager_get_type (void); |
542 | + |
543 | +IndicatorServiceManager * indicator_service_manager_new (gchar * dbus_name); |
544 | +gboolean indicator_service_manager_connected (IndicatorServiceManager * sm); |
545 | +void indicator_service_manager_set_refresh (IndicatorServiceManager * sm, |
546 | + guint time_in_ms); |
547 | + |
548 | +G_END_DECLS |
549 | + |
550 | +#endif |
551 | |
552 | === added file 'libindicator/indicator-service.c' |
553 | --- libindicator/indicator-service.c 1970-01-01 00:00:00 +0000 |
554 | +++ libindicator/indicator-service.c 2009-11-04 04:44:10 +0000 |
555 | @@ -0,0 +1,334 @@ |
556 | +#ifdef HAVE_CONFIG_H |
557 | +#include "config.h" |
558 | +#endif |
559 | +#include <dbus/dbus-glib-bindings.h> |
560 | +#include <dbus/dbus-glib-lowlevel.h> |
561 | + |
562 | +#include "indicator-service.h" |
563 | + |
564 | +/* DBus Prototypes */ |
565 | +static gboolean _indicator_service_server_watch (IndicatorService * service, DBusGMethodInvocation * method); |
566 | + |
567 | +#include "indicator-service-server.h" |
568 | +#include "dbus-shared.h" |
569 | + |
570 | +/* Private Stuff */ |
571 | +typedef struct _IndicatorServicePrivate IndicatorServicePrivate; |
572 | + |
573 | +struct _IndicatorServicePrivate { |
574 | + gchar * name; |
575 | + DBusGProxy * dbus_proxy; |
576 | + guint timeout; |
577 | + GList * watchers; |
578 | +}; |
579 | + |
580 | +/* Signals Stuff */ |
581 | +enum { |
582 | + SHUTDOWN, |
583 | + LAST_SIGNAL |
584 | +}; |
585 | + |
586 | +static guint signals[LAST_SIGNAL] = { 0 }; |
587 | + |
588 | +/* Properties */ |
589 | +/* Enum for the properties so that they can be quickly |
590 | + found and looked up. */ |
591 | +enum { |
592 | + PROP_0, |
593 | + PROP_NAME, |
594 | +}; |
595 | + |
596 | +/* The strings so that they can be slowly looked up. */ |
597 | +#define PROP_NAME_S "name" |
598 | + |
599 | +/* GObject Stuff */ |
600 | +#define INDICATOR_SERVICE_GET_PRIVATE(o) \ |
601 | + (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_SERVICE_TYPE, IndicatorServicePrivate)) |
602 | + |
603 | +static void indicator_service_class_init (IndicatorServiceClass *klass); |
604 | +static void indicator_service_init (IndicatorService *self); |
605 | +static void indicator_service_dispose (GObject *object); |
606 | +static void indicator_service_finalize (GObject *object); |
607 | + |
608 | +/* Other prototypes */ |
609 | +static void set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); |
610 | +static void get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); |
611 | +static void try_and_get_name (IndicatorService * service); |
612 | + |
613 | +G_DEFINE_TYPE (IndicatorService, indicator_service, G_TYPE_OBJECT); |
614 | + |
615 | +static void |
616 | +indicator_service_class_init (IndicatorServiceClass *klass) |
617 | +{ |
618 | + GObjectClass *object_class = G_OBJECT_CLASS (klass); |
619 | + |
620 | + g_type_class_add_private (klass, sizeof (IndicatorServicePrivate)); |
621 | + |
622 | + object_class->dispose = indicator_service_dispose; |
623 | + object_class->finalize = indicator_service_finalize; |
624 | + |
625 | + /* Property funcs */ |
626 | + object_class->set_property = set_property; |
627 | + object_class->get_property = get_property; |
628 | + |
629 | + /* Properties */ |
630 | + g_object_class_install_property(object_class, PROP_NAME, |
631 | + g_param_spec_string(PROP_NAME_S, |
632 | + "The DBus name for this service", |
633 | + "This is the name that should be used on DBus for this service.", |
634 | + NULL, |
635 | + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
636 | + |
637 | + /* Signals */ |
638 | + |
639 | + /** |
640 | + IndicatorService::shutdown: |
641 | + @arg0: The #IndicatorService object |
642 | + |
643 | + Signaled when the service should shutdown as no one |
644 | + is listening anymore. |
645 | + */ |
646 | + signals[SHUTDOWN] = g_signal_new (INDICATOR_SERVICE_SIGNAL_SHUTDOWN, |
647 | + G_TYPE_FROM_CLASS(klass), |
648 | + G_SIGNAL_RUN_LAST, |
649 | + G_STRUCT_OFFSET (IndicatorServiceClass, shutdown), |
650 | + NULL, NULL, |
651 | + g_cclosure_marshal_VOID__VOID, |
652 | + G_TYPE_NONE, 0, G_TYPE_NONE); |
653 | + |
654 | + /* Initialize the object as a DBus type */ |
655 | + dbus_g_object_type_install_info(INDICATOR_SERVICE_TYPE, |
656 | + &dbus_glib__indicator_service_server_object_info); |
657 | + |
658 | + return; |
659 | +} |
660 | + |
661 | +static void |
662 | +indicator_service_init (IndicatorService *self) |
663 | +{ |
664 | + IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(self); |
665 | + |
666 | + /* Get the private variables in a decent state */ |
667 | + priv->name = NULL; |
668 | + priv->dbus_proxy = NULL; |
669 | + priv->timeout = 0; |
670 | + priv->watchers = NULL; |
671 | + |
672 | + /* Start talkin' dbus */ |
673 | + GError * error = NULL; |
674 | + DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_STARTER, &error); |
675 | + if (error != NULL) { |
676 | + g_error("Unable to get starter bus: %s", error->message); |
677 | + g_error_free(error); |
678 | + |
679 | + /* Okay, fine let's try the session bus then. */ |
680 | + /* I think this should automatically, but I can't find confirmation |
681 | + of that, so we're putting the extra little code in here. */ |
682 | + error = NULL; |
683 | + bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); |
684 | + if (error != NULL) { |
685 | + g_error("Unable to get session bus: %s", error->message); |
686 | + g_error_free(error); |
687 | + return; |
688 | + } |
689 | + } |
690 | + |
691 | + priv->dbus_proxy = dbus_g_proxy_new_for_name_owner(bus, |
692 | + DBUS_SERVICE_DBUS, |
693 | + DBUS_PATH_DBUS, |
694 | + DBUS_INTERFACE_DBUS, |
695 | + &error); |
696 | + if (error != NULL) { |
697 | + g_error("Unable to get the proxy to DBus: %s", error->message); |
698 | + g_error_free(error); |
699 | + return; |
700 | + } |
701 | + |
702 | + dbus_g_connection_register_g_object(bus, |
703 | + INDICATOR_SERVICE_OBJECT, |
704 | + G_OBJECT(self)); |
705 | + |
706 | + return; |
707 | +} |
708 | + |
709 | +static void |
710 | +indicator_service_dispose (GObject *object) |
711 | +{ |
712 | + IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(object); |
713 | + |
714 | + if (priv->dbus_proxy != NULL) { |
715 | + g_object_unref(G_OBJECT(priv->dbus_proxy)); |
716 | + priv->dbus_proxy = NULL; |
717 | + } |
718 | + |
719 | + if (priv->timeout != 0) { |
720 | + g_source_remove(priv->timeout); |
721 | + priv->timeout = 0; |
722 | + } |
723 | + |
724 | + G_OBJECT_CLASS (indicator_service_parent_class)->dispose (object); |
725 | + return; |
726 | +} |
727 | + |
728 | +static void |
729 | +indicator_service_finalize (GObject *object) |
730 | +{ |
731 | + IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(object); |
732 | + |
733 | + if (priv->name != NULL) { |
734 | + g_free(priv->name); |
735 | + } |
736 | + |
737 | + if (priv->watchers != NULL) { |
738 | + g_list_foreach(priv->watchers, (GFunc)g_free, NULL); |
739 | + g_list_free(priv->watchers); |
740 | + priv->watchers = NULL; |
741 | + } |
742 | + |
743 | + G_OBJECT_CLASS (indicator_service_parent_class)->finalize (object); |
744 | + return; |
745 | +} |
746 | + |
747 | +static void |
748 | +set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) |
749 | +{ |
750 | + IndicatorService * self = INDICATOR_SERVICE(object); |
751 | + g_return_if_fail(self != NULL); |
752 | + |
753 | + IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(self); |
754 | + g_return_if_fail(priv != NULL); |
755 | + |
756 | + switch (prop_id) { |
757 | + /* *********************** */ |
758 | + case PROP_NAME: |
759 | + if (G_VALUE_HOLDS_STRING(value)) { |
760 | + if (priv->name != NULL) { |
761 | + g_error("Name can not be set twice!"); |
762 | + return; |
763 | + } |
764 | + priv->name = g_value_dup_string(value); |
765 | + try_and_get_name(self); |
766 | + } else { |
767 | + g_warning("Name property requires a string value."); |
768 | + } |
769 | + break; |
770 | + /* *********************** */ |
771 | + default: |
772 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
773 | + break; |
774 | + } |
775 | + |
776 | + return; |
777 | +} |
778 | + |
779 | +static void |
780 | +get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) |
781 | +{ |
782 | + IndicatorService * self = INDICATOR_SERVICE(object); |
783 | + g_return_if_fail(self != NULL); |
784 | + |
785 | + IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(self); |
786 | + g_return_if_fail(priv != NULL); |
787 | + |
788 | + switch (prop_id) { |
789 | + /* *********************** */ |
790 | + case PROP_NAME: |
791 | + if (G_VALUE_HOLDS_STRING(value)) { |
792 | + g_value_set_string(value, priv->name); |
793 | + } else { |
794 | + g_warning("Name property requires a string value."); |
795 | + } |
796 | + break; |
797 | + /* *********************** */ |
798 | + default: |
799 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
800 | + break; |
801 | + } |
802 | + |
803 | + return; |
804 | +} |
805 | + |
806 | +static gboolean |
807 | +timeout_no_watchers (gpointer data) |
808 | +{ |
809 | + g_signal_emit(G_OBJECT(data), signals[SHUTDOWN], 0, TRUE); |
810 | + return FALSE; |
811 | +} |
812 | + |
813 | +static void |
814 | +try_and_get_name_cb (DBusGProxy * proxy, guint status, GError * error, gpointer data) |
815 | +{ |
816 | + IndicatorService * service = INDICATOR_SERVICE(data); |
817 | + g_return_if_fail(service != NULL); |
818 | + |
819 | + if (status != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER && status != DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER) { |
820 | + /* The already owner seems like it shouldn't ever |
821 | + happen, but I have a hard time throwing an error |
822 | + on it as we did achieve our goals. */ |
823 | + g_signal_emit(G_OBJECT(data), signals[SHUTDOWN], 0, TRUE); |
824 | + return; |
825 | + } |
826 | + |
827 | + IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(service); |
828 | + priv->timeout = g_timeout_add(500, timeout_no_watchers, service); |
829 | + |
830 | + return; |
831 | +} |
832 | + |
833 | +static void |
834 | +try_and_get_name (IndicatorService * service) |
835 | +{ |
836 | + IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(service); |
837 | + g_return_if_fail(priv->dbus_proxy != NULL); |
838 | + g_return_if_fail(priv->name != NULL); |
839 | + |
840 | + org_freedesktop_DBus_request_name_async(priv->dbus_proxy, |
841 | + priv->name, |
842 | + DBUS_NAME_FLAG_DO_NOT_QUEUE, |
843 | + try_and_get_name_cb, |
844 | + service); |
845 | + |
846 | + return; |
847 | +} |
848 | + |
849 | +static gboolean |
850 | +_indicator_service_server_watch (IndicatorService * service, DBusGMethodInvocation * method) |
851 | +{ |
852 | + g_return_val_if_fail(INDICATOR_IS_SERVICE(service), FALSE); |
853 | + IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(service); |
854 | + |
855 | + priv->watchers = g_list_append(priv->watchers, |
856 | + g_strdup(dbus_g_method_get_sender(method))); |
857 | + |
858 | + if (priv->timeout != 0) { |
859 | + g_source_remove(priv->timeout); |
860 | + priv->timeout = 0; |
861 | + } |
862 | + |
863 | + dbus_g_method_return(method, 1); |
864 | + return TRUE; |
865 | +} |
866 | + |
867 | +/* API */ |
868 | + |
869 | +/** |
870 | + indicator_service_new: |
871 | + @name: The name for the service on dbus |
872 | + |
873 | + This function creates the service on DBus and tries to |
874 | + get a well-known name specified in @name. If the name |
875 | + can't be estabilished then the #IndicatorService::shutdown |
876 | + signal will be sent. |
877 | + |
878 | + Return value: A brand new #IndicatorService object or #NULL |
879 | + if there is an error. |
880 | +*/ |
881 | +IndicatorService * |
882 | +indicator_service_new (gchar * name) |
883 | +{ |
884 | + GObject * obj = g_object_new(INDICATOR_SERVICE_TYPE, |
885 | + PROP_NAME_S, name, |
886 | + NULL); |
887 | + |
888 | + return INDICATOR_SERVICE(obj); |
889 | +} |
890 | |
891 | === added file 'libindicator/indicator-service.h' |
892 | --- libindicator/indicator-service.h 1970-01-01 00:00:00 +0000 |
893 | +++ libindicator/indicator-service.h 2009-11-04 04:44:10 +0000 |
894 | @@ -0,0 +1,60 @@ |
895 | +#ifndef __INDICATOR_SERVICE_H__ |
896 | +#define __INDICATOR_SERVICE_H__ |
897 | + |
898 | +#include <glib.h> |
899 | +#include <glib-object.h> |
900 | + |
901 | +G_BEGIN_DECLS |
902 | + |
903 | +#define INDICATOR_SERVICE_TYPE (indicator_service_get_type ()) |
904 | +#define INDICATOR_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_SERVICE_TYPE, IndicatorService)) |
905 | +#define INDICATOR_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_SERVICE_TYPE, IndicatorServiceClass)) |
906 | +#define INDICATOR_IS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_SERVICE_TYPE)) |
907 | +#define INDICATOR_IS_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_SERVICE_TYPE)) |
908 | +#define INDICATOR_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_SERVICE_TYPE, IndicatorServiceClass)) |
909 | + |
910 | +#define INDICATOR_SERVICE_SIGNAL_SHUTDOWN "shutdown" |
911 | + |
912 | +typedef struct _IndicatorService IndicatorService; |
913 | +typedef struct _IndicatorServiceClass IndicatorServiceClass; |
914 | + |
915 | +/** |
916 | + IndicatorServiceClass: |
917 | + @parent_class: #GObjectClass |
918 | + @shutdown: Slot for IndicatorServiceClass::shutdown |
919 | + @indicator_service_reserved1: Reserved for future use |
920 | + @indicator_service_reserved2: Reserved for future use |
921 | + @indicator_service_reserved3: Reserved for future use |
922 | + @indicator_service_reserved4: Reserved for future use |
923 | + |
924 | +*/ |
925 | +struct _IndicatorServiceClass { |
926 | + GObjectClass parent_class; |
927 | + |
928 | + /* Signals */ |
929 | + void (*shutdown) (IndicatorService * service, gpointer user_data); |
930 | + |
931 | + /* Reserved */ |
932 | + void (*indicator_service_reserved1) (void); |
933 | + void (*indicator_service_reserved2) (void); |
934 | + void (*indicator_service_reserved3) (void); |
935 | + void (*indicator_service_reserved4) (void); |
936 | +}; |
937 | + |
938 | +/** |
939 | + IndicatorService: |
940 | + @parent: #GObject |
941 | + |
942 | +*/ |
943 | +struct _IndicatorService { |
944 | + GObject parent; |
945 | + |
946 | +}; |
947 | + |
948 | +GType indicator_service_get_type (void); |
949 | + |
950 | +IndicatorService * indicator_service_new (gchar * name); |
951 | + |
952 | +G_END_DECLS |
953 | + |
954 | +#endif |
955 | |
956 | === added file 'libindicator/indicator-service.xml' |
957 | --- libindicator/indicator-service.xml 1970-01-01 00:00:00 +0000 |
958 | +++ libindicator/indicator-service.xml 2009-11-04 04:44:10 +0000 |
959 | @@ -0,0 +1,17 @@ |
960 | +<?xml version="1.0" encoding="UTF-8"?> |
961 | +<node name="/"> |
962 | + <interface name="org.ayatana.indicator.service"> |
963 | +<!-- Properties --> |
964 | + <!-- None currently --> |
965 | + |
966 | +<!-- Methods --> |
967 | + <method name="Watch"> |
968 | + <annotation name="org.freedesktop.DBus.GLib.Async" value="true" /> |
969 | + <arg type="i" name="version" direction="out" /> |
970 | + </method> |
971 | + |
972 | +<!-- Signals --> |
973 | + <!-- None currently --> |
974 | + |
975 | + </interface> |
976 | +</node> |
977 | |
978 | === modified file 'libindicator/indicator.pc.in' |
979 | --- libindicator/indicator.pc.in 2009-08-08 15:55:54 +0000 |
980 | +++ libindicator/indicator.pc.in 2009-11-04 04:44:10 +0000 |
981 | @@ -9,7 +9,7 @@ |
982 | |
983 | Cflags: -I${includedir}/libindicator-0.1 |
984 | Requires: gtk+-2.0 |
985 | -Libs: |
986 | +Libs: -lindicator |
987 | |
988 | Name: libindicator |
989 | Description: libindicator. |
990 | |
991 | === modified file 'tests/Makefile.am' |
992 | --- tests/Makefile.am 2009-10-12 02:49:22 +0000 |
993 | +++ tests/Makefile.am 2009-11-04 04:44:10 +0000 |
994 | @@ -1,12 +1,20 @@ |
995 | +TESTS = |
996 | +DISTCLEANFILES = |
997 | |
998 | check_PROGRAMS = \ |
999 | - test-loader |
1000 | + test-loader \ |
1001 | + service-manager-no-connect \ |
1002 | + service-manager-connect \ |
1003 | + service-manager-connect-service \ |
1004 | + service-shutdown-timeout |
1005 | |
1006 | lib_LTLIBRARIES = \ |
1007 | libdummy-indicator-blank.la \ |
1008 | libdummy-indicator-null.la \ |
1009 | libdummy-indicator-simple.la |
1010 | |
1011 | +DBUS_RUNNER=dbus-test-runner --dbus-config /usr/share/dbus-test-runner/session.conf |
1012 | + |
1013 | ############################# |
1014 | # Test Loader |
1015 | ############################# |
1016 | @@ -77,16 +85,105 @@ |
1017 | -avoid-version |
1018 | |
1019 | ############################# |
1020 | +# Service Shutdown Timeout |
1021 | +############################# |
1022 | + |
1023 | +service_shutdown_timeout_SOURCES = \ |
1024 | + service-shutdown-timeout.c |
1025 | + |
1026 | +service_shutdown_timeout_CFLAGS = \ |
1027 | + -Wall -Werror \ |
1028 | + $(LIBINDICATOR_CFLAGS) -I$(top_srcdir) |
1029 | + |
1030 | +service_shutdown_timeout_LDADD = \ |
1031 | + $(LIBINDICATOR_LIBS) \ |
1032 | + $(top_builddir)/libindicator/.libs/libindicator.a |
1033 | + |
1034 | +service-shutdown-timeout-tester: service-shutdown-timeout Makefile |
1035 | + @echo "#!/bin/sh" > service-shutdown-timeout-tester |
1036 | + @echo $(DBUS_RUNNER) --task ./service-shutdown-timeout >> service-shutdown-timeout-tester |
1037 | + @chmod +x service-shutdown-timeout-tester |
1038 | + |
1039 | +TESTS += service-shutdown-timeout-tester |
1040 | +DISTCLEANFILES += service-shutdown-timeout-tester |
1041 | + |
1042 | +############################# |
1043 | +# Service Manager No Connect |
1044 | +############################# |
1045 | + |
1046 | +service_manager_no_connect_SOURCES = \ |
1047 | + service-manager-no-connect.c |
1048 | + |
1049 | +service_manager_no_connect_CFLAGS = \ |
1050 | + -Wall -Werror \ |
1051 | + $(LIBINDICATOR_CFLAGS) -I$(top_srcdir) |
1052 | + |
1053 | +service_manager_no_connect_LDADD = \ |
1054 | + $(LIBINDICATOR_LIBS) \ |
1055 | + $(top_builddir)/libindicator/.libs/libindicator.a |
1056 | + |
1057 | +service-manager-no-connect-tester: service-manager-no-connect Makefile.am |
1058 | + @echo "#!/bin/sh" > service-manager-no-connect-tester |
1059 | + @echo $(DBUS_RUNNER) --task ./service-manager-no-connect >> service-manager-no-connect-tester |
1060 | + @chmod +x service-manager-no-connect-tester |
1061 | + |
1062 | +TESTS += service-manager-no-connect-tester |
1063 | +DISTCLEANFILES += service-manager-no-connect-tester |
1064 | + |
1065 | +############################# |
1066 | +# Service Manager Connect |
1067 | +############################# |
1068 | + |
1069 | +session.conf: $(srcdir)/session.conf.in Makefile.am |
1070 | + sed -e "s|\@servicedir\@|$(abspath $(builddir))|" $< > $@ |
1071 | + |
1072 | +service-manager-connect.service: $(srcdir)/service-manager-connect.service.in Makefile.am |
1073 | + sed -e "s|\@builddir\@|$(abspath $(builddir))|" $< > $@ |
1074 | + |
1075 | +service_manager_connect_SOURCES = \ |
1076 | + service-manager-connect.c |
1077 | + |
1078 | +service_manager_connect_CFLAGS = \ |
1079 | + -Wall -Werror \ |
1080 | + $(LIBINDICATOR_CFLAGS) -I$(top_srcdir) |
1081 | + |
1082 | +service_manager_connect_LDADD = \ |
1083 | + $(LIBINDICATOR_LIBS) \ |
1084 | + $(top_builddir)/libindicator/.libs/libindicator.a |
1085 | + |
1086 | +service_manager_connect_service_SOURCES = \ |
1087 | + service-manager-connect-service.c |
1088 | + |
1089 | +service_manager_connect_service_CFLAGS = \ |
1090 | + -Wall -Werror \ |
1091 | + $(LIBINDICATOR_CFLAGS) -I$(top_srcdir) |
1092 | + |
1093 | +service_manager_connect_service_LDADD = \ |
1094 | + $(LIBINDICATOR_LIBS) \ |
1095 | + $(top_builddir)/libindicator/.libs/libindicator.a |
1096 | + |
1097 | +service-manager-connect-tester: service-manager-connect service-manager-connect-service session.conf service-manager-connect.service Makefile.am |
1098 | + @echo "#!/bin/sh" > service-manager-connect-tester |
1099 | + @echo dbus-test-runner --dbus-config $(builddir)/session.conf --task ./service-manager-connect >> service-manager-connect-tester |
1100 | + @chmod +x service-manager-connect-tester |
1101 | + |
1102 | +TESTS += service-manager-connect-tester |
1103 | +DISTCLEANFILES += service-manager-connect-tester session.conf service-manager-connect.service |
1104 | + |
1105 | +############################# |
1106 | # Test stuff |
1107 | ############################# |
1108 | |
1109 | XML_REPORT = loader-check-results.xml |
1110 | HTML_REPORT = loader-check-results.html |
1111 | |
1112 | -loader-tester: test-loader libdummy-indicator-null.la libdummy-indicator-simple.la |
1113 | - @gtester -k --verbose -o=$(XML_REPORT) ./test-loader |
1114 | - |
1115 | -check-local: loader-tester |
1116 | - |
1117 | -DISTCLEANFILES = $(XML_REPORT) $(HTML_REPORT) |
1118 | +loader-tester: test-loader libdummy-indicator-null.la libdummy-indicator-simple.la Makefile |
1119 | + @echo "#!/bin/sh" > loader-tester |
1120 | + @echo gtester -k --verbose -o=$(XML_REPORT) ./test-loader >> loader-tester |
1121 | + @chmod +x loader-tester |
1122 | + |
1123 | +TESTS += loader-tester |
1124 | +DISTCLEANFILES += loader-tester |
1125 | + |
1126 | +DISTCLEANFILES += $(XML_REPORT) $(HTML_REPORT) |
1127 | |
1128 | |
1129 | === added file 'tests/service-manager-connect-service.c' |
1130 | --- tests/service-manager-connect-service.c 1970-01-01 00:00:00 +0000 |
1131 | +++ tests/service-manager-connect-service.c 2009-11-04 04:44:10 +0000 |
1132 | @@ -0,0 +1,46 @@ |
1133 | + |
1134 | +#include <glib.h> |
1135 | +#include "libindicator/indicator-service.h" |
1136 | + |
1137 | +static GMainLoop * mainloop = NULL; |
1138 | +static gboolean passed = FALSE; |
1139 | + |
1140 | +gboolean |
1141 | +timeout (gpointer data) |
1142 | +{ |
1143 | + passed = TRUE; |
1144 | + g_debug("Timeout with no shutdown."); |
1145 | + g_main_loop_quit(mainloop); |
1146 | + return FALSE; |
1147 | +} |
1148 | + |
1149 | +void |
1150 | +shutdown (void) |
1151 | +{ |
1152 | + g_error("Shutdown"); |
1153 | + passed = FALSE; |
1154 | + g_main_loop_quit(mainloop); |
1155 | + return; |
1156 | +} |
1157 | + |
1158 | +int |
1159 | +main (int argc, char ** argv) |
1160 | +{ |
1161 | + g_type_init(); |
1162 | + |
1163 | + IndicatorService * is = indicator_service_new("org.ayatana.test"); |
1164 | + g_signal_connect(G_OBJECT(is), INDICATOR_SERVICE_SIGNAL_SHUTDOWN, shutdown, NULL); |
1165 | + |
1166 | + g_timeout_add_seconds(1, timeout, NULL); |
1167 | + |
1168 | + mainloop = g_main_loop_new(NULL, FALSE); |
1169 | + g_main_loop_run(mainloop); |
1170 | + |
1171 | + g_debug("Quiting"); |
1172 | + if (passed) { |
1173 | + g_debug("Passed"); |
1174 | + return 0; |
1175 | + } |
1176 | + g_debug("Failed"); |
1177 | + return 1; |
1178 | +} |
1179 | |
1180 | === added file 'tests/service-manager-connect.c' |
1181 | --- tests/service-manager-connect.c 1970-01-01 00:00:00 +0000 |
1182 | +++ tests/service-manager-connect.c 2009-11-04 04:44:10 +0000 |
1183 | @@ -0,0 +1,47 @@ |
1184 | + |
1185 | +#include <glib.h> |
1186 | +#include "libindicator/indicator-service-manager.h" |
1187 | + |
1188 | +static GMainLoop * mainloop = NULL; |
1189 | +static gboolean passed = FALSE; |
1190 | + |
1191 | +gboolean |
1192 | +timeout (gpointer data) |
1193 | +{ |
1194 | + passed = FALSE; |
1195 | + g_error("Timeout with no connection."); |
1196 | + g_main_loop_quit(mainloop); |
1197 | + return FALSE; |
1198 | +} |
1199 | + |
1200 | +void |
1201 | +connection (void) |
1202 | +{ |
1203 | + g_debug("Connection"); |
1204 | + passed = TRUE; |
1205 | + g_main_loop_quit(mainloop); |
1206 | + return; |
1207 | +} |
1208 | + |
1209 | +int |
1210 | +main (int argc, char ** argv) |
1211 | +{ |
1212 | + g_type_init(); |
1213 | + g_log_set_always_fatal(G_LOG_LEVEL_CRITICAL); |
1214 | + |
1215 | + IndicatorServiceManager * is = indicator_service_manager_new("org.ayatana.test"); |
1216 | + g_signal_connect(G_OBJECT(is), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, connection, NULL); |
1217 | + |
1218 | + g_timeout_add_seconds(1, timeout, NULL); |
1219 | + |
1220 | + mainloop = g_main_loop_new(NULL, FALSE); |
1221 | + g_main_loop_run(mainloop); |
1222 | + |
1223 | + g_debug("Quiting"); |
1224 | + if (passed) { |
1225 | + g_debug("Passed"); |
1226 | + return 0; |
1227 | + } |
1228 | + g_debug("Failed"); |
1229 | + return 1; |
1230 | +} |
1231 | |
1232 | === added file 'tests/service-manager-connect.service.in' |
1233 | --- tests/service-manager-connect.service.in 1970-01-01 00:00:00 +0000 |
1234 | +++ tests/service-manager-connect.service.in 2009-11-04 04:44:10 +0000 |
1235 | @@ -0,0 +1,3 @@ |
1236 | +[D-BUS Service] |
1237 | +Name=org.ayatana.test |
1238 | +Exec=@builddir@/service-manager-connect-service |
1239 | |
1240 | === added file 'tests/service-manager-no-connect.c' |
1241 | --- tests/service-manager-no-connect.c 1970-01-01 00:00:00 +0000 |
1242 | +++ tests/service-manager-no-connect.c 2009-11-04 04:44:10 +0000 |
1243 | @@ -0,0 +1,47 @@ |
1244 | + |
1245 | +#include <glib.h> |
1246 | +#include "libindicator/indicator-service-manager.h" |
1247 | + |
1248 | +static GMainLoop * mainloop = NULL; |
1249 | +static gboolean passed = FALSE; |
1250 | + |
1251 | +gboolean |
1252 | +timeout (gpointer data) |
1253 | +{ |
1254 | + passed = TRUE; |
1255 | + g_debug("Timeout with no connection."); |
1256 | + g_main_loop_quit(mainloop); |
1257 | + return FALSE; |
1258 | +} |
1259 | + |
1260 | +void |
1261 | +connection (void) |
1262 | +{ |
1263 | + g_debug("Connection"); |
1264 | + passed = FALSE; |
1265 | + g_main_loop_quit(mainloop); |
1266 | + return; |
1267 | +} |
1268 | + |
1269 | +int |
1270 | +main (int argc, char ** argv) |
1271 | +{ |
1272 | + g_type_init(); |
1273 | + g_log_set_always_fatal(G_LOG_LEVEL_CRITICAL); |
1274 | + |
1275 | + IndicatorServiceManager * is = indicator_service_manager_new("my.test.name"); |
1276 | + g_signal_connect(G_OBJECT(is), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, connection, NULL); |
1277 | + |
1278 | + g_timeout_add_seconds(1, timeout, NULL); |
1279 | + |
1280 | + mainloop = g_main_loop_new(NULL, FALSE); |
1281 | + g_main_loop_run(mainloop); |
1282 | + |
1283 | + g_debug("Quiting"); |
1284 | + if (passed) { |
1285 | + g_debug("Passed"); |
1286 | + return 0; |
1287 | + } |
1288 | + g_debug("Failed"); |
1289 | + return 1; |
1290 | +} |
1291 | |
1292 | === added file 'tests/service-shutdown-timeout.c' |
1293 | --- tests/service-shutdown-timeout.c 1970-01-01 00:00:00 +0000 |
1294 | +++ tests/service-shutdown-timeout.c 2009-11-04 04:44:10 +0000 |
1295 | @@ -0,0 +1,46 @@ |
1296 | + |
1297 | +#include <glib.h> |
1298 | +#include "libindicator/indicator-service.h" |
1299 | + |
1300 | +static GMainLoop * mainloop = NULL; |
1301 | +static gboolean passed = FALSE; |
1302 | + |
1303 | +gboolean |
1304 | +timeout (gpointer data) |
1305 | +{ |
1306 | + passed = FALSE; |
1307 | + g_error("Timeout with no shutdown."); |
1308 | + g_main_loop_quit(mainloop); |
1309 | + return FALSE; |
1310 | +} |
1311 | + |
1312 | +void |
1313 | +shutdown (void) |
1314 | +{ |
1315 | + g_debug("Shutdown"); |
1316 | + passed = TRUE; |
1317 | + g_main_loop_quit(mainloop); |
1318 | + return; |
1319 | +} |
1320 | + |
1321 | +int |
1322 | +main (int argc, char ** argv) |
1323 | +{ |
1324 | + g_type_init(); |
1325 | + |
1326 | + IndicatorService * is = indicator_service_new("my.test.name"); |
1327 | + g_signal_connect(G_OBJECT(is), INDICATOR_SERVICE_SIGNAL_SHUTDOWN, shutdown, NULL); |
1328 | + |
1329 | + g_timeout_add_seconds(1, timeout, NULL); |
1330 | + |
1331 | + mainloop = g_main_loop_new(NULL, FALSE); |
1332 | + g_main_loop_run(mainloop); |
1333 | + |
1334 | + g_debug("Quiting"); |
1335 | + if (passed) { |
1336 | + g_debug("Passed"); |
1337 | + return 0; |
1338 | + } |
1339 | + g_debug("Failed"); |
1340 | + return 1; |
1341 | +} |
1342 | |
1343 | === added file 'tests/session.conf.in' |
1344 | --- tests/session.conf.in 1970-01-01 00:00:00 +0000 |
1345 | +++ tests/session.conf.in 2009-11-04 04:44:10 +0000 |
1346 | @@ -0,0 +1,40 @@ |
1347 | +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN" |
1348 | + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> |
1349 | +<busconfig> |
1350 | + <!-- If we fork, keep the user's original umask to avoid affecting |
1351 | + the behavior of child processes. --> |
1352 | + <keep_umask/> |
1353 | + |
1354 | + <listen>unix:tmpdir=/tmp</listen> |
1355 | + |
1356 | + <servicedir>@servicedir@</servicedir> |
1357 | + |
1358 | + <policy context="default"> |
1359 | + <!-- Allow everything to be sent --> |
1360 | + <allow send_destination="*" eavesdrop="true"/> |
1361 | + <!-- Allow everything to be received --> |
1362 | + <allow eavesdrop="true"/> |
1363 | + <!-- Allow anyone to own anything --> |
1364 | + <allow own="*"/> |
1365 | + </policy> |
1366 | + |
1367 | + <!-- raise the service start timeout to 40 seconds as it can timeout |
1368 | + on the live cd on slow machines --> |
1369 | + <limit name="service_start_timeout">60000</limit> |
1370 | + |
1371 | + <!-- the memory limits are 1G instead of say 4G because they can't exceed 32-bit signed int max --> |
1372 | + <limit name="max_incoming_bytes">1000000000</limit> |
1373 | + <limit name="max_outgoing_bytes">1000000000</limit> |
1374 | + <limit name="max_message_size">1000000000</limit> |
1375 | + <limit name="service_start_timeout">120000</limit> |
1376 | + <limit name="auth_timeout">240000</limit> |
1377 | + <limit name="max_completed_connections">100000</limit> |
1378 | + <limit name="max_incomplete_connections">10000</limit> |
1379 | + <limit name="max_connections_per_user">100000</limit> |
1380 | + <limit name="max_pending_service_starts">10000</limit> |
1381 | + <limit name="max_names_per_connection">50000</limit> |
1382 | + <limit name="max_match_rules_per_connection">50000</limit> |
1383 | + <limit name="max_replies_per_connection">50000</limit> |
1384 | + <limit name="reply_timeout">300000</limit> |
1385 | + |
1386 | +</busconfig> |
Creating a set of objects to create a service and to manage it. For the most part this just takes care if starting up today. There isn't much "management" per se, it is just the boot strapping of this feature to get it working.