Merge lp://qastaging/~ted/libindicator/service-management into lp://qastaging/libindicator/0.4

Proposed by Ted Gould
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
Reviewer Review Type Date Requested Status
Robert Collins (community) Abstain
Review via email: mp+14398@code.qastaging.launchpad.net
To post a comment you must log in.
Revision history for this message
Ted Gould (ted) wrote :

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.

Revision history for this message
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/indicator-service-client.h
> +libindicator/indicator-service-server.h

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_service_manager_dispose (GObject *object)
> +{
> + IndicatorServiceManagerPrivate * priv =
> INDICATOR_SERVICE_MANAGER_GET_PRIVATE(object);
> +
> + /* 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_emit(object, signals[CONNECTION_CHANGE], 0,
> 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/service_version/ - it would be clearer

> + /* Buffer */
> + void (*indicator_service_manager_reserved1) (void);
> + void (*indicator_service_manager_reserved2) (void);
> + void (*indicator_service_manager_reserved3) (void);
> + void (*indicator_service_manager_reserved4) (void);
> +};

Perhaps here and below would be nicer as:
void (*reserved)[4] or
void (*indicator_service_manager_reserved)(void)[4]

> + } else {
> + g_warning("Name is a string bud.");

                                                      ^^^^ ???

+loader-tester: test-loader libdummy-indicator-null.la
libdummy-indicator-simple.la Makefile
> + @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-indicator-null.la \
  libdummy-indicator-simple.la
    gtester -k --verbose -o=$(XML_REPORT) ./test-loader >> loader-tester

would be a lot cleaner

Other than that, +1

 review: abstain

review: Abstain
Revision history for this message
Ted Gould (ted) wrote :
Download full text (3.2 KiB)

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/indicator-service-client.h
> > +libindicator/indicator-service-server.h
>
> 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_service_manager_dispose (GObject *object)
> > +{
> > + IndicatorServiceManagerPrivate * priv =
> > INDICATOR_SERVICE_MANAGER_GET_PRIVATE(object);
> > +
> > + /* 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_emit(object, signals[CONNECTION_CHANGE], 0,
> > 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/service_version/ - it would be clearer

Fixed r370.

> > + /* Buffer */
> > + void (*indicator_service_manager_reserved1) (void);
> > + void (*indicator_service_manager_reserved2) (void);
> > + void (*indicator_service_manager_reserved3) (void);
> > + void (*indicator_service_manager_reserved4) (void);
> > +};
>
> Perhaps here and below would be nicer as:
> void (*reserved)[4] or
> void (*indicator_service_manager_reserved)(void)[4]

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-indicator-null.la
> libdummy-indicator-simple.la Makefile
> > + @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-indicator-null.la \
> libdummy-indicator-simple.la
> 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...

Read more...

Revision history for this message
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

Revision history for this message
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 :)

331. By Ted Gould

Adding a service management interface into libindicators as many will use that.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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>

Subscribers

People subscribed via source and target branches