Branch data Line data Source code
1 : : /* GLib testing framework examples and tests
2 : : *
3 : : * Copyright (C) 2008-2018 Red Hat, Inc.
4 : : *
5 : : * SPDX-License-Identifier: LGPL-2.1-or-later
6 : : *
7 : : * This library is free software; you can redistribute it and/or
8 : : * modify it under the terms of the GNU Lesser General Public
9 : : * License as published by the Free Software Foundation; either
10 : : * version 2.1 of the License, or (at your option) any later version.
11 : : *
12 : : * This library is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : * Lesser General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU Lesser General
18 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 : : *
20 : : * Author: David Zeuthen <davidz@redhat.com>
21 : : */
22 : :
23 : : #include <gio/gio.h>
24 : : #include <unistd.h>
25 : : #include <string.h>
26 : : #include <stdio.h>
27 : :
28 : : #include "gdbus-tests.h"
29 : : #include "gstdio.h"
30 : :
31 : : #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64
32 : : #include "gdbus-test-codegen-generated-min-required-2-64.h"
33 : : #else
34 : : #include "gdbus-test-codegen-generated.h"
35 : : #endif
36 : :
37 : : #include "gdbus-test-codegen-generated-interface-info.h"
38 : :
39 : : #if GLIB_VERSION_MIN_REQUIRED < GLIB_VERSION_2_68
40 : : # undef G_DBUS_METHOD_INVOCATION_HANDLED
41 : : # define G_DBUS_METHOD_INVOCATION_HANDLED TRUE
42 : : #endif
43 : :
44 : : /* ---------------------------------------------------------------------------------------------------- */
45 : :
46 : : static guint
47 : 306 : count_annotations (GDBusAnnotationInfo **annotations)
48 : : {
49 : : guint ret;
50 : 306 : ret = 0;
51 [ + + + + ]: 363 : while (annotations != NULL && annotations[ret] != NULL)
52 : 57 : ret++;
53 : 306 : return ret;
54 : : }
55 : :
56 : : /* checks that
57 : : *
58 : : * - non-internal annotations are written out correctly; and
59 : : * - injection via --annotation --key --value works
60 : : */
61 : : static void
62 : 3 : test_annotations (void)
63 : : {
64 : : GDBusInterfaceInfo *iface;
65 : : GDBusMethodInfo *method;
66 : : GDBusSignalInfo *signal;
67 : : GDBusPropertyInfo *property;
68 : :
69 : 3 : iface = foo_igen_bar_interface_info ();
70 : 3 : g_assert (iface != NULL);
71 : :
72 : : /* see meson.build for where these annotations are injected */
73 : 3 : g_assert_cmpint (count_annotations (iface->annotations), ==, 1);
74 : 3 : g_assert_cmpstr (g_dbus_annotation_info_lookup (iface->annotations, "Key1"), ==, "Value1");
75 : :
76 : 3 : method = g_dbus_interface_info_lookup_method (iface, "HelloWorld");
77 : 3 : g_assert (method != NULL);
78 : 3 : g_assert_cmpint (count_annotations (method->annotations), ==, 2);
79 : 3 : g_assert_cmpstr (g_dbus_annotation_info_lookup (method->annotations, "ExistingAnnotation"), ==, "blah");
80 : 3 : g_assert_cmpstr (g_dbus_annotation_info_lookup (method->annotations, "Key3"), ==, "Value3");
81 : :
82 : 3 : signal = g_dbus_interface_info_lookup_signal (iface, "TestSignal");
83 : 3 : g_assert (signal != NULL);
84 : 3 : g_assert_cmpint (count_annotations (signal->annotations), ==, 1);
85 : 3 : g_assert_cmpstr (g_dbus_annotation_info_lookup (signal->annotations, "Key4"), ==, "Value4");
86 : 3 : g_assert_cmpstr (g_dbus_annotation_info_lookup (signal->args[1]->annotations, "Key8"), ==, "Value8");
87 : :
88 : 3 : property = g_dbus_interface_info_lookup_property (iface, "ay");
89 : 3 : g_assert (property != NULL);
90 : 3 : g_assert_cmpint (count_annotations (property->annotations), ==, 1);
91 : 3 : g_assert_cmpstr (g_dbus_annotation_info_lookup (property->annotations, "Key5"), ==, "Value5");
92 : :
93 : 3 : method = g_dbus_interface_info_lookup_method (iface, "TestPrimitiveTypes");
94 : 3 : g_assert (method != NULL);
95 : 3 : g_assert_cmpstr (g_dbus_annotation_info_lookup (method->in_args[4]->annotations, "Key6"), ==, "Value6");
96 : 3 : g_assert_cmpstr (g_dbus_annotation_info_lookup (method->out_args[5]->annotations, "Key7"), ==, "Value7");
97 : 3 : }
98 : :
99 : : /* ---------------------------------------------------------------------------------------------------- */
100 : :
101 : : static gboolean
102 : 0 : on_handle_hello_world (FooiGenBar *object,
103 : : GDBusMethodInvocation *invocation,
104 : : const gchar *greeting,
105 : : gpointer user_data)
106 : : {
107 : : gchar *response;
108 : 0 : response = g_strdup_printf ("Word! You said '%s'. I'm Skeleton, btw!", greeting);
109 : 0 : foo_igen_bar_complete_hello_world (object, invocation, response);
110 : 0 : g_free (response);
111 : 0 : return G_DBUS_METHOD_INVOCATION_HANDLED;
112 : : }
113 : :
114 : : static gboolean
115 : 3 : on_handle_test_primitive_types (FooiGenBar *object,
116 : : GDBusMethodInvocation *invocation,
117 : : guchar val_byte,
118 : : gboolean val_boolean,
119 : : gint16 val_int16,
120 : : guint16 val_uint16,
121 : : gint val_int32,
122 : : guint val_uint32,
123 : : gint64 val_int64,
124 : : guint64 val_uint64,
125 : : gdouble val_double,
126 : : const gchar *val_string,
127 : : const gchar *val_objpath,
128 : : const gchar *val_signature,
129 : : const gchar *val_bytestring,
130 : : gpointer user_data)
131 : : {
132 : : gchar *s1;
133 : : gchar *s2;
134 : : gchar *s3;
135 : 3 : s1 = g_strdup_printf ("Word! You said '%s'. Rock'n'roll!", val_string);
136 : 3 : s2 = g_strdup_printf ("/modified%s", val_objpath);
137 : 3 : s3 = g_strdup_printf ("assgit%s", val_signature);
138 : 3 : foo_igen_bar_complete_test_primitive_types (object,
139 : : invocation,
140 : 3 : 10 + val_byte,
141 : : !val_boolean,
142 : 3 : 100 + val_int16,
143 : 3 : 1000 + val_uint16,
144 : : 10000 + val_int32,
145 : : 100000 + val_uint32,
146 : : 1000000 + val_int64,
147 : : 10000000 + val_uint64,
148 : : val_double / G_PI,
149 : : s1,
150 : : s2,
151 : : s3,
152 : : "bytestring!\xff");
153 : 3 : g_free (s1);
154 : 3 : g_free (s2);
155 : 3 : g_free (s3);
156 : 3 : return G_DBUS_METHOD_INVOCATION_HANDLED;
157 : : }
158 : :
159 : : static gboolean
160 : 3 : on_handle_test_non_primitive_types (FooiGenBar *object,
161 : : GDBusMethodInvocation *invocation,
162 : : GVariant *dict_s_to_s,
163 : : GVariant *dict_s_to_pairs,
164 : : GVariant *a_struct,
165 : : const gchar* const *array_of_strings,
166 : : const gchar* const *array_of_objpaths,
167 : : GVariant *array_of_signatures,
168 : : const gchar* const *array_of_bytestrings,
169 : : gpointer user_data)
170 : : {
171 : : gchar *s;
172 : : GString *str;
173 : 3 : str = g_string_new (NULL);
174 : 6 : s = g_variant_print (dict_s_to_s, TRUE); g_string_append (str, s); g_free (s);
175 : 6 : s = g_variant_print (dict_s_to_pairs, TRUE); g_string_append (str, s); g_free (s);
176 : 6 : s = g_variant_print (a_struct, TRUE); g_string_append (str, s); g_free (s);
177 : 3 : s = g_strjoinv (", ", (gchar **) array_of_strings);
178 : 3 : g_string_append_printf (str, "array_of_strings: [%s] ", s);
179 : 3 : g_free (s);
180 : 3 : s = g_strjoinv (", ", (gchar **) array_of_objpaths);
181 : 3 : g_string_append_printf (str, "array_of_objpaths: [%s] ", s);
182 : 3 : g_free (s);
183 : 3 : s = g_variant_print (array_of_signatures, TRUE);
184 : 3 : g_string_append_printf (str, "array_of_signatures: %s ", s);
185 : 3 : g_free (s);
186 : 3 : s = g_strjoinv (", ", (gchar **) array_of_bytestrings);
187 : 3 : g_string_append_printf (str, "array_of_bytestrings: [%s] ", s);
188 : 3 : g_free (s);
189 : 3 : foo_igen_bar_complete_test_non_primitive_types (object, invocation,
190 : : array_of_strings,
191 : : array_of_objpaths,
192 : : array_of_signatures,
193 : : array_of_bytestrings,
194 : 3 : str->str);
195 : 3 : g_string_free (str, TRUE);
196 : 3 : return G_DBUS_METHOD_INVOCATION_HANDLED;
197 : : }
198 : :
199 : : static gboolean
200 : 3 : on_handle_request_signal_emission (FooiGenBar *object,
201 : : GDBusMethodInvocation *invocation,
202 : : gint which_one,
203 : : gpointer user_data)
204 : : {
205 [ + - ]: 3 : if (which_one == 0)
206 : : {
207 : 3 : const gchar *a_strv[] = {"foo", "bar", NULL};
208 : 3 : const gchar *a_bytestring_array[] = {"foo\xff", "bar\xff", NULL};
209 : 3 : GVariant *a_variant = g_variant_new_parsed ("{'first': (42, 42), 'second': (43, 43)}");
210 : 3 : foo_igen_bar_emit_test_signal (object, 43, a_strv, a_bytestring_array, a_variant); /* consumes a_variant */
211 : 3 : foo_igen_bar_complete_request_signal_emission (object, invocation);
212 : : }
213 : 3 : return G_DBUS_METHOD_INVOCATION_HANDLED;
214 : : }
215 : :
216 : : static gboolean
217 : 3 : on_handle_request_multi_property_mods (FooiGenBar *object,
218 : : GDBusMethodInvocation *invocation,
219 : : gpointer user_data)
220 : : {
221 : 3 : foo_igen_bar_set_y (object, foo_igen_bar_get_y (object) + 1);
222 : 3 : foo_igen_bar_set_i (object, foo_igen_bar_get_i (object) + 1);
223 : 3 : foo_igen_bar_set_y (object, foo_igen_bar_get_y (object) + 1);
224 : 3 : foo_igen_bar_set_i (object, foo_igen_bar_get_i (object) + 1);
225 : 3 : g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (object));
226 : 3 : foo_igen_bar_set_y (object, foo_igen_bar_get_y (object) + 1);
227 : 3 : foo_igen_bar_set_i (object, foo_igen_bar_get_i (object) + 1);
228 : 3 : foo_igen_bar_complete_request_multi_property_mods (object, invocation);
229 : 3 : return G_DBUS_METHOD_INVOCATION_HANDLED;
230 : : }
231 : :
232 : : static gboolean
233 : 3 : on_handle_property_cancellation (FooiGenBar *object,
234 : : GDBusMethodInvocation *invocation,
235 : : gpointer user_data)
236 : : {
237 : : guint n;
238 : 3 : n = foo_igen_bar_get_n (object);
239 : : /* This queues up a PropertiesChange event */
240 : 3 : foo_igen_bar_set_n (object, n + 1);
241 : : /* this modifies the queued up event */
242 : 3 : foo_igen_bar_set_n (object, n);
243 : : /* this flushes all PropertiesChanges event (sends the D-Bus message right
244 : : * away, if any - there should not be any)
245 : : */
246 : 3 : g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (object));
247 : : /* this makes us return the reply D-Bus method */
248 : 3 : foo_igen_bar_complete_property_cancellation (object, invocation);
249 : 3 : return G_DBUS_METHOD_INVOCATION_HANDLED;
250 : : }
251 : :
252 : : /* ---------------------------------------------------------------------------------------------------- */
253 : :
254 : : static gboolean
255 : 3 : on_handle_force_method (FooiGenBat *object,
256 : : GDBusMethodInvocation *invocation,
257 : : GVariant *force_in_i,
258 : : GVariant *force_in_s,
259 : : GVariant *force_in_ay,
260 : : GVariant *force_in_struct,
261 : : gpointer user_data)
262 : : {
263 : : GVariant *ret_i;
264 : : GVariant *ret_s;
265 : : GVariant *ret_ay;
266 : : GVariant *ret_struct;
267 : : gint32 val;
268 : : gchar *s;
269 : :
270 : 3 : ret_i = g_variant_new_int32 (g_variant_get_int32 (force_in_i) + 10);
271 : 3 : s = g_strdup_printf ("%s_foo", g_variant_get_string (force_in_s, NULL));
272 : 3 : ret_s = g_variant_new_string (s);
273 : 3 : g_free (s);
274 : 3 : s = g_strdup_printf ("%s_foo\xff", g_variant_get_bytestring (force_in_ay));
275 : 3 : ret_ay = g_variant_new_bytestring (s);
276 : 3 : g_free (s);
277 : :
278 : 3 : g_variant_get (force_in_struct, "(i)", &val);
279 : 3 : ret_struct = g_variant_new ("(i)", val + 10);
280 : :
281 : 3 : g_variant_ref_sink (ret_i);
282 : 3 : g_variant_ref_sink (ret_s);
283 : 3 : g_variant_ref_sink (ret_ay);
284 : 3 : g_variant_ref_sink (ret_struct);
285 : :
286 : 3 : foo_igen_bat_emit_force_signal (object,
287 : : ret_i,
288 : : ret_s,
289 : : ret_ay,
290 : : ret_struct);
291 : :
292 : 3 : foo_igen_bat_complete_force_method (object,
293 : : invocation,
294 : : ret_i,
295 : : ret_s,
296 : : ret_ay,
297 : : ret_struct);
298 : :
299 : 3 : g_variant_unref (ret_i);
300 : 3 : g_variant_unref (ret_s);
301 : 3 : g_variant_unref (ret_ay);
302 : 3 : g_variant_unref (ret_struct);
303 : :
304 : 3 : return G_DBUS_METHOD_INVOCATION_HANDLED;
305 : : }
306 : :
307 : :
308 : : /* ---------------------------------------------------------------------------------------------------- */
309 : :
310 : : static gboolean
311 : 6 : my_g_authorize_method_handler (GDBusInterfaceSkeleton *interface,
312 : : GDBusMethodInvocation *invocation,
313 : : gpointer user_data)
314 : : {
315 : : const gchar *method_name;
316 : : gboolean authorized;
317 : :
318 : 6 : authorized = FALSE;
319 : :
320 : 6 : method_name = g_dbus_method_invocation_get_method_name (invocation);
321 [ + + ]: 6 : if (g_strcmp0 (method_name, "CheckNotAuthorized") == 0)
322 : : {
323 : 3 : authorized = FALSE;
324 : : }
325 [ + - ]: 3 : else if (g_strcmp0 (method_name, "CheckAuthorized") == 0)
326 : : {
327 : 3 : authorized = TRUE;
328 : : }
329 [ # # ]: 0 : else if (g_strcmp0 (method_name, "CheckNotAuthorizedFromObject") == 0)
330 : : {
331 : 0 : authorized = TRUE;
332 : : }
333 : : else
334 : : {
335 : : g_assert_not_reached ();
336 : : }
337 : :
338 [ + + ]: 6 : if (!authorized)
339 : : {
340 : 3 : g_dbus_method_invocation_return_error (invocation,
341 : : G_IO_ERROR,
342 : : G_IO_ERROR_PERMISSION_DENIED,
343 : : "not authorized...");
344 : : }
345 : 6 : return authorized;
346 : : }
347 : :
348 : : static gboolean
349 : 9 : my_object_authorize_method_handler (GDBusObjectSkeleton *object,
350 : : GDBusInterfaceSkeleton *interface,
351 : : GDBusMethodInvocation *invocation,
352 : : gpointer user_data)
353 : : {
354 : : const gchar *method_name;
355 : : gboolean authorized;
356 : :
357 : 9 : authorized = FALSE;
358 : :
359 : 9 : method_name = g_dbus_method_invocation_get_method_name (invocation);
360 [ + + ]: 9 : if (g_strcmp0 (method_name, "CheckNotAuthorized") == 0)
361 : : {
362 : 3 : authorized = TRUE;
363 : : }
364 [ + + ]: 6 : else if (g_strcmp0 (method_name, "CheckAuthorized") == 0)
365 : : {
366 : 3 : authorized = TRUE;
367 : : }
368 [ + - ]: 3 : else if (g_strcmp0 (method_name, "CheckNotAuthorizedFromObject") == 0)
369 : : {
370 : 3 : authorized = FALSE;
371 : : }
372 : : else
373 : : {
374 : : g_assert_not_reached ();
375 : : }
376 : :
377 [ + + ]: 9 : if (!authorized)
378 : : {
379 : 3 : g_dbus_method_invocation_return_error (invocation,
380 : : G_IO_ERROR,
381 : : G_IO_ERROR_PENDING,
382 : : "not authorized (from object)...");
383 : : }
384 : 9 : return authorized;
385 : : }
386 : :
387 : : static gboolean
388 : 0 : on_handle_check_not_authorized (FooiGenAuthorize *object,
389 : : GDBusMethodInvocation *invocation,
390 : : gpointer user_data)
391 : : {
392 : 0 : foo_igen_authorize_complete_check_not_authorized (object, invocation);
393 : 0 : return G_DBUS_METHOD_INVOCATION_HANDLED;
394 : : }
395 : :
396 : : static gboolean
397 : 3 : on_handle_check_authorized (FooiGenAuthorize *object,
398 : : GDBusMethodInvocation *invocation,
399 : : gpointer user_data)
400 : : {
401 : 3 : foo_igen_authorize_complete_check_authorized (object, invocation);
402 : 3 : return G_DBUS_METHOD_INVOCATION_HANDLED;
403 : : }
404 : :
405 : : static gboolean
406 : 0 : on_handle_check_not_authorized_from_object (FooiGenAuthorize *object,
407 : : GDBusMethodInvocation *invocation,
408 : : gpointer user_data)
409 : : {
410 : 0 : foo_igen_authorize_complete_check_not_authorized_from_object (object, invocation);
411 : 0 : return G_DBUS_METHOD_INVOCATION_HANDLED;
412 : : }
413 : :
414 : : static gboolean
415 : 3 : on_handle_fdpassing_hello_fd (FooiGenMethodThreads *object,
416 : : GDBusMethodInvocation *invocation,
417 : : GUnixFDList *fd_list,
418 : : const gchar *greeting,
419 : : gpointer user_data)
420 : : {
421 : 3 : g_assert_true (G_IS_UNIX_FD_LIST (fd_list));
422 : 3 : g_assert_cmpuint (g_unix_fd_list_get_length (fd_list), ==, 2);
423 : 3 : g_assert_cmpstr (greeting, ==, "Hey fd!");
424 : 3 : foo_igen_test_fdpassing_complete_hello_fd (FOO_IGEN_TEST_FDPASSING (object),
425 : : invocation, fd_list,
426 : : "I love to receive fds!");
427 : 3 : return G_DBUS_METHOD_INVOCATION_HANDLED;
428 : : }
429 : :
430 : : /* ---------------------------------------------------------------------------------------------------- */
431 : :
432 : : static gboolean
433 : 6 : on_handle_get_self (FooiGenMethodThreads *object,
434 : : GDBusMethodInvocation *invocation,
435 : : gpointer user_data)
436 : : {
437 : : gchar *s;
438 : 6 : s = g_strdup_printf ("%p", (void *)g_thread_self ());
439 : 6 : foo_igen_method_threads_complete_get_self (object, invocation, s);
440 : 6 : g_free (s);
441 : 6 : return G_DBUS_METHOD_INVOCATION_HANDLED;
442 : : }
443 : :
444 : : /* ---------------------------------------------------------------------------------------------------- */
445 : :
446 : : static GThread *method_handler_thread = NULL;
447 : :
448 : : static FooiGenBar *exported_bar_object = NULL;
449 : : static FooiGenBat *exported_bat_object = NULL;
450 : : static FooiGenTestFDPassing *exported_fd_passing_object = NULL;
451 : : static FooiGenAuthorize *exported_authorize_object = NULL;
452 : : static GDBusObjectSkeleton *authorize_enclosing_object = NULL;
453 : : static FooiGenMethodThreads *exported_thread_object_1 = NULL;
454 : : static FooiGenMethodThreads *exported_thread_object_2 = NULL;
455 : :
456 : : static void
457 : 3 : unexport_objects (void)
458 : : {
459 : 3 : g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (exported_bar_object));
460 : 3 : g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (exported_bat_object));
461 : 3 : g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (exported_authorize_object));
462 : 3 : g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (exported_thread_object_1));
463 : 3 : g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (exported_thread_object_2));
464 : 3 : g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (exported_fd_passing_object));
465 : 3 : }
466 : :
467 : : static void
468 : 3 : on_bus_acquired (GDBusConnection *connection,
469 : : const gchar *name,
470 : : gpointer user_data)
471 : : {
472 : : GError *error;
473 : :
474 : : /* Test that we can export an object using the generated
475 : : * FooiGenBarSkeleton subclass. Notes:
476 : : *
477 : : * 1. We handle methods by simply connecting to the appropriate
478 : : * GObject signal.
479 : : *
480 : : * 2. Property storage is taken care of by the class; we can
481 : : * use g_object_get()/g_object_set() (and the generated
482 : : * C bindings at will)
483 : : */
484 : 3 : error = NULL;
485 : 3 : exported_bar_object = foo_igen_bar_skeleton_new ();
486 : 3 : foo_igen_bar_set_ay (exported_bar_object, "ABCabc");
487 : 3 : foo_igen_bar_set_y (exported_bar_object, 42);
488 : 3 : foo_igen_bar_set_d (exported_bar_object, 43.0);
489 : 3 : foo_igen_bar_set_finally_normal_name (exported_bar_object, "There aint no place like home");
490 : 3 : foo_igen_bar_set_writeonly_property (exported_bar_object, "Mr. Burns");
491 : :
492 : : /* The following works because it's on the Skeleton object - it will
493 : : * fail (at run-time) on a Proxy (see on_proxy_appeared() below)
494 : : */
495 : 3 : foo_igen_bar_set_readonly_property (exported_bar_object, "blah");
496 : 3 : g_assert_cmpstr (foo_igen_bar_get_writeonly_property (exported_bar_object), ==, "Mr. Burns");
497 : :
498 : 3 : g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (exported_bar_object),
499 : : connection,
500 : : "/bar",
501 : : &error);
502 : 3 : g_assert_no_error (error);
503 : 3 : g_signal_connect (exported_bar_object,
504 : : "handle-hello-world",
505 : : G_CALLBACK (on_handle_hello_world),
506 : : NULL);
507 : 3 : g_signal_connect (exported_bar_object,
508 : : "handle-test-primitive-types",
509 : : G_CALLBACK (on_handle_test_primitive_types),
510 : : NULL);
511 : 3 : g_signal_connect (exported_bar_object,
512 : : "handle-test-non-primitive-types",
513 : : G_CALLBACK (on_handle_test_non_primitive_types),
514 : : NULL);
515 : 3 : g_signal_connect (exported_bar_object,
516 : : "handle-request-signal-emission",
517 : : G_CALLBACK (on_handle_request_signal_emission),
518 : : NULL);
519 : 3 : g_signal_connect (exported_bar_object,
520 : : "handle-request-multi-property-mods",
521 : : G_CALLBACK (on_handle_request_multi_property_mods),
522 : : NULL);
523 : 3 : g_signal_connect (exported_bar_object,
524 : : "handle-property-cancellation",
525 : : G_CALLBACK (on_handle_property_cancellation),
526 : : NULL);
527 : :
528 : 3 : exported_bat_object = foo_igen_bat_skeleton_new ();
529 : 3 : g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (exported_bat_object),
530 : : connection,
531 : : "/bat",
532 : : &error);
533 : 3 : g_assert_no_error (error);
534 : 3 : g_signal_connect (exported_bat_object,
535 : : "handle-force-method",
536 : : G_CALLBACK (on_handle_force_method),
537 : : NULL);
538 : 3 : g_object_set (exported_bat_object,
539 : : "force-i", g_variant_new_int32 (43),
540 : : "force-s", g_variant_new_string ("prop string"),
541 : : "force-ay", g_variant_new_bytestring ("prop bytestring\xff"),
542 : : "force-struct", g_variant_new ("(i)", 4300),
543 : : NULL);
544 : :
545 : 3 : authorize_enclosing_object = g_dbus_object_skeleton_new ("/authorize");
546 : 3 : g_signal_connect (authorize_enclosing_object,
547 : : "authorize-method",
548 : : G_CALLBACK (my_object_authorize_method_handler),
549 : : NULL);
550 : 3 : exported_authorize_object = foo_igen_authorize_skeleton_new ();
551 : 3 : g_dbus_object_skeleton_add_interface (authorize_enclosing_object,
552 : 3 : G_DBUS_INTERFACE_SKELETON (exported_authorize_object));
553 : 3 : g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (exported_authorize_object),
554 : : connection,
555 : : "/authorize",
556 : : &error);
557 : 3 : g_assert_no_error (error);
558 : 3 : g_signal_connect (exported_authorize_object,
559 : : "g-authorize-method",
560 : : G_CALLBACK (my_g_authorize_method_handler),
561 : : NULL);
562 : 3 : g_signal_connect (exported_authorize_object,
563 : : "handle-check-not-authorized",
564 : : G_CALLBACK (on_handle_check_not_authorized),
565 : : NULL);
566 : 3 : g_signal_connect (exported_authorize_object,
567 : : "handle-check-authorized",
568 : : G_CALLBACK (on_handle_check_authorized),
569 : : NULL);
570 : 3 : g_signal_connect (exported_authorize_object,
571 : : "handle-check-not-authorized-from-object",
572 : : G_CALLBACK (on_handle_check_not_authorized_from_object),
573 : : NULL);
574 : :
575 : :
576 : : /* only object 1 has the G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD flag set */
577 : 3 : exported_thread_object_1 = foo_igen_method_threads_skeleton_new ();
578 : 3 : g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (exported_thread_object_1),
579 : : G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD);
580 : :
581 : 3 : g_assert (!g_dbus_interface_skeleton_has_connection (G_DBUS_INTERFACE_SKELETON (exported_thread_object_1), connection));
582 : 3 : g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (exported_thread_object_1),
583 : : connection,
584 : : "/method_threads_1",
585 : : &error);
586 : 3 : g_assert_no_error (error);
587 : 3 : g_signal_connect (exported_thread_object_1,
588 : : "handle-get-self",
589 : : G_CALLBACK (on_handle_get_self),
590 : : NULL);
591 : 3 : g_assert_cmpint (g_dbus_interface_skeleton_get_flags (G_DBUS_INTERFACE_SKELETON (exported_thread_object_1)), ==, G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD);
592 : :
593 : 3 : exported_thread_object_2 = foo_igen_method_threads_skeleton_new ();
594 : 3 : g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (exported_thread_object_2),
595 : : connection,
596 : : "/method_threads_2",
597 : : &error);
598 : 3 : g_assert_no_error (error);
599 : 3 : g_signal_connect (exported_thread_object_2,
600 : : "handle-get-self",
601 : : G_CALLBACK (on_handle_get_self),
602 : : NULL);
603 : :
604 : 3 : g_assert_cmpint (g_dbus_interface_skeleton_get_flags (G_DBUS_INTERFACE_SKELETON (exported_thread_object_2)), ==, G_DBUS_INTERFACE_SKELETON_FLAGS_NONE);
605 : :
606 : 3 : exported_fd_passing_object = foo_igen_test_fdpassing_skeleton_new ();
607 : 3 : g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (exported_fd_passing_object),
608 : : connection,
609 : : "/fdpassing",
610 : : &error);
611 : 3 : g_assert_no_error (error);
612 : 3 : g_signal_connect (exported_fd_passing_object,
613 : : "handle-hello-fd",
614 : : G_CALLBACK (on_handle_fdpassing_hello_fd),
615 : : NULL);
616 : :
617 : 3 : method_handler_thread = g_thread_self ();
618 : 3 : }
619 : :
620 : : static gpointer check_proxies_in_thread (gpointer user_data);
621 : :
622 : : static void
623 : 3 : on_name_acquired (GDBusConnection *connection,
624 : : const gchar *name,
625 : : gpointer user_data)
626 : : {
627 : 3 : GMainLoop *loop = user_data;
628 : 3 : GThread *thread = g_thread_new ("check-proxies", check_proxies_in_thread, loop);
629 : 3 : g_thread_unref (thread);
630 : 3 : }
631 : :
632 : : static void
633 : 0 : on_name_lost (GDBusConnection *connection,
634 : : const gchar *name,
635 : : gpointer user_data)
636 : : {
637 : : g_assert_not_reached ();
638 : : }
639 : :
640 : : /* ---------------------------------------------------------------------------------------------------- */
641 : :
642 : : typedef struct
643 : : {
644 : : GMainLoop *thread_loop;
645 : : gint initial_y;
646 : : gint initial_i;
647 : : guint num_g_properties_changed;
648 : : gboolean received_test_signal;
649 : : guint num_notify_u;
650 : : guint num_notify_n;
651 : : } ClientData;
652 : :
653 : : static void
654 : 9 : on_notify_u (GObject *object,
655 : : GParamSpec *pspec,
656 : : gpointer user_data)
657 : : {
658 : 9 : ClientData *data = user_data;
659 : 9 : g_assert_cmpstr (pspec->name, ==, "u");
660 : 9 : data->num_notify_u += 1;
661 : 9 : }
662 : :
663 : : static void
664 : 6 : on_notify_n (GObject *object,
665 : : GParamSpec *pspec,
666 : : gpointer user_data)
667 : : {
668 : 6 : ClientData *data = user_data;
669 : 6 : g_assert_cmpstr (pspec->name, ==, "n");
670 : 6 : data->num_notify_n += 1;
671 : 6 : }
672 : :
673 : : static void
674 : 6 : on_g_properties_changed (GDBusProxy *_proxy,
675 : : GVariant *changed_properties,
676 : : const gchar* const *invalidated_properties,
677 : : gpointer user_data)
678 : : {
679 : 6 : ClientData *data = user_data;
680 : 6 : FooiGenBar *proxy = FOO_IGEN_BAR (_proxy);
681 : :
682 : 6 : g_assert_cmpint (g_variant_n_children (changed_properties), ==, 2);
683 : :
684 [ + + ]: 6 : if (data->num_g_properties_changed == 0)
685 : : {
686 : 3 : g_assert_cmpint (data->initial_y, ==, foo_igen_bar_get_y (proxy) - 2);
687 : 3 : g_assert_cmpint (data->initial_i, ==, foo_igen_bar_get_i (proxy) - 2);
688 : : }
689 [ + - ]: 3 : else if (data->num_g_properties_changed == 1)
690 : : {
691 : 3 : g_assert_cmpint (data->initial_y, ==, foo_igen_bar_get_y (proxy) - 3);
692 : 3 : g_assert_cmpint (data->initial_i, ==, foo_igen_bar_get_i (proxy) - 3);
693 : : }
694 : : else
695 : : g_assert_not_reached ();
696 : :
697 : 6 : data->num_g_properties_changed++;
698 : :
699 [ + + ]: 6 : if (data->num_g_properties_changed == 2)
700 : 3 : g_main_loop_quit (data->thread_loop);
701 : 6 : }
702 : :
703 : : static void
704 : 3 : on_test_signal (FooiGenBar *proxy,
705 : : gint val_int32,
706 : : const gchar* const *array_of_strings,
707 : : const gchar* const *array_of_bytestrings,
708 : : GVariant *dict_s_to_pairs,
709 : : gpointer user_data)
710 : : {
711 : 3 : ClientData *data = user_data;
712 : :
713 : 3 : g_assert_cmpint (val_int32, ==, 43);
714 : 3 : g_assert_cmpstr (array_of_strings[0], ==, "foo");
715 : 3 : g_assert_cmpstr (array_of_strings[1], ==, "bar");
716 : 3 : g_assert (array_of_strings[2] == NULL);
717 : 3 : g_assert_cmpstr (array_of_bytestrings[0], ==, "foo\xff");
718 : 3 : g_assert_cmpstr (array_of_bytestrings[1], ==, "bar\xff");
719 : 3 : g_assert (array_of_bytestrings[2] == NULL);
720 : :
721 : 3 : data->received_test_signal = TRUE;
722 : 3 : g_main_loop_quit (data->thread_loop);
723 : 3 : }
724 : :
725 : : static void
726 : 3 : on_property_cancellation_cb (FooiGenBar *proxy,
727 : : GAsyncResult *res,
728 : : gpointer user_data)
729 : : {
730 : 3 : ClientData *data = user_data;
731 : : gboolean ret;
732 : 3 : GError *error = NULL;
733 : :
734 : 3 : error = NULL;
735 : 3 : ret = foo_igen_bar_call_property_cancellation_finish (proxy, res, &error);
736 : 3 : g_assert_no_error (error);
737 : 3 : g_assert (ret);
738 : :
739 : 3 : g_main_loop_quit (data->thread_loop);
740 : 3 : }
741 : :
742 : : static void
743 : 3 : check_bar_proxy (FooiGenBar *proxy,
744 : : GMainLoop *thread_loop)
745 : : {
746 : 3 : const gchar *array_of_strings[3] = {"one", "two", NULL};
747 : 3 : const gchar *array_of_strings_2[3] = {"one2", "two2", NULL};
748 : 3 : const gchar *array_of_objpaths[3] = {"/one", "/one/two", NULL};
749 : 3 : GVariant *array_of_signatures = NULL;
750 : 3 : const gchar *array_of_bytestrings[3] = {"one\xff", "two\xff", NULL};
751 : 3 : gchar **ret_array_of_strings = NULL;
752 : 3 : gchar **ret_array_of_objpaths = NULL;
753 : 3 : GVariant *ret_array_of_signatures = NULL;
754 : 3 : gchar **ret_array_of_bytestrings = NULL;
755 : : guchar ret_val_byte;
756 : : gboolean ret_val_boolean;
757 : : gint16 ret_val_int16;
758 : : guint16 ret_val_uint16;
759 : : gint ret_val_int32;
760 : : guint ret_val_uint32;
761 : : gint64 ret_val_int64;
762 : : guint64 ret_val_uint64;
763 : : gdouble ret_val_double;
764 : : gchar *ret_val_string;
765 : : gchar *ret_val_objpath;
766 : : gchar *ret_val_signature;
767 : : gchar *ret_val_bytestring;
768 : : gboolean ret;
769 : : GError *error;
770 : : ClientData *data;
771 : : guchar val_y;
772 : : gboolean val_b;
773 : : gint val_n;
774 : : guint val_q;
775 : : gint val_i;
776 : : guint val_u;
777 : : gint64 val_x;
778 : : guint64 val_t;
779 : : gdouble val_d;
780 : : gchar *val_s;
781 : : gchar *val_o;
782 : : gchar *val_g;
783 : : gchar *val_ay;
784 : : gchar **val_as;
785 : : gchar **val_ao;
786 : : GVariant *val_ag;
787 : : gint32 val_unset_i;
788 : : gdouble val_unset_d;
789 : : gchar *val_unset_s;
790 : : gchar *val_unset_o;
791 : : gchar *val_unset_g;
792 : : gchar *val_unset_ay;
793 : : gchar **val_unset_as;
794 : : gchar **val_unset_ao;
795 : : GVariant *val_unset_ag;
796 : : GVariant *val_unset_struct;
797 : : gchar *val_finally_normal_name;
798 : : GVariant *v;
799 : : gchar *s;
800 : : const gchar *const *read_as;
801 : : const gchar *const *read_as2;
802 : : const gchar *const *read_as3;
803 : :
804 : 3 : data = g_new0 (ClientData, 1);
805 : 3 : data->thread_loop = thread_loop;
806 : :
807 : 3 : v = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "y");
808 : 3 : g_assert (v != NULL);
809 : 3 : g_variant_unref (v);
810 : :
811 : : /* set empty values to non-empty */
812 : 3 : val_unset_i = 42;
813 : 3 : val_unset_d = 42.0;
814 : 3 : val_unset_s = "42";
815 : 3 : val_unset_o = "42";
816 : 3 : val_unset_g = "42";
817 : 3 : val_unset_ay = NULL;
818 : 3 : val_unset_as = NULL;
819 : 3 : val_unset_ao = NULL;
820 : 3 : val_unset_ag = NULL;
821 : 3 : val_unset_struct = NULL;
822 : : /* check properties */
823 : 3 : g_object_get (proxy,
824 : : "y", &val_y,
825 : : "b", &val_b,
826 : : "n", &val_n,
827 : : "q", &val_q,
828 : : "i", &val_i,
829 : : "u", &val_u,
830 : : "x", &val_x,
831 : : "t", &val_t,
832 : : "d", &val_d,
833 : : "s", &val_s,
834 : : "o", &val_o,
835 : : "g", &val_g,
836 : : "ay", &val_ay,
837 : : "as", &val_as,
838 : : "ao", &val_ao,
839 : : "ag", &val_ag,
840 : : "unset_i", &val_unset_i,
841 : : "unset_d", &val_unset_d,
842 : : "unset_s", &val_unset_s,
843 : : "unset_o", &val_unset_o,
844 : : "unset_g", &val_unset_g,
845 : : "unset_ay", &val_unset_ay,
846 : : "unset_as", &val_unset_as,
847 : : "unset_ao", &val_unset_ao,
848 : : "unset_ag", &val_unset_ag,
849 : : "unset_struct", &val_unset_struct,
850 : : "finally-normal-name", &val_finally_normal_name,
851 : : NULL);
852 : 3 : g_assert_cmpint (val_y, ==, 42);
853 : 3 : g_assert_cmpstr (val_finally_normal_name, ==, "There aint no place like home");
854 : 3 : g_free (val_s);
855 : 3 : g_free (val_o);
856 : 3 : g_free (val_g);
857 : 3 : g_assert_cmpstr (val_ay, ==, "ABCabc");
858 : 3 : g_free (val_ay);
859 : 3 : g_strfreev (val_as);
860 : 3 : g_strfreev (val_ao);
861 : 3 : g_variant_unref (val_ag);
862 : 3 : g_free (val_finally_normal_name);
863 : : /* check empty values */
864 : 3 : g_assert_cmpint (val_unset_i, ==, 0);
865 : 3 : g_assert_cmpfloat (val_unset_d, ==, 0.0);
866 : 3 : g_assert_cmpstr (val_unset_s, ==, "");
867 : 3 : g_assert_cmpstr (val_unset_o, ==, "/");
868 : 3 : g_assert_cmpstr (val_unset_g, ==, "");
869 : 3 : g_free (val_unset_s);
870 : 3 : g_free (val_unset_o);
871 : 3 : g_free (val_unset_g);
872 : 3 : g_assert_cmpstr (val_unset_ay, ==, "");
873 : 3 : g_assert (val_unset_as[0] == NULL);
874 : 3 : g_assert (val_unset_ao[0] == NULL);
875 : 3 : g_assert (g_variant_is_of_type (val_unset_ag, G_VARIANT_TYPE ("ag")));
876 : 3 : g_assert (g_variant_is_of_type (val_unset_struct, G_VARIANT_TYPE ("(idsogayasaoag)")));
877 : 3 : s = g_variant_print (val_unset_struct, TRUE);
878 : 3 : g_assert_cmpstr (s, ==, "(0, 0.0, '', objectpath '/', signature '', @ay [], @as [], @ao [], @ag [])");
879 : 3 : g_free (s);
880 : 3 : g_free (val_unset_ay);
881 : 3 : g_strfreev (val_unset_as);
882 : 3 : g_strfreev (val_unset_ao);
883 : 3 : g_variant_unref (val_unset_ag);
884 : 3 : g_variant_unref (val_unset_struct);
885 : :
886 : : /* Try setting a property. This causes the generated glue to invoke
887 : : * the org.fd.DBus.Properties.Set() method asynchronously. So we
888 : : * have to wait for properties-changed...
889 : : */
890 : 3 : foo_igen_bar_set_finally_normal_name (proxy, "foo!");
891 : 3 : _g_assert_property_notify (proxy, "finally-normal-name");
892 : 3 : g_assert_cmpstr (foo_igen_bar_get_finally_normal_name (proxy), ==, "foo!");
893 : :
894 : : /* Try setting properties that requires memory management. This
895 : : * is to exercise the paths that frees the references.
896 : : */
897 : :
898 : 3 : g_object_set (proxy,
899 : : "s", "a string",
900 : : "o", "/a/path",
901 : : "g", "asig",
902 : : "ay", "eg",
903 : : "as", array_of_strings,
904 : : "ao", array_of_objpaths,
905 : : "ag", g_variant_new_parsed ("[@g 'ass', 'git']"),
906 : : NULL);
907 : :
908 : 3 : error = NULL;
909 : 3 : ret = foo_igen_bar_call_test_primitive_types_sync (proxy,
910 : : 10,
911 : : TRUE,
912 : : 11,
913 : : 12,
914 : : 13,
915 : : 14,
916 : : 15,
917 : : 16,
918 : : 17,
919 : : "a string",
920 : : "/a/path",
921 : : "asig",
922 : : "bytestring\xff",
923 : : #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64
924 : : G_DBUS_CALL_FLAGS_NONE,
925 : : -1,
926 : : #endif
927 : : &ret_val_byte,
928 : : &ret_val_boolean,
929 : : &ret_val_int16,
930 : : &ret_val_uint16,
931 : : &ret_val_int32,
932 : : &ret_val_uint32,
933 : : &ret_val_int64,
934 : : &ret_val_uint64,
935 : : &ret_val_double,
936 : : &ret_val_string,
937 : : &ret_val_objpath,
938 : : &ret_val_signature,
939 : : &ret_val_bytestring,
940 : : NULL, /* GCancellable */
941 : : &error);
942 : 3 : g_assert_no_error (error);
943 : 3 : g_assert (ret);
944 : :
945 : 3 : g_clear_pointer (&ret_val_string, g_free);
946 : 3 : g_clear_pointer (&ret_val_objpath, g_free);
947 : 3 : g_clear_pointer (&ret_val_signature, g_free);
948 : 3 : g_clear_pointer (&ret_val_bytestring, g_free);
949 : :
950 : 3 : error = NULL;
951 : 3 : array_of_signatures = g_variant_ref_sink (g_variant_new_parsed ("[@g 'ass', 'git']"));
952 : 3 : ret = foo_igen_bar_call_test_non_primitive_types_sync (proxy,
953 : : g_variant_new_parsed ("{'one': 'red',"
954 : : " 'two': 'blue'}"),
955 : : g_variant_new_parsed ("{'first': (42, 42), "
956 : : "'second': (43, 43)}"),
957 : : g_variant_new_parsed ("(42, 'foo', 'bar')"),
958 : : array_of_strings,
959 : : array_of_objpaths,
960 : : array_of_signatures,
961 : : array_of_bytestrings,
962 : : #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64
963 : : G_DBUS_CALL_FLAGS_NONE,
964 : : -1,
965 : : #endif
966 : : &ret_array_of_strings,
967 : : &ret_array_of_objpaths,
968 : : &ret_array_of_signatures,
969 : : &ret_array_of_bytestrings,
970 : : &s,
971 : : NULL, /* GCancellable */
972 : : &error);
973 : :
974 : 3 : g_assert_no_error (error);
975 : 3 : g_assert (ret);
976 : :
977 : 3 : g_assert_nonnull (ret_array_of_strings);
978 : 3 : g_assert_cmpuint (g_strv_length ((gchar **) ret_array_of_strings), ==,
979 : : g_strv_length ((gchar **) array_of_strings));
980 : 3 : g_assert_nonnull (ret_array_of_objpaths);
981 : 3 : g_assert_cmpuint (g_strv_length ((gchar **) ret_array_of_objpaths), ==,
982 : : g_strv_length ((gchar **) array_of_objpaths));
983 : 3 : g_assert_nonnull (ret_array_of_signatures);
984 : 3 : g_assert_cmpvariant (ret_array_of_signatures, array_of_signatures);
985 : 3 : g_assert_nonnull (ret_array_of_bytestrings);
986 : 3 : g_assert_cmpuint (g_strv_length ((gchar **) ret_array_of_bytestrings), ==,
987 : : g_strv_length ((gchar **) array_of_bytestrings));
988 : :
989 : 3 : g_clear_pointer (&ret_array_of_strings, g_strfreev);
990 : 3 : g_clear_pointer (&ret_array_of_objpaths, g_strfreev);
991 : 3 : g_clear_pointer (&ret_array_of_signatures, g_variant_unref);
992 : 3 : g_clear_pointer (&ret_array_of_bytestrings, g_strfreev);
993 : 3 : g_clear_pointer (&s, g_free);
994 : :
995 : : /* Check that org.freedesktop.DBus.Error.UnknownMethod is returned on
996 : : * unimplemented methods.
997 : : */
998 : 3 : error = NULL;
999 : : #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64
1000 : 1 : ret = foo_igen_bar_call_unimplemented_method_sync (proxy, G_DBUS_CALL_FLAGS_NONE, -1, NULL /* GCancellable */, &error);
1001 : : #else
1002 : 2 : ret = foo_igen_bar_call_unimplemented_method_sync (proxy, NULL /* GCancellable */, &error);
1003 : : #endif
1004 : 3 : g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD);
1005 : 3 : g_error_free (error);
1006 : 3 : error = NULL;
1007 : 3 : g_assert (!ret);
1008 : :
1009 : 3 : g_signal_connect (proxy,
1010 : : "test-signal",
1011 : : G_CALLBACK (on_test_signal),
1012 : : data);
1013 : 3 : error = NULL;
1014 : : #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64
1015 : 1 : ret = foo_igen_bar_call_request_signal_emission_sync (proxy, 0, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1016 : : #else
1017 : 2 : ret = foo_igen_bar_call_request_signal_emission_sync (proxy, 0, NULL, &error);
1018 : : #endif
1019 : 3 : g_assert_no_error (error);
1020 : 3 : g_assert (ret);
1021 : :
1022 : 3 : g_assert (!data->received_test_signal);
1023 : 3 : g_main_loop_run (thread_loop);
1024 : 3 : g_assert (data->received_test_signal);
1025 : :
1026 : : /* Try setting a property. This causes the generated glue to invoke
1027 : : * the org.fd.DBus.Properties.Set() method asynchronously. So we
1028 : : * have to wait for properties-changed...
1029 : : */
1030 : 3 : foo_igen_bar_set_finally_normal_name (proxy, "hey back!");
1031 : 3 : _g_assert_property_notify (proxy, "finally-normal-name");
1032 : 3 : g_assert_cmpstr (foo_igen_bar_get_finally_normal_name (proxy), ==, "hey back!");
1033 : :
1034 : : /* Check that multiple calls to a strv getter works... and that
1035 : : * updates on them works as well (See comment for "property vfuncs"
1036 : : * in gio/gdbus-codegen/codegen.py for details)
1037 : : */
1038 : 3 : read_as = foo_igen_bar_get_as (proxy);
1039 : 3 : read_as2 = foo_igen_bar_get_as (proxy);
1040 : 3 : g_assert_cmpint (g_strv_length ((gchar **) read_as), ==, 2);
1041 : 3 : g_assert_cmpstr (read_as[0], ==, "one");
1042 : 3 : g_assert_cmpstr (read_as[1], ==, "two");
1043 : 3 : g_assert (read_as == read_as2); /* this is more testing an implementation detail */
1044 : 3 : g_object_set (proxy,
1045 : : "as", array_of_strings_2,
1046 : : NULL);
1047 : 3 : _g_assert_property_notify (proxy, "as");
1048 : 3 : read_as3 = foo_igen_bar_get_as (proxy);
1049 : 3 : g_assert_cmpint (g_strv_length ((gchar **) read_as3), ==, 2);
1050 : 3 : g_assert_cmpstr (read_as3[0], ==, "one2");
1051 : 3 : g_assert_cmpstr (read_as3[1], ==, "two2");
1052 : :
1053 : : /* Check that grouping changes in idle works.
1054 : : *
1055 : : * See on_handle_request_multi_property_mods(). The server should
1056 : : * emit exactly two PropertiesChanged signals each containing two
1057 : : * properties.
1058 : : *
1059 : : * On the first reception, y and i should both be increased by
1060 : : * two. On the second reception, only by one. The signal handler
1061 : : * checks this.
1062 : : *
1063 : : * This also checks that _drain_notify() works.
1064 : : */
1065 : 3 : data->initial_y = foo_igen_bar_get_y (proxy);
1066 : 3 : data->initial_i = foo_igen_bar_get_i (proxy);
1067 : 3 : g_signal_connect (proxy,
1068 : : "g-properties-changed",
1069 : : G_CALLBACK (on_g_properties_changed),
1070 : : data);
1071 : 3 : error = NULL;
1072 : : #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64
1073 : 1 : ret = foo_igen_bar_call_request_multi_property_mods_sync (proxy, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1074 : : #else
1075 : 2 : ret = foo_igen_bar_call_request_multi_property_mods_sync (proxy, NULL, &error);
1076 : : #endif
1077 : 3 : g_assert_no_error (error);
1078 : 3 : g_assert (ret);
1079 : 3 : g_main_loop_run (thread_loop);
1080 : 3 : g_assert_cmpint (data->num_g_properties_changed, ==, 2);
1081 : 3 : g_signal_handlers_disconnect_by_func (proxy,
1082 : : G_CALLBACK (on_g_properties_changed),
1083 : : data);
1084 : :
1085 : : /* Check that we don't emit PropertiesChanged() if the property
1086 : : * didn't change... we actually get two notifies.. one for the
1087 : : * local set (without a value change) and one when receiving
1088 : : * the PropertiesChanged() signal generated from the remote end.
1089 : : */
1090 : 3 : g_assert_cmpint (data->num_notify_u, ==, 0);
1091 : 3 : g_signal_connect (proxy,
1092 : : "notify::u",
1093 : : G_CALLBACK (on_notify_u),
1094 : : data);
1095 : 3 : foo_igen_bar_set_u (proxy, 1042);
1096 : 3 : g_assert_cmpint (data->num_notify_u, ==, 1);
1097 : 3 : g_assert_cmpint (foo_igen_bar_get_u (proxy), ==, 0);
1098 : 3 : _g_assert_property_notify (proxy, "u");
1099 : 3 : g_assert_cmpint (foo_igen_bar_get_u (proxy), ==, 1042);
1100 : 3 : g_assert_cmpint (data->num_notify_u, ==, 2);
1101 : :
1102 : : /* Now change u again to the same value.. this will cause a
1103 : : * local notify:: notify and the usual Properties.Set() call
1104 : : *
1105 : : * (Btw, why also the Set() call if the value in the cache is
1106 : : * the same? Because someone else might have changed it
1107 : : * in the mean time and we're just waiting to receive the
1108 : : * PropertiesChanged() signal...)
1109 : : *
1110 : : * More tricky - how do we check for the *absence* of the
1111 : : * notification that u changed? Simple: we change another
1112 : : * property and wait for that PropertiesChanged() message
1113 : : * to arrive.
1114 : : */
1115 : 3 : foo_igen_bar_set_u (proxy, 1042);
1116 : 3 : g_assert_cmpint (data->num_notify_u, ==, 3);
1117 : :
1118 : 3 : g_assert_cmpint (data->num_notify_n, ==, 0);
1119 : 3 : g_signal_connect (proxy,
1120 : : "notify::n",
1121 : : G_CALLBACK (on_notify_n),
1122 : : data);
1123 : 3 : foo_igen_bar_set_n (proxy, 10042);
1124 : 3 : g_assert_cmpint (data->num_notify_n, ==, 1);
1125 : 3 : g_assert_cmpint (foo_igen_bar_get_n (proxy), ==, 0);
1126 : 3 : _g_assert_property_notify (proxy, "n");
1127 : 3 : g_assert_cmpint (foo_igen_bar_get_n (proxy), ==, 10042);
1128 : 3 : g_assert_cmpint (data->num_notify_n, ==, 2);
1129 : : /* Checks that u didn't change at all */
1130 : 3 : g_assert_cmpint (data->num_notify_u, ==, 3);
1131 : :
1132 : : /* Now we check that if the service does
1133 : : *
1134 : : * guint n = foo_igen_bar_get_n (foo);
1135 : : * foo_igen_bar_set_n (foo, n + 1);
1136 : : * foo_igen_bar_set_n (foo, n);
1137 : : *
1138 : : * then no PropertiesChanged() signal is emitted!
1139 : : */
1140 : 3 : error = NULL;
1141 : 3 : foo_igen_bar_call_property_cancellation (proxy,
1142 : : #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64
1143 : : G_DBUS_CALL_FLAGS_NONE,
1144 : : -1,
1145 : : #endif
1146 : : NULL, /* GCancellable */
1147 : : (GAsyncReadyCallback) on_property_cancellation_cb,
1148 : : data);
1149 : 3 : g_main_loop_run (thread_loop);
1150 : : /* Checks that n didn't change at all */
1151 : 3 : g_assert_cmpint (data->num_notify_n, ==, 2);
1152 : :
1153 : : /* cleanup */
1154 : 3 : g_free (data);
1155 : 3 : g_variant_unref (array_of_signatures);
1156 : 3 : }
1157 : :
1158 : : static void
1159 : 3 : check_fdpassing_proxy (FooiGenTestFDPassing *proxy)
1160 : : {
1161 : 3 : GError *error = NULL;
1162 : 3 : GUnixFDList *fd_list = g_unix_fd_list_new ();
1163 : 3 : GUnixFDList *ret_fd_list = NULL;
1164 : 3 : char *response = NULL;
1165 : : int fd;
1166 : :
1167 : 3 : fd = dup (0);
1168 : 3 : g_assert_cmpint (g_unix_fd_list_append (fd_list, fd, &error), ==, 0);
1169 : 3 : g_assert_no_error (error);
1170 : 3 : g_close (fd, &error);
1171 : 3 : g_assert_no_error (error);
1172 : :
1173 : 3 : fd = dup (0);
1174 : 3 : g_assert_cmpint (g_unix_fd_list_append (fd_list, fd, &error), ==, 1);
1175 : 3 : g_assert_no_error (error);
1176 : 3 : g_close (fd, &error);
1177 : 3 : g_assert_no_error (error);
1178 : :
1179 : 3 : foo_igen_test_fdpassing_call_hello_fd_sync (proxy, "Hey fd!",
1180 : : #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64
1181 : : G_DBUS_CALL_FLAGS_NO_AUTO_START, -1,
1182 : : #endif
1183 : : fd_list,
1184 : : &response, &ret_fd_list, NULL,
1185 : : &error);
1186 : 3 : g_assert_no_error (error);
1187 : :
1188 : 3 : g_assert_true (G_IS_UNIX_FD_LIST (ret_fd_list));
1189 : 3 : g_assert_cmpuint (g_unix_fd_list_get_length (fd_list), ==, 2);
1190 : :
1191 : 3 : g_assert_cmpstr (response, ==, "I love to receive fds!");
1192 : 3 : g_clear_pointer (&response, g_free);
1193 : 3 : g_clear_object (&fd_list);
1194 : 3 : g_clear_object (&ret_fd_list);
1195 : 3 : }
1196 : :
1197 : : /* ---------------------------------------------------------------------------------------------------- */
1198 : :
1199 : : static void
1200 : 3 : on_force_signal (FooiGenBat *proxy,
1201 : : GVariant *force_i,
1202 : : GVariant *force_s,
1203 : : GVariant *force_ay,
1204 : : GVariant *force_struct,
1205 : : gpointer user_data)
1206 : : {
1207 : 3 : gboolean *signal_received = user_data;
1208 : : gint val;
1209 : :
1210 : 3 : g_assert (!(*signal_received));
1211 : :
1212 : 3 : g_assert_cmpint (g_variant_get_int32 (force_i), ==, 42 + 10);
1213 : 3 : g_assert_cmpstr (g_variant_get_string (force_s, NULL), ==, "a string_foo");
1214 : 3 : g_assert_cmpstr (g_variant_get_bytestring (force_ay), ==, "a bytestring\xff_foo\xff");
1215 : 3 : g_variant_get (force_struct, "(i)", &val);
1216 : 3 : g_assert_cmpint (val, ==, 4200 + 10);
1217 : :
1218 : 3 : *signal_received = TRUE;
1219 : 3 : }
1220 : :
1221 : : static void
1222 : 3 : check_bat_proxy (FooiGenBat *proxy,
1223 : : GMainLoop *thread_loop)
1224 : : {
1225 : : GError *error;
1226 : : GVariant *ret_i;
1227 : : GVariant *ret_s;
1228 : : GVariant *ret_ay;
1229 : : GVariant *ret_struct;
1230 : : gint val;
1231 : : gboolean force_signal_received;
1232 : :
1233 : : /* --------------------------------------------------- */
1234 : : /* Check type-mapping where we force use of a GVariant */
1235 : : /* --------------------------------------------------- */
1236 : :
1237 : : /* check properties */
1238 : 3 : g_object_get (proxy,
1239 : : "force-i", &ret_i,
1240 : : "force-s", &ret_s,
1241 : : "force-ay", &ret_ay,
1242 : : "force-struct", &ret_struct,
1243 : : NULL);
1244 : 3 : g_assert_cmpint (g_variant_get_int32 (ret_i), ==, 43);
1245 : 3 : g_assert_cmpstr (g_variant_get_string (ret_s, NULL), ==, "prop string");
1246 : 3 : g_assert_cmpstr (g_variant_get_bytestring (ret_ay), ==, "prop bytestring\xff");
1247 : 3 : g_variant_get (ret_struct, "(i)", &val);
1248 : 3 : g_assert_cmpint (val, ==, 4300);
1249 : 3 : g_variant_unref (ret_i);
1250 : 3 : g_variant_unref (ret_s);
1251 : 3 : g_variant_unref (ret_ay);
1252 : 3 : g_variant_unref (ret_struct);
1253 : :
1254 : : /* check method and signal */
1255 : 3 : force_signal_received = FALSE;
1256 : 3 : g_signal_connect (proxy,
1257 : : "force-signal",
1258 : : G_CALLBACK (on_force_signal),
1259 : : &force_signal_received);
1260 : :
1261 : 3 : error = NULL;
1262 : 3 : foo_igen_bat_call_force_method_sync (proxy,
1263 : : g_variant_new_int32 (42),
1264 : : g_variant_new_string ("a string"),
1265 : : g_variant_new_bytestring ("a bytestring\xff"),
1266 : : g_variant_new ("(i)", 4200),
1267 : : #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64
1268 : : G_DBUS_CALL_FLAGS_NONE,
1269 : : -1,
1270 : : #endif
1271 : : &ret_i,
1272 : : &ret_s,
1273 : : &ret_ay,
1274 : : &ret_struct,
1275 : : NULL, /* GCancellable* */
1276 : : &error);
1277 : 3 : g_assert_no_error (error);
1278 : 3 : g_assert_cmpint (g_variant_get_int32 (ret_i), ==, 42 + 10);
1279 : 3 : g_assert_cmpstr (g_variant_get_string (ret_s, NULL), ==, "a string_foo");
1280 : 3 : g_assert_cmpstr (g_variant_get_bytestring (ret_ay), ==, "a bytestring\xff_foo\xff");
1281 : 3 : g_variant_get (ret_struct, "(i)", &val);
1282 : 3 : g_assert_cmpint (val, ==, 4200 + 10);
1283 : 3 : g_variant_unref (ret_i);
1284 : 3 : g_variant_unref (ret_s);
1285 : 3 : g_variant_unref (ret_ay);
1286 : 3 : g_variant_unref (ret_struct);
1287 : 3 : _g_assert_signal_received (proxy, "force-signal");
1288 : 3 : g_assert (force_signal_received);
1289 : 3 : }
1290 : :
1291 : : /* ---------------------------------------------------------------------------------------------------- */
1292 : :
1293 : : static void
1294 : 3 : check_authorize_proxy (FooiGenAuthorize *proxy,
1295 : : GMainLoop *thread_loop)
1296 : : {
1297 : : GError *error;
1298 : : gboolean ret;
1299 : :
1300 : : /* Check that g-authorize-method works as intended */
1301 : :
1302 : 3 : error = NULL;
1303 : : #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64
1304 : 1 : ret = foo_igen_authorize_call_check_not_authorized_sync (proxy, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1305 : : #else
1306 : 2 : ret = foo_igen_authorize_call_check_not_authorized_sync (proxy, NULL, &error);
1307 : : #endif
1308 : 3 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED);
1309 : 3 : g_error_free (error);
1310 : 3 : g_assert (!ret);
1311 : :
1312 : 3 : error = NULL;
1313 : : #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64
1314 : 1 : ret = foo_igen_authorize_call_check_authorized_sync (proxy, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1315 : : #else
1316 : 2 : ret = foo_igen_authorize_call_check_authorized_sync (proxy, NULL, &error);
1317 : : #endif
1318 : 3 : g_assert_no_error (error);
1319 : 3 : g_assert (ret);
1320 : :
1321 : 3 : error = NULL;
1322 : : #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64
1323 : 1 : ret = foo_igen_authorize_call_check_not_authorized_from_object_sync (proxy, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1324 : : #else
1325 : 2 : ret = foo_igen_authorize_call_check_not_authorized_from_object_sync (proxy, NULL, &error);
1326 : : #endif
1327 : 3 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PENDING);
1328 : 3 : g_error_free (error);
1329 : 3 : g_assert (!ret);
1330 : 3 : }
1331 : :
1332 : : /* ---------------------------------------------------------------------------------------------------- */
1333 : :
1334 : : static GThread *
1335 : 6 : get_self_via_proxy (FooiGenMethodThreads *proxy_1)
1336 : : {
1337 : : GError *error;
1338 : : gchar *self_str;
1339 : : gboolean ret;
1340 : : gpointer self;
1341 : :
1342 : 6 : error = NULL;
1343 : : #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64
1344 : 2 : ret = foo_igen_method_threads_call_get_self_sync (proxy_1, G_DBUS_CALL_FLAGS_NONE, -1, &self_str, NULL, &error);
1345 : : #else
1346 : 4 : ret = foo_igen_method_threads_call_get_self_sync (proxy_1, &self_str, NULL, &error);
1347 : : #endif
1348 : 6 : g_assert_no_error (error);
1349 : 6 : g_assert (ret);
1350 : :
1351 : 6 : g_assert_cmpint (sscanf (self_str, "%p", &self), ==, 1);
1352 : :
1353 : 6 : g_free (self_str);
1354 : :
1355 : 6 : return self;
1356 : : }
1357 : :
1358 : : static void
1359 : 3 : check_thread_proxies (FooiGenMethodThreads *proxy_1,
1360 : : FooiGenMethodThreads *proxy_2,
1361 : : GMainLoop *thread_loop)
1362 : : {
1363 : : /* proxy_1 is indeed using threads so should never get the handler thread */
1364 : 3 : g_assert (get_self_via_proxy (proxy_1) != method_handler_thread);
1365 : :
1366 : : /* proxy_2 is not using threads so should get the handler thread */
1367 : 3 : g_assert (get_self_via_proxy (proxy_2) == method_handler_thread);
1368 : 3 : }
1369 : :
1370 : : /* ---------------------------------------------------------------------------------------------------- */
1371 : :
1372 : : static gpointer
1373 : 3 : check_proxies_in_thread (gpointer user_data)
1374 : : {
1375 : 3 : GMainLoop *loop = user_data;
1376 : : GMainContext *thread_context;
1377 : : GMainLoop *thread_loop;
1378 : : GError *error;
1379 : : FooiGenBar *bar_proxy;
1380 : : FooiGenBat *bat_proxy;
1381 : : FooiGenTestFDPassing *fd_passing_proxy;
1382 : : FooiGenAuthorize *authorize_proxy;
1383 : : FooiGenMethodThreads *thread_proxy_1;
1384 : : FooiGenMethodThreads *thread_proxy_2;
1385 : :
1386 : 3 : thread_context = g_main_context_new ();
1387 : 3 : thread_loop = g_main_loop_new (thread_context, FALSE);
1388 : 3 : g_main_context_push_thread_default (thread_context);
1389 : :
1390 : : /* Check the object */
1391 : 3 : error = NULL;
1392 : 3 : bar_proxy = foo_igen_bar_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
1393 : : G_DBUS_PROXY_FLAGS_NONE,
1394 : : "org.gtk.GDBus.BindingsTool.Test",
1395 : : "/bar",
1396 : : NULL, /* GCancellable* */
1397 : : &error);
1398 : 3 : g_assert_no_error (error);
1399 : 3 : check_bar_proxy (bar_proxy, thread_loop);
1400 : 3 : g_object_unref (bar_proxy);
1401 : :
1402 : 3 : error = NULL;
1403 : 3 : bat_proxy = foo_igen_bat_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
1404 : : G_DBUS_PROXY_FLAGS_NONE,
1405 : : "org.gtk.GDBus.BindingsTool.Test",
1406 : : "/bat",
1407 : : NULL, /* GCancellable* */
1408 : : &error);
1409 : 3 : g_assert_no_error (error);
1410 : 3 : check_bat_proxy (bat_proxy, thread_loop);
1411 : 3 : g_object_unref (bat_proxy);
1412 : :
1413 : 3 : error = NULL;
1414 : 3 : authorize_proxy = foo_igen_authorize_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
1415 : : G_DBUS_PROXY_FLAGS_NONE,
1416 : : "org.gtk.GDBus.BindingsTool.Test",
1417 : : "/authorize",
1418 : : NULL, /* GCancellable* */
1419 : : &error);
1420 : 3 : g_assert_no_error (error);
1421 : 3 : check_authorize_proxy (authorize_proxy, thread_loop);
1422 : 3 : g_object_unref (authorize_proxy);
1423 : :
1424 : 3 : error = NULL;
1425 : 3 : thread_proxy_1 = foo_igen_method_threads_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
1426 : : G_DBUS_PROXY_FLAGS_NONE,
1427 : : "org.gtk.GDBus.BindingsTool.Test",
1428 : : "/method_threads_1",
1429 : : NULL, /* GCancellable* */
1430 : : &error);
1431 : 3 : g_assert_no_error (error);
1432 : 3 : thread_proxy_2 = foo_igen_method_threads_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
1433 : : G_DBUS_PROXY_FLAGS_NONE,
1434 : : "org.gtk.GDBus.BindingsTool.Test",
1435 : : "/method_threads_2",
1436 : : NULL, /* GCancellable* */
1437 : : &error);
1438 : 3 : g_assert_no_error (error);
1439 : 3 : check_thread_proxies (thread_proxy_1, thread_proxy_2, thread_loop);
1440 : 3 : g_object_unref (thread_proxy_1);
1441 : 3 : g_object_unref (thread_proxy_2);
1442 : :
1443 : 3 : fd_passing_proxy = foo_igen_test_fdpassing_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
1444 : : G_DBUS_PROXY_FLAGS_NONE,
1445 : : "org.gtk.GDBus.BindingsTool.Test",
1446 : : "/fdpassing",
1447 : : NULL, /* GCancellable* */
1448 : : &error);
1449 : 3 : g_assert_no_error (error);
1450 : 3 : check_fdpassing_proxy (fd_passing_proxy);
1451 : 3 : g_object_unref (fd_passing_proxy);
1452 : :
1453 : : /* Wait for the proxy signals to all be unsubscribed. */
1454 [ + + ]: 6 : while (g_main_context_iteration (thread_context, FALSE))
1455 : : {
1456 : : /* Nothing needs to be done here */
1457 : : }
1458 : :
1459 : 3 : g_main_loop_unref (thread_loop);
1460 : 3 : g_main_context_unref (thread_context);
1461 : :
1462 : : /* this breaks out of the loop in main() (below) */
1463 : 3 : g_main_loop_quit (loop);
1464 : 3 : return NULL;
1465 : : }
1466 : :
1467 : : /* ---------------------------------------------------------------------------------------------------- */
1468 : :
1469 : : typedef struct
1470 : : {
1471 : : gchar *xml;
1472 : : GMainLoop *loop;
1473 : : } IntrospectData;
1474 : :
1475 : : static void
1476 : 33 : introspect_cb (GDBusConnection *connection,
1477 : : GAsyncResult *res,
1478 : : gpointer user_data)
1479 : : {
1480 : 33 : IntrospectData *data = user_data;
1481 : : GVariant *result;
1482 : : GError *error;
1483 : :
1484 : 33 : error = NULL;
1485 : 33 : result = g_dbus_connection_call_finish (connection,
1486 : : res,
1487 : : &error);
1488 : 33 : g_assert_no_error (error);
1489 : 33 : g_assert (result != NULL);
1490 : 33 : g_variant_get (result, "(s)", &data->xml);
1491 : 33 : g_variant_unref (result);
1492 : :
1493 : 33 : g_main_loop_quit (data->loop);
1494 : 33 : }
1495 : :
1496 : : static GDBusNodeInfo *
1497 : 33 : introspect (GDBusConnection *connection,
1498 : : const gchar *name,
1499 : : const gchar *object_path,
1500 : : GMainLoop *loop)
1501 : : {
1502 : : GError *error;
1503 : : GDBusNodeInfo *node_info;
1504 : : IntrospectData *data;
1505 : :
1506 : 33 : data = g_new0 (IntrospectData, 1);
1507 : 33 : data->xml = NULL;
1508 : 33 : data->loop = loop;
1509 : :
1510 : : /* do this async to avoid deadlocks */
1511 : 33 : g_dbus_connection_call (connection,
1512 : : name,
1513 : : object_path,
1514 : : "org.freedesktop.DBus.Introspectable",
1515 : : "Introspect",
1516 : : NULL, /* params */
1517 : : G_VARIANT_TYPE ("(s)"),
1518 : : G_DBUS_CALL_FLAGS_NONE,
1519 : : -1,
1520 : : NULL,
1521 : : (GAsyncReadyCallback) introspect_cb,
1522 : : data);
1523 : 33 : g_main_loop_run (loop);
1524 : 33 : g_assert (data->xml != NULL);
1525 : :
1526 : 33 : error = NULL;
1527 : 33 : node_info = g_dbus_node_info_new_for_xml (data->xml, &error);
1528 : 33 : g_assert_no_error (error);
1529 : 33 : g_assert (node_info != NULL);
1530 : 33 : g_free (data->xml);
1531 : 33 : g_free (data);
1532 : :
1533 : 33 : return node_info;
1534 : : }
1535 : :
1536 : : static guint
1537 : 33 : count_interfaces (GDBusNodeInfo *info)
1538 : : {
1539 : : guint n;
1540 [ + - + + ]: 132 : for (n = 0; info->interfaces != NULL && info->interfaces[n] != NULL; n++)
1541 : : ;
1542 : 33 : return n;
1543 : : }
1544 : :
1545 : : static guint
1546 : 6 : count_nodes (GDBusNodeInfo *info)
1547 : : {
1548 : : guint n;
1549 [ + - - + ]: 6 : for (n = 0; info->nodes != NULL && info->nodes[n] != NULL; n++)
1550 : : ;
1551 : 6 : return n;
1552 : : }
1553 : :
1554 : : static guint
1555 : 27 : has_interface (GDBusNodeInfo *info,
1556 : : const gchar *name)
1557 : : {
1558 : : guint n;
1559 [ + - + - ]: 111 : for (n = 0; info->interfaces != NULL && info->interfaces[n] != NULL; n++)
1560 : : {
1561 [ + + ]: 111 : if (g_strcmp0 (info->interfaces[n]->name, name) == 0)
1562 : 27 : return TRUE;
1563 : : }
1564 : 0 : return FALSE;
1565 : : }
1566 : :
1567 : : /* ---------------------------------------------------------------------------------------------------- */
1568 : :
1569 : : typedef struct {
1570 : : GMainLoop *loop;
1571 : : GVariant *result;
1572 : : } OMGetManagedObjectsData;
1573 : :
1574 : : static void
1575 : 18 : om_get_all_cb (GDBusConnection *connection,
1576 : : GAsyncResult *res,
1577 : : gpointer user_data)
1578 : : {
1579 : 18 : OMGetManagedObjectsData *data = user_data;
1580 : : GError *error;
1581 : :
1582 : 18 : error = NULL;
1583 : 18 : data->result = g_dbus_connection_call_finish (connection,
1584 : : res,
1585 : : &error);
1586 : 18 : g_assert_no_error (error);
1587 : 18 : g_assert (data->result != NULL);
1588 : 18 : g_main_loop_quit (data->loop);
1589 : 18 : }
1590 : :
1591 : : static void
1592 : 18 : om_check_get_all (GDBusConnection *c,
1593 : : GMainLoop *loop,
1594 : : const gchar *str)
1595 : : {
1596 : : OMGetManagedObjectsData data;
1597 : : gchar *s;
1598 : :
1599 : 18 : data.loop = loop;
1600 : 18 : data.result = NULL;
1601 : :
1602 : : /* do this async to avoid deadlocks */
1603 : 18 : g_dbus_connection_call (c,
1604 : : g_dbus_connection_get_unique_name (c),
1605 : : "/managed",
1606 : : "org.freedesktop.DBus.ObjectManager",
1607 : : "GetManagedObjects",
1608 : : NULL, /* params */
1609 : : G_VARIANT_TYPE ("(a{oa{sa{sv}}})"),
1610 : : G_DBUS_CALL_FLAGS_NONE,
1611 : : -1,
1612 : : NULL,
1613 : : (GAsyncReadyCallback) om_get_all_cb,
1614 : : &data);
1615 : 18 : g_main_loop_run (loop);
1616 : 18 : g_assert (data.result != NULL);
1617 : 18 : s = g_variant_print (data.result, TRUE);
1618 : 18 : g_assert_cmpstr (s, ==, str);
1619 : 18 : g_free (s);
1620 : 18 : g_variant_unref (data.result);
1621 : 18 : }
1622 : :
1623 : : typedef struct
1624 : : {
1625 : : GMainLoop *loop;
1626 : : guint state;
1627 : :
1628 : : guint num_object_proxy_added_signals;
1629 : : guint num_object_proxy_removed_signals;
1630 : : guint num_interface_added_signals;
1631 : : guint num_interface_removed_signals;
1632 : : } OMData;
1633 : :
1634 : : static void
1635 : 21 : om_check_interfaces_added (const gchar *signal_name,
1636 : : GVariant *parameters,
1637 : : const gchar *object_path,
1638 : : const gchar *first_interface_name,
1639 : : ...)
1640 : : {
1641 : : const gchar *path;
1642 : : GVariant *array;
1643 : : guint n;
1644 : : GPtrArray *interfaces;
1645 : : GPtrArray *interfaces_in_message;
1646 : : va_list var_args;
1647 : : const gchar *str;
1648 : :
1649 : 21 : interfaces = g_ptr_array_new ();
1650 : 21 : g_ptr_array_add (interfaces, (gpointer) first_interface_name);
1651 : 21 : va_start (var_args, first_interface_name);
1652 : : do
1653 : : {
1654 : 24 : str = va_arg (var_args, const gchar *);
1655 [ + + ]: 24 : if (str == NULL)
1656 : 21 : break;
1657 : 3 : g_ptr_array_add (interfaces, (gpointer) str);
1658 : : }
1659 : : while (TRUE);
1660 : 21 : va_end (var_args);
1661 : :
1662 : 21 : g_variant_get (parameters, "(&o*)", &path, &array);
1663 : 21 : g_assert_cmpstr (signal_name, ==, "InterfacesAdded");
1664 : 21 : g_assert_cmpstr (path, ==, object_path);
1665 : 21 : g_assert_cmpint (g_variant_n_children (array), ==, interfaces->len);
1666 : 21 : interfaces_in_message = g_ptr_array_new ();
1667 [ + + ]: 45 : for (n = 0; n < interfaces->len; n++)
1668 : : {
1669 : : const gchar *iface_name;
1670 : 24 : g_variant_get_child (array, n, "{&sa{sv}}", &iface_name, NULL);
1671 : 24 : g_ptr_array_add (interfaces_in_message, (gpointer) iface_name);
1672 : : }
1673 : 21 : g_assert_cmpint (interfaces_in_message->len, ==, interfaces->len);
1674 : : G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1675 : 21 : g_ptr_array_sort_values (interfaces, (GCompareFunc) g_strcmp0);
1676 : 21 : g_ptr_array_sort_values (interfaces_in_message, (GCompareFunc) g_strcmp0);
1677 : : G_GNUC_END_IGNORE_DEPRECATIONS
1678 [ + + ]: 45 : for (n = 0; n < interfaces->len; n++)
1679 : 24 : g_assert_cmpstr (interfaces->pdata[n], ==, interfaces_in_message->pdata[n]);
1680 : 21 : g_ptr_array_unref (interfaces_in_message);
1681 : 21 : g_ptr_array_unref (interfaces);
1682 : 21 : g_variant_unref (array);
1683 : 21 : }
1684 : :
1685 : : static void
1686 : 15 : om_check_interfaces_removed (const gchar *signal_name,
1687 : : GVariant *parameters,
1688 : : const gchar *object_path,
1689 : : const gchar *first_interface_name,
1690 : : ...)
1691 : : {
1692 : : const gchar *path;
1693 : : GVariant *array;
1694 : : guint n;
1695 : : GPtrArray *interfaces;
1696 : : GPtrArray *interfaces_in_message;
1697 : : va_list var_args;
1698 : : const gchar *str;
1699 : :
1700 : 15 : interfaces = g_ptr_array_new ();
1701 : 15 : g_ptr_array_add (interfaces, (gpointer) first_interface_name);
1702 : 15 : va_start (var_args, first_interface_name);
1703 : : do
1704 : : {
1705 : 18 : str = va_arg (var_args, const gchar *);
1706 [ + + ]: 18 : if (str == NULL)
1707 : 15 : break;
1708 : 3 : g_ptr_array_add (interfaces, (gpointer) str);
1709 : : }
1710 : : while (TRUE);
1711 : 15 : va_end (var_args);
1712 : :
1713 : 15 : g_variant_get (parameters, "(&o*)", &path, &array);
1714 : 15 : g_assert_cmpstr (signal_name, ==, "InterfacesRemoved");
1715 : 15 : g_assert_cmpstr (path, ==, object_path);
1716 : 15 : g_assert_cmpint (g_variant_n_children (array), ==, interfaces->len);
1717 : 15 : interfaces_in_message = g_ptr_array_new ();
1718 [ + + ]: 33 : for (n = 0; n < interfaces->len; n++)
1719 : : {
1720 : : const gchar *iface_name;
1721 : 18 : g_variant_get_child (array, n, "&s", &iface_name, NULL);
1722 : 18 : g_ptr_array_add (interfaces_in_message, (gpointer) iface_name);
1723 : : }
1724 : 15 : g_assert_cmpint (interfaces_in_message->len, ==, interfaces->len);
1725 : : G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1726 : 15 : g_ptr_array_sort_values (interfaces, (GCompareFunc) g_strcmp0);
1727 : 15 : g_ptr_array_sort_values (interfaces_in_message, (GCompareFunc) g_strcmp0);
1728 : : G_GNUC_END_IGNORE_DEPRECATIONS
1729 [ + + ]: 33 : for (n = 0; n < interfaces->len; n++)
1730 : 18 : g_assert_cmpstr (interfaces->pdata[n], ==, interfaces_in_message->pdata[n]);
1731 : 15 : g_ptr_array_unref (interfaces_in_message);
1732 : 15 : g_ptr_array_unref (interfaces);
1733 : 15 : g_variant_unref (array);
1734 : 15 : }
1735 : :
1736 : : static void
1737 : 36 : om_on_signal (GDBusConnection *connection,
1738 : : const gchar *sender_name,
1739 : : const gchar *object_path,
1740 : : const gchar *interface_name,
1741 : : const gchar *signal_name,
1742 : : GVariant *parameters,
1743 : : gpointer user_data)
1744 : : {
1745 : 36 : OMData *om_data = user_data;
1746 : :
1747 : : //g_debug ("foo: %s", g_variant_print (parameters, TRUE));
1748 : :
1749 [ - + + + : 36 : switch (om_data->state)
+ + + + +
+ + + + ]
1750 : : {
1751 : 0 : default:
1752 : : case 0:
1753 : 0 : g_printerr ("failing and om_data->state=%d on signal %s, params=%s\n",
1754 : : om_data->state,
1755 : : signal_name,
1756 : : g_variant_print (parameters, TRUE));
1757 : : g_assert_not_reached ();
1758 : : break;
1759 : :
1760 : 3 : case 1:
1761 : 3 : om_check_interfaces_added (signal_name, parameters, "/managed/first",
1762 : : "org.project.Bar", NULL);
1763 : 3 : om_data->state = 2;
1764 : 3 : g_main_loop_quit (om_data->loop);
1765 : 3 : break;
1766 : :
1767 : 3 : case 3:
1768 : 3 : om_check_interfaces_removed (signal_name, parameters, "/managed/first",
1769 : : "org.project.Bar", NULL);
1770 : 3 : om_data->state = 5;
1771 : : /* keep running the loop */
1772 : 3 : break;
1773 : :
1774 : 3 : case 5:
1775 : 3 : om_check_interfaces_added (signal_name, parameters, "/managed/first",
1776 : : "org.project.Bar", NULL);
1777 : 3 : om_data->state = 6;
1778 : 3 : g_main_loop_quit (om_data->loop);
1779 : 3 : break;
1780 : :
1781 : 3 : case 7:
1782 : 3 : om_check_interfaces_removed (signal_name, parameters, "/managed/first",
1783 : : "org.project.Bar", NULL);
1784 : 3 : om_data->state = 9;
1785 : : /* keep running the loop */
1786 : 3 : break;
1787 : :
1788 : 3 : case 9:
1789 : 3 : om_check_interfaces_added (signal_name, parameters, "/managed/first",
1790 : : "org.project.Bar", NULL);
1791 : 3 : om_data->state = 10;
1792 : 3 : g_main_loop_quit (om_data->loop);
1793 : 3 : break;
1794 : :
1795 : 3 : case 11:
1796 : 3 : om_check_interfaces_added (signal_name, parameters, "/managed/first",
1797 : : "org.project.Bat", NULL);
1798 : 3 : om_data->state = 12;
1799 : 3 : g_main_loop_quit (om_data->loop);
1800 : 3 : break;
1801 : :
1802 : 3 : case 13:
1803 : 3 : om_check_interfaces_removed (signal_name, parameters, "/managed/first",
1804 : : "org.project.Bar", NULL);
1805 : 3 : om_data->state = 14;
1806 : 3 : g_main_loop_quit (om_data->loop);
1807 : 3 : break;
1808 : :
1809 : 3 : case 15:
1810 : 3 : om_check_interfaces_removed (signal_name, parameters, "/managed/first",
1811 : : "org.project.Bat", NULL);
1812 : 3 : om_data->state = 16;
1813 : 3 : g_main_loop_quit (om_data->loop);
1814 : 3 : break;
1815 : :
1816 : 3 : case 17:
1817 : 3 : om_check_interfaces_added (signal_name, parameters, "/managed/first",
1818 : : "com.acme.Coyote", NULL);
1819 : 3 : om_data->state = 18;
1820 : 3 : g_main_loop_quit (om_data->loop);
1821 : 3 : break;
1822 : :
1823 : 3 : case 101:
1824 : 3 : om_check_interfaces_added (signal_name, parameters, "/managed/second",
1825 : : "org.project.Bat", "org.project.Bar", NULL);
1826 : 3 : om_data->state = 102;
1827 : 3 : g_main_loop_quit (om_data->loop);
1828 : 3 : break;
1829 : :
1830 : 3 : case 103:
1831 : 3 : om_check_interfaces_removed (signal_name, parameters, "/managed/second",
1832 : : "org.project.Bat", "org.project.Bar", NULL);
1833 : 3 : om_data->state = 104;
1834 : 3 : g_main_loop_quit (om_data->loop);
1835 : 3 : break;
1836 : :
1837 : 3 : case 200:
1838 : 3 : om_check_interfaces_added (signal_name, parameters, "/managed/first_1",
1839 : : "com.acme.Coyote", NULL);
1840 : 3 : om_data->state = 201;
1841 : 3 : g_main_loop_quit (om_data->loop);
1842 : 3 : break;
1843 : : }
1844 : 36 : }
1845 : :
1846 : : static GAsyncResult *om_res = NULL;
1847 : :
1848 : : static void
1849 : 3 : om_pm_start_cb (FooiGenObjectManagerClient *manager,
1850 : : GAsyncResult *res,
1851 : : gpointer user_data)
1852 : : {
1853 : 3 : GMainLoop *loop = user_data;
1854 : 3 : om_res = g_object_ref (res);
1855 : 3 : g_main_loop_quit (loop);
1856 : 3 : }
1857 : :
1858 : : static void
1859 : 3 : on_interface_added (GDBusObject *object,
1860 : : GDBusInterface *interface,
1861 : : gpointer user_data)
1862 : : {
1863 : 3 : OMData *om_data = user_data;
1864 : 3 : om_data->num_interface_added_signals += 1;
1865 : 3 : }
1866 : :
1867 : : static void
1868 : 3 : on_interface_removed (GDBusObject *object,
1869 : : GDBusInterface *interface,
1870 : : gpointer user_data)
1871 : : {
1872 : 3 : OMData *om_data = user_data;
1873 : 3 : om_data->num_interface_removed_signals += 1;
1874 : 3 : }
1875 : :
1876 : : static void
1877 : 18 : on_object_proxy_added (GDBusObjectManagerClient *manager,
1878 : : GDBusObjectProxy *object_proxy,
1879 : : gpointer user_data)
1880 : : {
1881 : 18 : OMData *om_data = user_data;
1882 : 18 : om_data->num_object_proxy_added_signals += 1;
1883 : 18 : g_signal_connect (object_proxy,
1884 : : "interface-added",
1885 : : G_CALLBACK (on_interface_added),
1886 : : om_data);
1887 : 18 : g_signal_connect (object_proxy,
1888 : : "interface-removed",
1889 : : G_CALLBACK (on_interface_removed),
1890 : : om_data);
1891 : 18 : }
1892 : :
1893 : : static void
1894 : 12 : on_object_proxy_removed (GDBusObjectManagerClient *manager,
1895 : : GDBusObjectProxy *object_proxy,
1896 : : gpointer user_data)
1897 : : {
1898 : 12 : OMData *om_data = user_data;
1899 : 12 : om_data->num_object_proxy_removed_signals += 1;
1900 : 12 : g_assert_cmpint (g_signal_handlers_disconnect_by_func (object_proxy,
1901 : : G_CALLBACK (on_interface_added),
1902 : : om_data), ==, 1);
1903 : 12 : g_assert_cmpint (g_signal_handlers_disconnect_by_func (object_proxy,
1904 : : G_CALLBACK (on_interface_removed),
1905 : : om_data), ==, 1);
1906 : 12 : }
1907 : :
1908 : : static void
1909 : 0 : property_changed (GObject *object,
1910 : : GParamSpec *pspec,
1911 : : gpointer user_data)
1912 : : {
1913 : 0 : gboolean *changed = user_data;
1914 : :
1915 : 0 : *changed = TRUE;
1916 : 0 : }
1917 : :
1918 : : static void
1919 : 3 : om_check_property_and_signal_emission (GMainLoop *loop,
1920 : : FooiGenBar *skeleton,
1921 : : FooiGenBar *proxy)
1922 : : {
1923 : 3 : gboolean d_changed = FALSE;
1924 : 3 : gboolean quiet_changed = FALSE;
1925 : 3 : gboolean quiet_too_changed = FALSE;
1926 : : guint handler;
1927 : :
1928 : : /* First PropertiesChanged */
1929 : 3 : g_assert_cmpint (foo_igen_bar_get_i (skeleton), ==, 0);
1930 : 3 : g_assert_cmpint (foo_igen_bar_get_i (proxy), ==, 0);
1931 : 3 : foo_igen_bar_set_i (skeleton, 1);
1932 : 3 : _g_assert_property_notify (proxy, "i");
1933 : 3 : g_assert_cmpint (foo_igen_bar_get_i (skeleton), ==, 1);
1934 : 3 : g_assert_cmpint (foo_igen_bar_get_i (proxy), ==, 1);
1935 : :
1936 : : /* Double-check the gdouble case */
1937 : 3 : g_assert_cmpfloat (foo_igen_bar_get_d (skeleton), ==, 0.0);
1938 : 3 : g_assert_cmpfloat (foo_igen_bar_get_d (proxy), ==, 0.0);
1939 : 3 : foo_igen_bar_set_d (skeleton, 1.0);
1940 : 3 : _g_assert_property_notify (proxy, "d");
1941 : :
1942 : : /* Verify that re-setting it to the same value doesn't cause a
1943 : : * notify on the proxy, by taking advantage of the fact that
1944 : : * notifications are serialized.
1945 : : */
1946 : 3 : handler = g_signal_connect (proxy, "notify::d",
1947 : : G_CALLBACK (property_changed), &d_changed);
1948 : 3 : foo_igen_bar_set_d (skeleton, 1.0);
1949 : 3 : foo_igen_bar_set_i (skeleton, 2);
1950 : 3 : _g_assert_property_notify (proxy, "i");
1951 : 3 : g_assert (d_changed == FALSE);
1952 : 3 : g_signal_handler_disconnect (proxy, handler);
1953 : :
1954 : : /* Verify that re-setting a property with the "EmitsChangedSignal"
1955 : : * set to false doesn't emit a signal. */
1956 : 3 : handler = g_signal_connect (proxy, "notify::quiet",
1957 : : G_CALLBACK (property_changed), &quiet_changed);
1958 : 3 : foo_igen_bar_set_quiet (skeleton, "hush!");
1959 : 3 : foo_igen_bar_set_i (skeleton, 3);
1960 : 3 : _g_assert_property_notify (proxy, "i");
1961 : 3 : g_assert (quiet_changed == FALSE);
1962 : 3 : g_assert_cmpstr (foo_igen_bar_get_quiet (skeleton), ==, "hush!");
1963 : 3 : g_signal_handler_disconnect (proxy, handler);
1964 : :
1965 : : /* Also verify that re-setting a property with the "EmitsChangedSignal"
1966 : : * set to 'const' doesn't emit a signal. */
1967 : 3 : handler = g_signal_connect (proxy, "notify::quiet-too",
1968 : : G_CALLBACK (property_changed), &quiet_changed);
1969 : 3 : foo_igen_bar_set_quiet_too (skeleton, "hush too!");
1970 : 3 : foo_igen_bar_set_i (skeleton, 4);
1971 : 3 : _g_assert_property_notify (proxy, "i");
1972 : 3 : g_assert (quiet_too_changed == FALSE);
1973 : 3 : g_assert_cmpstr (foo_igen_bar_get_quiet_too (skeleton), ==, "hush too!");
1974 : 3 : g_signal_handler_disconnect (proxy, handler);
1975 : :
1976 : : /* Then just a regular signal */
1977 : 3 : foo_igen_bar_emit_another_signal (skeleton, "word");
1978 : 3 : _g_assert_signal_received (proxy, "another-signal");
1979 : 3 : }
1980 : :
1981 : : static void
1982 : 3 : check_object_manager (void)
1983 : : {
1984 : 3 : FooiGenObjectSkeleton *o = NULL;
1985 : 3 : FooiGenObjectSkeleton *o2 = NULL;
1986 : 3 : FooiGenObjectSkeleton *o3 = NULL;
1987 : : GDBusInterfaceSkeleton *i;
1988 : : GDBusConnection *c;
1989 : 3 : GDBusObjectManagerServer *manager = NULL;
1990 : : GDBusNodeInfo *info;
1991 : : GError *error;
1992 : : GMainLoop *loop;
1993 : 3 : OMData *om_data = NULL;
1994 : 3 : guint om_signal_id = 0;
1995 : 3 : GDBusObjectManager *pm = NULL;
1996 : : GList *object_proxies;
1997 : : GList *proxies;
1998 : : GDBusObject *op;
1999 : : GDBusProxy *p;
2000 : : FooiGenBar *bar_skeleton;
2001 : : GDBusInterface *iface;
2002 : : gchar *path, *name, *name_owner;
2003 : : GDBusConnection *c2;
2004 : : GDBusObjectManagerClientFlags flags;
2005 : :
2006 : 3 : loop = g_main_loop_new (NULL, FALSE);
2007 : :
2008 : 3 : om_data = g_new0 (OMData, 1);
2009 : 3 : om_data->loop = loop;
2010 : 3 : om_data->state = 0;
2011 : :
2012 : 3 : error = NULL;
2013 : 3 : c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
2014 : 3 : g_assert_no_error (error);
2015 : 3 : g_assert (c != NULL);
2016 : :
2017 : 3 : om_signal_id = g_dbus_connection_signal_subscribe (c,
2018 : : NULL, /* sender */
2019 : : "org.freedesktop.DBus.ObjectManager",
2020 : : NULL, /* member */
2021 : : NULL, /* object_path */
2022 : : NULL, /* arg0 */
2023 : : G_DBUS_SIGNAL_FLAGS_NONE,
2024 : : om_on_signal,
2025 : : om_data,
2026 : : NULL); /* user_data_free_func */
2027 : :
2028 : : /* Our GDBusObjectManagerClient tests are simple - we basically just count the
2029 : : * number of times the various signals have been emitted (we don't check
2030 : : * that the right objects/interfaces are passed though - that's checked
2031 : : * in the lower-level tests in om_on_signal()...)
2032 : : *
2033 : : * Note that these tests rely on the D-Bus signal handlers used by
2034 : : * GDBusObjectManagerClient firing before om_on_signal().
2035 : : */
2036 : 3 : error = NULL;
2037 : 3 : pm = foo_igen_object_manager_client_new_sync (c,
2038 : : G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
2039 : : g_dbus_connection_get_unique_name (c),
2040 : : "/managed",
2041 : : NULL, /* GCancellable */
2042 : : &error);
2043 : 3 : g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD);
2044 : 3 : g_error_free (error);
2045 : 3 : g_assert (pm == NULL);
2046 : :
2047 : 3 : manager = g_dbus_object_manager_server_new ("/managed");
2048 : :
2049 : 3 : g_assert (g_dbus_object_manager_server_get_connection (manager) == NULL);
2050 : :
2051 : 3 : g_dbus_object_manager_server_set_connection (manager, c);
2052 : :
2053 : 3 : g_assert_cmpstr (g_dbus_object_manager_get_object_path (G_DBUS_OBJECT_MANAGER (manager)), ==, "/managed");
2054 : 3 : g_object_get (manager, "object-path", &path, "connection", &c2, NULL);
2055 : 3 : g_assert_cmpstr (path, ==, "/managed");
2056 : 3 : g_assert (c2 == c);
2057 : 3 : g_free (path);
2058 : 3 : g_clear_object (&c2);
2059 : :
2060 : : /* Check that the manager object is visible */
2061 : 3 : info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed", loop);
2062 : 3 : g_assert_cmpint (count_interfaces (info), ==, 4); /* ObjectManager + Properties,Introspectable,Peer */
2063 : 3 : g_assert (has_interface (info, "org.freedesktop.DBus.ObjectManager"));
2064 : 3 : g_assert_cmpint (count_nodes (info), ==, 0);
2065 : 3 : g_dbus_node_info_unref (info);
2066 : :
2067 : : /* Check GetManagedObjects() - should be empty since we have no objects */
2068 : 3 : om_check_get_all (c, loop,
2069 : : "(@a{oa{sa{sv}}} {},)");
2070 : :
2071 : : /* Now try to create the proxy manager again - this time it should work */
2072 : 3 : error = NULL;
2073 : 3 : foo_igen_object_manager_client_new (c,
2074 : : G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
2075 : : g_dbus_connection_get_unique_name (c),
2076 : : "/managed",
2077 : : NULL, /* GCancellable */
2078 : : (GAsyncReadyCallback) om_pm_start_cb,
2079 : : loop);
2080 : 3 : g_main_loop_run (loop);
2081 : 3 : error = NULL;
2082 : 3 : pm = foo_igen_object_manager_client_new_finish (om_res, &error);
2083 : 3 : g_clear_object (&om_res);
2084 : 3 : g_assert_no_error (error);
2085 : 3 : g_assert (pm != NULL);
2086 : 3 : g_signal_connect (pm,
2087 : : "object-added",
2088 : : G_CALLBACK (on_object_proxy_added),
2089 : : om_data);
2090 : 3 : g_signal_connect (pm,
2091 : : "object-removed",
2092 : : G_CALLBACK (on_object_proxy_removed),
2093 : : om_data);
2094 : :
2095 : 3 : g_assert_cmpstr (g_dbus_object_manager_get_object_path (G_DBUS_OBJECT_MANAGER (pm)), ==, "/managed");
2096 : 3 : g_object_get (pm,
2097 : : "object-path", &path,
2098 : : "connection", &c2,
2099 : : "name", &name,
2100 : : "name-owner", &name_owner,
2101 : : "flags", &flags,
2102 : : NULL);
2103 : 3 : g_assert_cmpstr (path, ==, "/managed");
2104 : 3 : g_assert_cmpstr (name, ==, g_dbus_connection_get_unique_name (c));
2105 : 3 : g_assert_cmpstr (name_owner, ==, g_dbus_connection_get_unique_name (c));
2106 : 3 : g_assert_cmpint (flags, ==, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE);
2107 : 3 : g_assert (c2 == c);
2108 : 3 : g_free (path);
2109 : 3 : g_clear_object (&c2);
2110 : 3 : g_free (name);
2111 : 3 : g_free (name_owner);
2112 : :
2113 : : /* ... check there are no object proxies yet */
2114 : 3 : object_proxies = g_dbus_object_manager_get_objects (pm);
2115 : 3 : g_assert (object_proxies == NULL);
2116 : :
2117 : : /* First, export an object with a single interface (also check that
2118 : : * g_dbus_interface_get_object() works and that the object isn't reffed)
2119 : : */
2120 : 3 : o = foo_igen_object_skeleton_new ("/managed/first");
2121 : 3 : i = G_DBUS_INTERFACE_SKELETON (foo_igen_bar_skeleton_new ());
2122 : 3 : g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == NULL);
2123 : 3 : g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1);
2124 : 3 : foo_igen_object_skeleton_set_bar (o, FOO_IGEN_BAR (i));
2125 : 3 : g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1);
2126 : 3 : g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == G_DBUS_OBJECT (o));
2127 : 3 : g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1);
2128 : 3 : foo_igen_object_skeleton_set_bar (o, NULL);
2129 : 3 : g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == NULL);
2130 : 3 : g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1);
2131 : 3 : foo_igen_object_skeleton_set_bar (o, FOO_IGEN_BAR (i));
2132 : 3 : g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == G_DBUS_OBJECT (o));
2133 : 3 : g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1);
2134 : :
2135 : 3 : o2 = FOO_IGEN_OBJECT_SKELETON (g_dbus_interface_dup_object (G_DBUS_INTERFACE (i)));
2136 : 3 : g_assert (G_DBUS_OBJECT (o2) == G_DBUS_OBJECT (o));
2137 : 3 : g_assert_cmpint (G_OBJECT (o2)->ref_count, ==, 2);
2138 : 3 : g_clear_object (&o2);
2139 : :
2140 : 3 : g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (o));
2141 : :
2142 : : /* ... check we get the InterfacesAdded signal */
2143 : 3 : om_data->state = 1;
2144 : :
2145 : 3 : g_main_loop_run (om_data->loop);
2146 : :
2147 : 3 : g_assert_cmpint (om_data->state, ==, 2);
2148 : 3 : g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 1);
2149 : 3 : g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 0);
2150 : 3 : g_assert_cmpint (om_data->num_interface_added_signals, ==, 0);
2151 : 3 : g_assert_cmpint (om_data->num_interface_removed_signals, ==, 0);
2152 : : /* ... check there's one non-standard interfaces */
2153 : 3 : info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop);
2154 : 3 : g_assert_cmpint (count_interfaces (info), ==, 4); /* Bar + Properties,Introspectable,Peer */
2155 : 3 : g_assert (has_interface (info, "org.project.Bar"));
2156 : 3 : g_dbus_node_info_unref (info);
2157 : :
2158 : : /* Also check g_dbus_object_manager_get_interface */
2159 : 3 : iface = g_dbus_object_manager_get_interface (G_DBUS_OBJECT_MANAGER (manager), "/managed/first", "org.project.Bar");
2160 : 3 : g_assert (iface != NULL);
2161 : 3 : g_clear_object (&iface);
2162 : 3 : iface = g_dbus_object_manager_get_interface (G_DBUS_OBJECT_MANAGER (manager), "/managed/first", "org.project.Bat");
2163 : 3 : g_assert (iface == NULL);
2164 : 3 : iface = g_dbus_object_manager_get_interface (G_DBUS_OBJECT_MANAGER (pm), "/managed/first", "org.project.Bar");
2165 : 3 : g_assert (iface != NULL);
2166 : 3 : g_clear_object (&iface);
2167 : 3 : iface = g_dbus_object_manager_get_interface (G_DBUS_OBJECT_MANAGER (pm), "/managed/first", "org.project.Bat");
2168 : 3 : g_assert (iface == NULL);
2169 : :
2170 : : /* Now, check adding the same interface replaces the existing one */
2171 : 3 : foo_igen_object_skeleton_set_bar (o, FOO_IGEN_BAR (i));
2172 : : /* ... check we get the InterfacesRemoved */
2173 : 3 : om_data->state = 3;
2174 : 3 : g_main_loop_run (om_data->loop);
2175 : : /* ... and then check we get the InterfacesAdded */
2176 : 3 : g_assert_cmpint (om_data->state, ==, 6);
2177 : 3 : g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 2);
2178 : 3 : g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 1);
2179 : 3 : g_assert_cmpint (om_data->num_interface_added_signals, ==, 0);
2180 : 3 : g_assert_cmpint (om_data->num_interface_removed_signals, ==, 0);
2181 : : /* ... check introspection data */
2182 : 3 : info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop);
2183 : 3 : g_assert_cmpint (count_interfaces (info), ==, 4); /* Bar + Properties,Introspectable,Peer */
2184 : 3 : g_assert (has_interface (info, "org.project.Bar"));
2185 : 3 : g_dbus_node_info_unref (info);
2186 : 3 : g_clear_object (&i);
2187 : :
2188 : : /* check adding an interface of same type (but not same object) replaces the existing one */
2189 : 3 : i = G_DBUS_INTERFACE_SKELETON (foo_igen_bar_skeleton_new ());
2190 : 3 : foo_igen_object_skeleton_set_bar (o, FOO_IGEN_BAR (i));
2191 : : /* ... check we get the InterfacesRemoved and then InterfacesAdded */
2192 : 3 : om_data->state = 7;
2193 : 3 : g_main_loop_run (om_data->loop);
2194 : 3 : g_assert_cmpint (om_data->state, ==, 10);
2195 : 3 : g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 3);
2196 : 3 : g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 2);
2197 : 3 : g_assert_cmpint (om_data->num_interface_added_signals, ==, 0);
2198 : 3 : g_assert_cmpint (om_data->num_interface_removed_signals, ==, 0);
2199 : : /* ... check introspection data */
2200 : 3 : info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop);
2201 : 3 : g_assert_cmpint (count_interfaces (info), ==, 4); /* Bar + Properties,Introspectable,Peer */
2202 : 3 : g_assert (has_interface (info, "org.project.Bar"));
2203 : 3 : g_dbus_node_info_unref (info);
2204 : 3 : g_clear_object (&i);
2205 : :
2206 : : /* check adding an interface of another type doesn't replace the existing one */
2207 : 3 : i = G_DBUS_INTERFACE_SKELETON (foo_igen_bat_skeleton_new ());
2208 : 3 : foo_igen_object_skeleton_set_bat (o, FOO_IGEN_BAT (i));
2209 : 3 : g_clear_object (&i);
2210 : : /* ... check we get the InterfacesAdded */
2211 : 3 : om_data->state = 11;
2212 : 3 : g_main_loop_run (om_data->loop);
2213 : 3 : g_assert_cmpint (om_data->state, ==, 12);
2214 : 3 : g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 3);
2215 : 3 : g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 2);
2216 : 3 : g_assert_cmpint (om_data->num_interface_added_signals, ==, 1);
2217 : 3 : g_assert_cmpint (om_data->num_interface_removed_signals, ==, 0);
2218 : : /* ... check introspection data */
2219 : 3 : info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop);
2220 : 3 : g_assert_cmpint (count_interfaces (info), ==, 5); /* Bar,Bat + Properties,Introspectable,Peer */
2221 : 3 : g_assert (has_interface (info, "org.project.Bar"));
2222 : 3 : g_assert (has_interface (info, "org.project.Bat"));
2223 : 3 : g_dbus_node_info_unref (info);
2224 : :
2225 : : /* check we can remove an interface */
2226 : 3 : foo_igen_object_skeleton_set_bar (o, NULL);
2227 : : /* ... check we get the InterfacesRemoved */
2228 : 3 : om_data->state = 13;
2229 : 3 : g_main_loop_run (om_data->loop);
2230 : 3 : g_assert_cmpint (om_data->state, ==, 14);
2231 : 3 : g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 3);
2232 : 3 : g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 2);
2233 : 3 : g_assert_cmpint (om_data->num_interface_added_signals, ==, 1);
2234 : 3 : g_assert_cmpint (om_data->num_interface_removed_signals, ==, 1);
2235 : : /* ... check introspection data */
2236 : 3 : info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop);
2237 : 3 : g_assert_cmpint (count_interfaces (info), ==, 4); /* Bat + Properties,Introspectable,Peer */
2238 : 3 : g_assert (has_interface (info, "org.project.Bat"));
2239 : 3 : g_dbus_node_info_unref (info);
2240 : : /* also and that the call only has effect if the interface actually exists
2241 : : *
2242 : : * (Note: if a signal was emitted we'd assert in the signal handler
2243 : : * because we're in state 14)
2244 : : */
2245 : 3 : foo_igen_object_skeleton_set_bar (o, NULL);
2246 : : /* ... check introspection data */
2247 : 3 : info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop);
2248 : 3 : g_assert_cmpint (count_interfaces (info), ==, 4); /* Bat + Properties,Introspectable,Peer */
2249 : 3 : g_assert (has_interface (info, "org.project.Bat"));
2250 : 3 : g_dbus_node_info_unref (info);
2251 : :
2252 : : /* remove the last interface */
2253 : 3 : foo_igen_object_skeleton_set_bat (o, NULL);
2254 : : /* ... check we get the InterfacesRemoved */
2255 : 3 : om_data->state = 15;
2256 : 3 : g_main_loop_run (om_data->loop);
2257 : 3 : g_assert_cmpint (om_data->state, ==, 16);
2258 : 3 : g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 3);
2259 : 3 : g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 3);
2260 : 3 : g_assert_cmpint (om_data->num_interface_added_signals, ==, 1);
2261 : 3 : g_assert_cmpint (om_data->num_interface_removed_signals, ==, 1);
2262 : : /* ... check introspection data */
2263 : 3 : info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop);
2264 : 3 : g_assert_cmpint (count_interfaces (info), ==, 0); /* nothing */
2265 : 3 : g_dbus_node_info_unref (info);
2266 : :
2267 : : /* and add an interface again */
2268 : 3 : i = G_DBUS_INTERFACE_SKELETON (foo_igen_com_acme_coyote_skeleton_new ());
2269 : 3 : foo_igen_object_skeleton_set_com_acme_coyote (o, FOO_IGEN_COM_ACME_COYOTE (i));
2270 : 3 : g_clear_object (&i);
2271 : : /* ... check we get the InterfacesAdded */
2272 : 3 : om_data->state = 17;
2273 : 3 : g_main_loop_run (om_data->loop);
2274 : 3 : g_assert_cmpint (om_data->state, ==, 18);
2275 : 3 : g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 4);
2276 : 3 : g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 3);
2277 : 3 : g_assert_cmpint (om_data->num_interface_added_signals, ==, 1);
2278 : 3 : g_assert_cmpint (om_data->num_interface_removed_signals, ==, 1);
2279 : : /* ... check introspection data */
2280 : 3 : info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop);
2281 : 3 : g_assert_cmpint (count_interfaces (info), ==, 4); /* com.acme.Coyote + Properties,Introspectable,Peer */
2282 : 3 : g_assert (has_interface (info, "com.acme.Coyote"));
2283 : 3 : g_dbus_node_info_unref (info);
2284 : :
2285 : : /* Check GetManagedObjects() - should be just the Coyote */
2286 : 3 : om_check_get_all (c, loop,
2287 : : "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}},)");
2288 : :
2289 : : /* -------------------------------------------------- */
2290 : :
2291 : : /* create a new object with two interfaces */
2292 : 3 : o2 = foo_igen_object_skeleton_new ("/managed/second");
2293 : 3 : i = G_DBUS_INTERFACE_SKELETON (foo_igen_bar_skeleton_new ());
2294 : 3 : bar_skeleton = FOO_IGEN_BAR (i); /* save for later test */
2295 : 3 : foo_igen_object_skeleton_set_bar (o2, FOO_IGEN_BAR (i));
2296 : 3 : g_clear_object (&i);
2297 : 3 : i = G_DBUS_INTERFACE_SKELETON (foo_igen_bat_skeleton_new ());
2298 : 3 : foo_igen_object_skeleton_set_bat (o2, FOO_IGEN_BAT (i));
2299 : 3 : g_clear_object (&i);
2300 : : /* ... add it */
2301 : 3 : g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (o2));
2302 : : /* ... check we get the InterfacesAdded with _two_ interfaces */
2303 : 3 : om_data->state = 101;
2304 : 3 : g_main_loop_run (om_data->loop);
2305 : 3 : g_assert_cmpint (om_data->state, ==, 102);
2306 : 3 : g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 5);
2307 : 3 : g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 3);
2308 : 3 : g_assert_cmpint (om_data->num_interface_added_signals, ==, 1);
2309 : 3 : g_assert_cmpint (om_data->num_interface_removed_signals, ==, 1);
2310 : :
2311 : : /* -------------------------------------------------- */
2312 : :
2313 : : /* Now that we have a couple of objects with interfaces, check
2314 : : * that ObjectManager.GetManagedObjects() works
2315 : : */
2316 : 3 : om_check_get_all (c, loop,
2317 : : "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}, '/managed/second': {'org.project.Bar': {'y': <byte 0x00>, 'b': <false>, 'n': <int16 0>, 'q': <uint16 0>, 'i': <0>, 'u': <uint32 0>, 'x': <int64 0>, 't': <uint64 0>, 'd': <0.0>, 's': <''>, 'o': <objectpath '/'>, 'g': <signature ''>, 'ay': <b''>, 'as': <@as []>, 'aay': <@aay []>, 'ao': <@ao []>, 'ag': <@ag []>, 'FinallyNormalName': <''>, 'ReadonlyProperty': <''>, 'quiet': <''>, 'quiet_too': <''>, 'unset_i': <0>, 'unset_d': <0.0>, 'unset_s': <''>, 'unset_o': <objectpath '/'>, 'unset_g': <signature ''>, 'unset_ay': <b''>, 'unset_as': <@as []>, 'unset_ao': <@ao []>, 'unset_ag': <@ag []>, 'unset_struct': <(0, 0.0, '', objectpath '/', signature '', @ay [], @as [], @ao [], @ag [])>}, 'org.project.Bat': {'force_i': <0>, 'force_s': <''>, 'force_ay': <@ay []>, 'force_struct': <(0,)>}}},)");
2318 : :
2319 : : /* Set connection to NULL, causing everything to be unexported.. verify this.. and
2320 : : * then set the connection back.. and then check things still work
2321 : : */
2322 : 3 : g_dbus_object_manager_server_set_connection (manager, NULL);
2323 : 3 : info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed", loop);
2324 : 3 : g_assert_cmpint (count_interfaces (info), ==, 0); /* nothing */
2325 : 3 : g_dbus_node_info_unref (info);
2326 : :
2327 : 3 : g_dbus_object_manager_server_set_connection (manager, c);
2328 : 3 : om_check_get_all (c, loop,
2329 : : "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}, '/managed/second': {'org.project.Bar': {'y': <byte 0x00>, 'b': <false>, 'n': <int16 0>, 'q': <uint16 0>, 'i': <0>, 'u': <uint32 0>, 'x': <int64 0>, 't': <uint64 0>, 'd': <0.0>, 's': <''>, 'o': <objectpath '/'>, 'g': <signature ''>, 'ay': <b''>, 'as': <@as []>, 'aay': <@aay []>, 'ao': <@ao []>, 'ag': <@ag []>, 'FinallyNormalName': <''>, 'ReadonlyProperty': <''>, 'quiet': <''>, 'quiet_too': <''>, 'unset_i': <0>, 'unset_d': <0.0>, 'unset_s': <''>, 'unset_o': <objectpath '/'>, 'unset_g': <signature ''>, 'unset_ay': <b''>, 'unset_as': <@as []>, 'unset_ao': <@ao []>, 'unset_ag': <@ag []>, 'unset_struct': <(0, 0.0, '', objectpath '/', signature '', @ay [], @as [], @ao [], @ag [])>}, 'org.project.Bat': {'force_i': <0>, 'force_s': <''>, 'force_ay': <@ay []>, 'force_struct': <(0,)>}}},)");
2330 : :
2331 : : /* Also check that the ObjectManagerClient returns these objects - and
2332 : : * that they are of the right GType cf. what was requested via
2333 : : * the generated ::get-proxy-type signal handler
2334 : : */
2335 : 3 : object_proxies = g_dbus_object_manager_get_objects (pm);
2336 : 3 : g_assert (g_list_length (object_proxies) == 2);
2337 : 3 : g_list_free_full (object_proxies, g_object_unref);
2338 : 3 : op = g_dbus_object_manager_get_object (pm, "/managed/first");
2339 : 3 : g_assert (op != NULL);
2340 : 3 : g_assert (FOO_IGEN_IS_OBJECT_PROXY (op));
2341 : 3 : g_assert_cmpstr (g_dbus_object_get_object_path (op), ==, "/managed/first");
2342 : 3 : proxies = g_dbus_object_get_interfaces (op);
2343 : 3 : g_assert (g_list_length (proxies) == 1);
2344 : 3 : g_list_free_full (proxies, g_object_unref);
2345 : 3 : p = G_DBUS_PROXY (foo_igen_object_get_com_acme_coyote (FOO_IGEN_OBJECT (op)));
2346 : 3 : g_assert (p != NULL);
2347 : 3 : g_assert_cmpint (G_TYPE_FROM_INSTANCE (p), ==, FOO_IGEN_TYPE_COM_ACME_COYOTE_PROXY);
2348 : 3 : g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (p), FOO_IGEN_TYPE_COM_ACME_COYOTE));
2349 : 3 : g_clear_object (&p);
2350 : 3 : p = (GDBusProxy *) g_dbus_object_get_interface (op, "org.project.NonExisting");
2351 : 3 : g_assert (p == NULL);
2352 : 3 : g_clear_object (&op);
2353 : :
2354 : : /* -- */
2355 : 3 : op = g_dbus_object_manager_get_object (pm, "/managed/second");
2356 : 3 : g_assert (op != NULL);
2357 : 3 : g_assert (FOO_IGEN_IS_OBJECT_PROXY (op));
2358 : 3 : g_assert_cmpstr (g_dbus_object_get_object_path (op), ==, "/managed/second");
2359 : 3 : proxies = g_dbus_object_get_interfaces (op);
2360 : 3 : g_assert (g_list_length (proxies) == 2);
2361 : 3 : g_list_free_full (proxies, g_object_unref);
2362 : 3 : p = G_DBUS_PROXY (foo_igen_object_get_bat (FOO_IGEN_OBJECT (op)));
2363 : 3 : g_assert (p != NULL);
2364 : 3 : g_assert_cmpint (G_TYPE_FROM_INSTANCE (p), ==, FOO_IGEN_TYPE_BAT_PROXY);
2365 : 3 : g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (p), FOO_IGEN_TYPE_BAT));
2366 : 3 : g_clear_object (&p);
2367 : 3 : p = G_DBUS_PROXY (foo_igen_object_get_bar (FOO_IGEN_OBJECT (op)));
2368 : 3 : g_assert (p != NULL);
2369 : 3 : g_assert_cmpint (G_TYPE_FROM_INSTANCE (p), ==, FOO_IGEN_TYPE_BAR_PROXY);
2370 : 3 : g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (p), FOO_IGEN_TYPE_BAR));
2371 : : /* ... now that we have a Bar instance around, also check that we get signals
2372 : : * and property changes...
2373 : : */
2374 : 3 : om_check_property_and_signal_emission (loop, bar_skeleton, FOO_IGEN_BAR (p));
2375 : 3 : g_clear_object (&p);
2376 : 3 : p = (GDBusProxy *) g_dbus_object_get_interface (op, "org.project.NonExisting");
2377 : 3 : g_assert (p == NULL);
2378 : 3 : g_clear_object (&op);
2379 : :
2380 : : /* -------------------------------------------------- */
2381 : :
2382 : : /* Now remove the second object added above */
2383 : 3 : g_dbus_object_manager_server_unexport (manager, "/managed/second");
2384 : : /* ... check we get InterfacesRemoved with both interfaces */
2385 : 3 : om_data->state = 103;
2386 : 3 : g_main_loop_run (om_data->loop);
2387 : 3 : g_assert_cmpint (om_data->state, ==, 104);
2388 : 3 : g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 5);
2389 : 3 : g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 4);
2390 : 3 : g_assert_cmpint (om_data->num_interface_added_signals, ==, 1);
2391 : 3 : g_assert_cmpint (om_data->num_interface_removed_signals, ==, 1);
2392 : : /* ... check introspection data (there should be nothing) */
2393 : 3 : info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/second", loop);
2394 : 3 : g_assert_cmpint (count_nodes (info), ==, 0);
2395 : 3 : g_assert_cmpint (count_interfaces (info), ==, 0);
2396 : 3 : g_dbus_node_info_unref (info);
2397 : :
2398 : : /* Check GetManagedObjects() again */
2399 : 3 : om_check_get_all (c, loop,
2400 : : "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}},)");
2401 : : /* -------------------------------------------------- */
2402 : :
2403 : : /* Check that export_uniquely() works */
2404 : :
2405 : 3 : o3 = foo_igen_object_skeleton_new ("/managed/first");
2406 : 3 : i = G_DBUS_INTERFACE_SKELETON (foo_igen_com_acme_coyote_skeleton_new ());
2407 : 3 : foo_igen_com_acme_coyote_set_mood (FOO_IGEN_COM_ACME_COYOTE (i), "indifferent");
2408 : 3 : foo_igen_object_skeleton_set_com_acme_coyote (o3, FOO_IGEN_COM_ACME_COYOTE (i));
2409 : 3 : g_clear_object (&i);
2410 : 3 : g_dbus_object_manager_server_export_uniquely (manager, G_DBUS_OBJECT_SKELETON (o3));
2411 : : /* ... check we get the InterfacesAdded signal */
2412 : 3 : om_data->state = 200;
2413 : 3 : g_main_loop_run (om_data->loop);
2414 : 3 : g_assert_cmpint (om_data->state, ==, 201);
2415 : :
2416 : 3 : om_check_get_all (c, loop,
2417 : : "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}, '/managed/first_1': {'com.acme.Coyote': {'Mood': <'indifferent'>}}},)");
2418 : :
2419 : : //g_main_loop_run (loop); /* TODO: tmp */
2420 : :
2421 : : /* Clean up objects */
2422 : 3 : g_assert (g_dbus_object_manager_server_unexport (manager, "/managed/first_1"));
2423 : : //g_assert (g_dbus_object_manager_server_unexport (manager, "/managed/second"));
2424 : 3 : g_assert (g_dbus_object_manager_server_unexport (manager, "/managed/first"));
2425 : 3 : g_assert_cmpint (g_list_length (g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (manager))), ==, 0);
2426 : :
2427 [ + - ]: 3 : if (loop != NULL)
2428 : 3 : g_main_loop_unref (loop);
2429 : :
2430 [ + - ]: 3 : if (om_signal_id != 0)
2431 : 3 : g_dbus_connection_signal_unsubscribe (c, om_signal_id);
2432 : 3 : g_clear_object (&o3);
2433 : 3 : g_clear_object (&o2);
2434 : 3 : g_clear_object (&o);
2435 : 3 : g_clear_object (&manager);
2436 [ + - ]: 3 : if (pm != NULL)
2437 : : {
2438 : 3 : g_assert_cmpint (g_signal_handlers_disconnect_by_func (pm,
2439 : : G_CALLBACK (on_object_proxy_added),
2440 : : om_data), ==, 1);
2441 : 3 : g_assert_cmpint (g_signal_handlers_disconnect_by_func (pm,
2442 : : G_CALLBACK (on_object_proxy_removed),
2443 : : om_data), ==, 1);
2444 : 3 : g_clear_object (&pm);
2445 : : }
2446 : 3 : g_clear_object (&c);
2447 : :
2448 : 3 : g_free (om_data);
2449 : 3 : }
2450 : :
2451 : : /* ---------------------------------------------------------------------------------------------------- */
2452 : :
2453 : : static void
2454 : 3 : test_object_manager (void)
2455 : : {
2456 : : GMainLoop *loop;
2457 : : guint id;
2458 : :
2459 : 3 : loop = g_main_loop_new (NULL, FALSE);
2460 : :
2461 : 3 : id = g_bus_own_name (G_BUS_TYPE_SESSION,
2462 : : "org.gtk.GDBus.BindingsTool.Test",
2463 : : G_BUS_NAME_OWNER_FLAGS_NONE,
2464 : : on_bus_acquired,
2465 : : on_name_acquired,
2466 : : on_name_lost,
2467 : : loop,
2468 : : NULL);
2469 : :
2470 : 3 : g_main_loop_run (loop);
2471 : :
2472 : 3 : check_object_manager ();
2473 : :
2474 : : /* uncomment to keep the service around (to e.g. introspect it) */
2475 : : /* g_main_loop_run (loop); */
2476 : :
2477 : 3 : unexport_objects ();
2478 : :
2479 : 3 : g_bus_unown_name (id);
2480 : 3 : g_main_loop_unref (loop);
2481 : 3 : }
2482 : :
2483 : : /* ---------------------------------------------------------------------------------------------------- */
2484 : : /* This checks that forcing names via org.gtk.GDBus.Name works (see test-codegen.xml) */
2485 : :
2486 : : extern gpointer name_forcing_1;
2487 : : extern gpointer name_forcing_2;
2488 : : extern gpointer name_forcing_3;
2489 : : extern gpointer name_forcing_4;
2490 : : extern gpointer name_forcing_5;
2491 : : extern gpointer name_forcing_6;
2492 : : extern gpointer name_forcing_7;
2493 : : gpointer name_forcing_1 = foo_igen_rocket123_get_type;
2494 : : gpointer name_forcing_2 = foo_igen_rocket123_call_ignite_xyz;
2495 : : gpointer name_forcing_3 = foo_igen_rocket123_emit_exploded_xyz;
2496 : : gpointer name_forcing_4 = foo_igen_rocket123_get_speed_xyz;
2497 : : gpointer name_forcing_5 = foo_igen_test_ugly_case_interface_call_get_iscsi_servers;
2498 : : gpointer name_forcing_6 = foo_igen_test_ugly_case_interface_emit_servers_updated_now;
2499 : : gpointer name_forcing_7 = foo_igen_test_ugly_case_interface_get_ugly_name;
2500 : :
2501 : : /* ---------------------------------------------------------------------------------------------------- */
2502 : :
2503 : : /* See https://bugzilla.gnome.org/show_bug.cgi?id=647577#c5 for details */
2504 : :
2505 : : #define CHECK_FIELD(name, v1, v2) g_assert_cmpint (G_STRUCT_OFFSET (FooiGenChangingInterface##v1##Iface, name), ==, G_STRUCT_OFFSET (FooiGenChangingInterface##v2##Iface, name));
2506 : :
2507 : : static void
2508 : 3 : test_interface_stability (void)
2509 : : {
2510 [ - + ]: 3 : CHECK_FIELD(handle_foo_method, V1, V2);
2511 [ - + ]: 3 : CHECK_FIELD(handle_bar_method, V1, V2);
2512 [ - + ]: 3 : CHECK_FIELD(handle_baz_method, V1, V2);
2513 [ - + ]: 3 : CHECK_FIELD(foo_signal, V1, V2);
2514 [ - + ]: 3 : CHECK_FIELD(bar_signal, V1, V2);
2515 [ - + ]: 3 : CHECK_FIELD(baz_signal, V1, V2);
2516 [ - + ]: 3 : CHECK_FIELD(handle_new_method_in2, V2, V10);
2517 [ - + ]: 3 : CHECK_FIELD(new_signal_in2, V2, V10);
2518 : 3 : }
2519 : :
2520 : : #undef CHECK_FIELD
2521 : :
2522 : : /* ---------------------------------------------------------------------------------------------------- */
2523 : :
2524 : : /* property naming
2525 : : *
2526 : : * - check that a property with name "Type" is mapped into g-name "type"
2527 : : * with C accessors get_type_ (to avoid clashing with the GType accessor)
2528 : : * and set_type_ (for symmetry)
2529 : : * (see https://bugzilla.gnome.org/show_bug.cgi?id=679473 for details)
2530 : : *
2531 : : * - (could add more tests here)
2532 : : */
2533 : :
2534 : : static void
2535 : 3 : test_property_naming (void)
2536 : : {
2537 : 3 : gpointer c_getter_name = foo_igen_naming_get_type_;
2538 : 3 : gpointer c_setter_name = foo_igen_naming_set_type_;
2539 : : FooiGenNaming *skel;
2540 : :
2541 : : (void) c_getter_name;
2542 : : (void) c_setter_name;
2543 : :
2544 : 3 : skel = foo_igen_naming_skeleton_new ();
2545 : 3 : g_assert (g_object_class_find_property (G_OBJECT_GET_CLASS (skel), "type") != NULL);
2546 : 3 : g_object_unref (skel);
2547 : 3 : }
2548 : :
2549 : : /* ---------------------------------------------------------------------------------------------------- */
2550 : :
2551 : : /* autocleanups
2552 : : *
2553 : : * - check that g_autoptr() works for all generated types, if supported by the
2554 : : * current compiler
2555 : : */
2556 : :
2557 : : static void
2558 : 3 : test_autocleanups (void)
2559 : : {
2560 : : #ifdef g_autoptr
2561 : 3 : g_autoptr(FooiGenBar) bar = NULL;
2562 : 3 : g_autoptr(FooiGenBarProxy) bar_proxy = NULL;
2563 : 3 : g_autoptr(FooiGenBarSkeleton) bar_skeleton = NULL;
2564 : 3 : g_autoptr(FooiGenObject) object = NULL;
2565 : 3 : g_autoptr(FooiGenObjectProxy) object_proxy = NULL;
2566 : 3 : g_autoptr(FooiGenObjectSkeleton) object_skeleton = NULL;
2567 : 3 : g_autoptr(FooiGenObjectManagerClient) object_manager_client = NULL;
2568 : :
2569 : : (void) bar;
2570 : : (void) bar_proxy;
2571 : : (void) bar_skeleton;
2572 : : (void) object;
2573 : : (void) object_proxy;
2574 : : (void) object_skeleton;
2575 : : (void) object_manager_client;
2576 : : #elif GLIB_CHECK_VERSION(2, 38, 0)
2577 : : /* This file is compiled twice, once without GLib version guards and once
2578 : : * with
2579 : : *
2580 : : * -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_36
2581 : : * -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_36
2582 : : *
2583 : : * g_test_skip() was added in 2.38.
2584 : : */
2585 : : g_test_skip ("g_autoptr() not supported on this compiler");
2586 : : #else
2587 : : /* Let's just say it passed. */
2588 : : #endif
2589 : 3 : }
2590 : :
2591 : : /* ---------------------------------------------------------------------------------------------------- */
2592 : :
2593 : : /* deprecations
2594 : : */
2595 : :
2596 : : static void
2597 : 3 : test_deprecations (void)
2598 : : {
2599 : : {
2600 : : FooiGenOldieInterface *iskel;
2601 : : GParamSpec *pspec;
2602 : :
2603 : : G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
2604 : 3 : iskel = foo_igen_oldie_interface_skeleton_new ();
2605 : : G_GNUC_END_IGNORE_DEPRECATIONS;
2606 : :
2607 : 3 : pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (iskel), "bat");
2608 : 3 : g_assert_nonnull (pspec);
2609 : 3 : g_assert_cmpint (pspec->flags & G_PARAM_DEPRECATED, ==, G_PARAM_DEPRECATED);
2610 : :
2611 : 3 : g_object_unref (iskel);
2612 : : }
2613 : :
2614 : : {
2615 : : FooiGenObjectSkeleton *oskel;
2616 : : GParamSpec *pspec;
2617 : :
2618 : 3 : oskel = foo_igen_object_skeleton_new ("/objects/first");
2619 : 3 : pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (oskel), "oldie-interface");
2620 : 3 : g_assert_nonnull (pspec);
2621 : 3 : g_assert_cmpint (pspec->flags & G_PARAM_DEPRECATED, ==, G_PARAM_DEPRECATED);
2622 : :
2623 : 3 : g_object_unref (oskel);
2624 : : }
2625 : 3 : }
2626 : :
2627 : : /* ---------------------------------------------------------------------------------------------------- */
2628 : :
2629 : : static void
2630 : 48 : assert_arg_infos_equal (GDBusArgInfo **a,
2631 : : GDBusArgInfo **b)
2632 : : {
2633 [ + + ]: 48 : if (a == NULL)
2634 : : {
2635 : 21 : g_assert_null (b);
2636 : 21 : return;
2637 : : }
2638 : :
2639 : 27 : g_assert_nonnull (b);
2640 : :
2641 [ + + + - ]: 165 : for (; *a != NULL && *b != NULL; a++, b++)
2642 : : {
2643 : 138 : g_assert_cmpstr ((*a)->name, ==, (*b)->name);
2644 : 138 : g_assert_cmpstr ((*a)->signature, ==, (*b)->signature);
2645 : : }
2646 : :
2647 : 27 : g_assert_null (*a);
2648 : 27 : g_assert_null (*b);
2649 : : }
2650 : :
2651 : : static void
2652 : 147 : assert_annotations_equal (GDBusAnnotationInfo **a,
2653 : : GDBusAnnotationInfo **b)
2654 : : {
2655 : 147 : guint a_len = count_annotations (a);
2656 : 147 : guint b_len = count_annotations (b);
2657 : :
2658 : 147 : g_assert_cmpuint (a_len, ==, b_len);
2659 : :
2660 [ + + - + ]: 147 : if (a == NULL || b == NULL)
2661 : 129 : return;
2662 : :
2663 [ + + + - ]: 39 : for (; *a != NULL && *b != NULL; a++, b++)
2664 : : {
2665 : 21 : g_assert_cmpstr ((*a)->key, ==, (*b)->key);
2666 : 21 : g_assert_cmpstr ((*a)->value, ==, (*b)->value);
2667 : 21 : assert_annotations_equal ((*a)->annotations, (*b)->annotations);
2668 : : }
2669 : :
2670 : 18 : g_assert_null (*a);
2671 : 18 : g_assert_null (*b);
2672 : : }
2673 : :
2674 : : /* Test that the GDBusInterfaceInfo structure generated by gdbus-codegen
2675 : : * --interface-info-body matches that generated by the other mode.
2676 : : */
2677 : : static void
2678 : 3 : test_standalone_interface_info (void)
2679 : : {
2680 : 3 : GDBusInterfaceSkeleton *skel = G_DBUS_INTERFACE_SKELETON (foo_igen_bar_skeleton_new ());
2681 : 3 : GDBusInterfaceInfo *skel_info = g_dbus_interface_skeleton_get_info (skel);
2682 : 3 : const GDBusInterfaceInfo *slim_info = &org_project_bar_interface;
2683 : : gsize i;
2684 : :
2685 : 3 : g_assert_cmpstr (skel_info->name, ==, slim_info->name);
2686 : :
2687 [ + + ]: 24 : for (i = 0; skel_info->methods[i] != NULL; i++)
2688 : : {
2689 : 21 : GDBusMethodInfo *skel_method = skel_info->methods[i];
2690 : 21 : GDBusMethodInfo *slim_method = slim_info->methods[i];
2691 : :
2692 : 21 : g_assert_nonnull (slim_method);
2693 : 21 : g_assert_cmpstr (skel_method->name, ==, slim_method->name);
2694 : 21 : assert_arg_infos_equal (skel_method->in_args, slim_method->in_args);
2695 : 21 : assert_arg_infos_equal (skel_method->out_args, slim_method->out_args);
2696 : 21 : assert_annotations_equal (skel_method->annotations, slim_method->annotations);
2697 : : }
2698 : 3 : g_assert_null (slim_info->methods[i]);
2699 : :
2700 [ + + ]: 9 : for (i = 0; skel_info->signals[i] != NULL; i++)
2701 : : {
2702 : 6 : GDBusSignalInfo *skel_signal = skel_info->signals[i];
2703 : 6 : GDBusSignalInfo *slim_signal = slim_info->signals[i];
2704 : :
2705 : 6 : g_assert_nonnull (slim_signal);
2706 : 6 : g_assert_cmpstr (skel_signal->name, ==, slim_signal->name);
2707 : 6 : assert_arg_infos_equal (skel_signal->args, slim_signal->args);
2708 : 6 : assert_annotations_equal (skel_signal->annotations, slim_signal->annotations);
2709 : : }
2710 : 3 : g_assert_null (slim_info->signals[i]);
2711 : :
2712 [ + + ]: 99 : for (i = 0; skel_info->properties[i] != NULL; i++)
2713 : : {
2714 : 96 : GDBusPropertyInfo *skel_prop = skel_info->properties[i];
2715 : 96 : GDBusPropertyInfo *slim_prop = slim_info->properties[i];
2716 : :
2717 : 96 : g_assert_nonnull (slim_prop);
2718 : :
2719 : 96 : g_assert_cmpstr (skel_prop->name, ==, slim_prop->name);
2720 : 96 : g_assert_cmpstr (skel_prop->signature, ==, slim_prop->signature);
2721 : 96 : g_assert_cmpuint (skel_prop->flags, ==, slim_prop->flags);
2722 : 96 : assert_annotations_equal (skel_prop->annotations, slim_prop->annotations);
2723 : : }
2724 : 3 : g_assert_null (slim_info->properties[i]);
2725 : :
2726 : 3 : assert_annotations_equal (skel_info->annotations, slim_info->annotations);
2727 : :
2728 : 3 : g_clear_object (&skel);
2729 : 3 : }
2730 : :
2731 : : /* ---------------------------------------------------------------------------------------------------- */
2732 : : static gboolean
2733 : 0 : handle_hello_fd (FooiGenTestFDPassing *object,
2734 : : GDBusMethodInvocation *invocation,
2735 : : GUnixFDList *fd_list,
2736 : : const gchar *arg_greeting)
2737 : : {
2738 : 0 : foo_igen_test_fdpassing_complete_hello_fd (object, invocation, fd_list, arg_greeting);
2739 : 0 : return G_DBUS_METHOD_INVOCATION_HANDLED;
2740 : : }
2741 : :
2742 : : #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64
2743 : : static gboolean
2744 : 0 : handle_no_annotation (FooiGenTestFDPassing *object,
2745 : : GDBusMethodInvocation *invocation,
2746 : : GUnixFDList *fd_list,
2747 : : GVariant *arg_greeting,
2748 : : const gchar *arg_greeting_locale)
2749 : : {
2750 : 0 : foo_igen_test_fdpassing_complete_no_annotation (object, invocation, fd_list, arg_greeting, arg_greeting_locale);
2751 : 0 : return G_DBUS_METHOD_INVOCATION_HANDLED;
2752 : : }
2753 : :
2754 : : static gboolean
2755 : 0 : handle_no_annotation_nested (FooiGenTestFDPassing *object,
2756 : : GDBusMethodInvocation *invocation,
2757 : : GUnixFDList *fd_list,
2758 : : GVariant *arg_files)
2759 : : {
2760 : 0 : foo_igen_test_fdpassing_complete_no_annotation_nested (object, invocation, fd_list);
2761 : 0 : return G_DBUS_METHOD_INVOCATION_HANDLED;
2762 : : }
2763 : : #else
2764 : : static gboolean
2765 : 0 : handle_no_annotation (FooiGenTestFDPassing *object,
2766 : : GDBusMethodInvocation *invocation,
2767 : : GVariant *arg_greeting,
2768 : : const gchar *arg_greeting_locale)
2769 : : {
2770 : 0 : foo_igen_test_fdpassing_complete_no_annotation (object, invocation, arg_greeting, arg_greeting_locale);
2771 : 0 : return G_DBUS_METHOD_INVOCATION_HANDLED;
2772 : : }
2773 : :
2774 : : static gboolean
2775 : 0 : handle_no_annotation_nested (FooiGenTestFDPassing *object,
2776 : : GDBusMethodInvocation *invocation,
2777 : : GVariant *arg_files)
2778 : : {
2779 : 0 : foo_igen_test_fdpassing_complete_no_annotation_nested (object, invocation);
2780 : 0 : return G_DBUS_METHOD_INVOCATION_HANDLED;
2781 : : }
2782 : : #endif
2783 : :
2784 : : /* Test that generated code for methods includes GUnixFDList arguments
2785 : : * unconditionally if the method is explicitly annotated as C.UnixFD, and only
2786 : : * emits GUnixFDList arguments when there's merely an 'h' parameter if
2787 : : * --glib-min-required=2.64 or greater.
2788 : : */
2789 : : static void
2790 : 3 : test_unix_fd_list (void)
2791 : : {
2792 : : FooiGenTestFDPassingIface iface;
2793 : :
2794 : 3 : g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1726");
2795 : :
2796 : : /* This method is explicitly annotated. */
2797 : 3 : iface.handle_hello_fd = handle_hello_fd;
2798 : :
2799 : : /* This one is not annotated; even though it's got an in and out 'h'
2800 : : * parameter, for backwards compatibility we cannot emit GUnixFDList
2801 : : * arguments unless --glib-min-required >= 2.64 was used.
2802 : : */
2803 : 3 : iface.handle_no_annotation = handle_no_annotation;
2804 : :
2805 : : /* This method has an 'h' inside a complex type. */
2806 : 3 : iface.handle_no_annotation_nested = handle_no_annotation_nested;
2807 : :
2808 : : (void) iface;
2809 : 3 : }
2810 : :
2811 : : /* ---------------------------------------------------------------------------------------------------- */
2812 : :
2813 : : int
2814 : 3 : main (int argc,
2815 : : char *argv[])
2816 : : {
2817 : 3 : g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
2818 : :
2819 : 3 : g_test_add_func ("/gdbus/codegen/annotations", test_annotations);
2820 : 3 : g_test_add_func ("/gdbus/codegen/interface_stability", test_interface_stability);
2821 : 3 : g_test_add_func ("/gdbus/codegen/object-manager", test_object_manager);
2822 : 3 : g_test_add_func ("/gdbus/codegen/property-naming", test_property_naming);
2823 : 3 : g_test_add_func ("/gdbus/codegen/autocleanups", test_autocleanups);
2824 : 3 : g_test_add_func ("/gdbus/codegen/deprecations", test_deprecations);
2825 : 3 : g_test_add_func ("/gdbus/codegen/standalone-interface-info", test_standalone_interface_info);
2826 : 3 : g_test_add_func ("/gdbus/codegen/unix-fd-list", test_unix_fd_list);
2827 : :
2828 : 3 : return session_bus_run ();
2829 : : }
|