1 /* GDBus - GLib D-Bus Library
3 * Copyright (C) 2008-2010 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Author: David Zeuthen <davidz@redhat.com>
25 #include "gdbusobjectmanager.h"
26 #include "gdbusobjectmanagerserver.h"
27 #include "gdbusobject.h"
28 #include "gdbusobjectskeleton.h"
29 #include "gdbusinterfaceskeleton.h"
30 #include "gdbusconnection.h"
31 #include "gdbusintrospection.h"
32 #include "gdbusmethodinvocation.h"
33 #include "gdbuserror.h"
38 * SECTION:gdbusobjectmanagerserver
39 * @short_description: Service-side object manager
42 * #GDBusObjectManagerServer is used to export #GDBusObject instances using
43 * the standardized <ulink
44 * url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager">org.freedesktop.DBus.ObjectManager</ulink>
45 * interface. For example, remote D-Bus clients can get all objects
46 * and properties in a single call. Additionally, any change in the
47 * object hierarchy is broadcast using signals. This means that D-Bus
48 * clients can keep caches up to date by only listening to D-Bus
51 * See #GDBusObjectManagerClient for the client-side code that is
52 * intended to be used with #GDBusObjectManagerServer or any D-Bus
53 * object implementing the org.freedesktop.DBus.ObjectManager
59 GDBusObjectSkeleton *object;
60 GDBusObjectManagerServer *manager;
61 GHashTable *map_iface_name_to_iface;
65 static void registration_data_free (RegistrationData *data);
67 static void export_all (GDBusObjectManagerServer *manager);
68 static void unexport_all (GDBusObjectManagerServer *manager, gboolean only_manager);
70 static void g_dbus_object_manager_server_emit_interfaces_added (GDBusObjectManagerServer *manager,
71 RegistrationData *data,
72 const gchar *const *interfaces);
74 static void g_dbus_object_manager_server_emit_interfaces_removed (GDBusObjectManagerServer *manager,
75 RegistrationData *data,
76 const gchar *const *interfaces);
78 struct _GDBusObjectManagerServerPrivate
80 GDBusConnection *connection;
82 gchar *object_path_ending_in_slash;
83 GHashTable *map_object_path_to_data;
94 static void dbus_object_manager_interface_init (GDBusObjectManagerIface *iface);
96 G_DEFINE_TYPE_WITH_CODE (GDBusObjectManagerServer, g_dbus_object_manager_server, G_TYPE_OBJECT,
97 G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT_MANAGER, dbus_object_manager_interface_init));
99 static void g_dbus_object_manager_server_constructed (GObject *object);
102 g_dbus_object_manager_server_finalize (GObject *object)
104 GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);
106 if (manager->priv->connection != NULL)
108 unexport_all (manager, TRUE);
109 g_object_unref (manager->priv->connection);
111 g_hash_table_unref (manager->priv->map_object_path_to_data);
112 g_free (manager->priv->object_path);
113 g_free (manager->priv->object_path_ending_in_slash);
115 if (G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->finalize != NULL)
116 G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->finalize (object);
120 g_dbus_object_manager_server_get_property (GObject *object,
125 GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);
129 case PROP_CONNECTION:
130 g_value_set_object (value, manager->priv->connection);
133 case PROP_OBJECT_PATH:
134 g_value_set_string (value, g_dbus_object_manager_get_object_path (G_DBUS_OBJECT_MANAGER (manager)));
138 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
144 g_dbus_object_manager_server_set_property (GObject *object,
149 GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);
153 case PROP_CONNECTION:
154 g_dbus_object_manager_server_set_connection (manager, g_value_get_object (value));
157 case PROP_OBJECT_PATH:
158 g_assert (manager->priv->object_path == NULL);
159 g_assert (g_variant_is_object_path (g_value_get_string (value)));
160 manager->priv->object_path = g_value_dup_string (value);
161 manager->priv->object_path_ending_in_slash = g_strdup_printf ("%s/", manager->priv->object_path);
165 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
171 g_dbus_object_manager_server_class_init (GDBusObjectManagerServerClass *klass)
173 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
175 gobject_class->finalize = g_dbus_object_manager_server_finalize;
176 gobject_class->constructed = g_dbus_object_manager_server_constructed;
177 gobject_class->set_property = g_dbus_object_manager_server_set_property;
178 gobject_class->get_property = g_dbus_object_manager_server_get_property;
181 * GDBusObjectManagerServer:connection:
183 * The #GDBusConnection to export objects on.
187 g_object_class_install_property (gobject_class,
189 g_param_spec_object ("connection",
191 "The connection to export objects on",
192 G_TYPE_DBUS_CONNECTION,
195 G_PARAM_STATIC_STRINGS));
198 * GDBusObjectManagerServer:object-path:
200 * The object path to register the manager object at.
204 g_object_class_install_property (gobject_class,
206 g_param_spec_string ("object-path",
208 "The object path to register the manager object at",
212 G_PARAM_CONSTRUCT_ONLY |
213 G_PARAM_STATIC_STRINGS));
215 g_type_class_add_private (klass, sizeof (GDBusObjectManagerServerPrivate));
219 g_dbus_object_manager_server_init (GDBusObjectManagerServer *manager)
221 manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
222 G_TYPE_DBUS_OBJECT_MANAGER_SERVER,
223 GDBusObjectManagerServerPrivate);
224 manager->priv->map_object_path_to_data = g_hash_table_new_full (g_str_hash,
227 (GDestroyNotify) registration_data_free);
231 * g_dbus_object_manager_server_new:
232 * @object_path: The object path to export the manager object at.
234 * Creates a new #GDBusObjectManagerServer object.
236 * The returned server isn't yet exported on any connection. To do so,
237 * use g_dbus_object_manager_server_set_connection(). Normally you
238 * want to export all of your objects before doing so to avoid <ulink
239 * url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager">InterfacesAdded</ulink>
240 * signals being emitted.
242 * Returns: A #GDBusObjectManagerServer object. Free with g_object_unref().
246 GDBusObjectManagerServer *
247 g_dbus_object_manager_server_new (const gchar *object_path)
249 g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
250 return G_DBUS_OBJECT_MANAGER_SERVER (g_object_new (G_TYPE_DBUS_OBJECT_MANAGER_SERVER,
251 "object-path", object_path,
256 * g_dbus_object_manager_server_set_connection:
257 * @manager: A #GDBusObjectManagerServer.
258 * @connection: (allow-none): A #GDBusConnection or %NULL.
260 * Exports all objects managed by @manager on @connection. If
261 * @connection is %NULL, stops exporting objects.
264 g_dbus_object_manager_server_set_connection (GDBusObjectManagerServer *manager,
265 GDBusConnection *connection)
267 g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
268 g_return_if_fail (connection == NULL || G_IS_DBUS_CONNECTION (connection));
270 if (manager->priv->connection == connection)
273 if (manager->priv->connection != NULL)
275 unexport_all (manager, FALSE);
276 g_object_unref (manager->priv->connection);
277 manager->priv->connection = NULL;
280 manager->priv->connection = connection != NULL ? g_object_ref (connection) : NULL;
281 if (manager->priv->connection != NULL)
282 export_all (manager);
284 g_object_notify (G_OBJECT (manager), "connection");
290 * g_dbus_object_manager_server_get_connection:
291 * @manager: A #GDBusObjectManagerServer
293 * Gets the #GDBusConnection used by @manager.
295 * Returns: (transfer full): A #GDBusConnection object or %NULL if
296 * @manager isn't exported on a connection. The returned object should
297 * be freed with g_object_unref().
302 g_dbus_object_manager_server_get_connection (GDBusObjectManagerServer *manager)
304 g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), NULL);
305 return manager->priv->connection != NULL ? g_object_ref (manager->priv->connection) : NULL;
308 /* ---------------------------------------------------------------------------------------------------- */
311 registration_data_export_interface (RegistrationData *data,
312 GDBusInterfaceSkeleton *interface_skeleton)
314 GDBusInterfaceInfo *info;
316 const gchar *object_path;
318 object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
320 info = g_dbus_interface_skeleton_get_info (interface_skeleton);
322 if (data->manager->priv->connection != NULL)
324 if (!g_dbus_interface_skeleton_export (interface_skeleton,
325 data->manager->priv->connection,
329 g_warning ("%s: Error registering object at %s with interface %s: %s",
334 g_error_free (error);
338 g_assert (g_hash_table_lookup (data->map_iface_name_to_iface, info->name) == NULL);
339 g_hash_table_insert (data->map_iface_name_to_iface,
341 g_object_ref (interface_skeleton));
343 /* if we are already exported, then... */
346 const gchar *interfaces[2];
347 /* emit InterfacesAdded on the ObjectManager object */
348 interfaces[0] = info->name;
349 interfaces[1] = NULL;
350 g_dbus_object_manager_server_emit_interfaces_added (data->manager, data, interfaces);
355 registration_data_unexport_interface (RegistrationData *data,
356 GDBusInterfaceSkeleton *interface_skeleton)
358 GDBusInterfaceInfo *info;
359 GDBusInterfaceSkeleton *iface;
361 info = g_dbus_interface_skeleton_get_info (interface_skeleton);
362 iface = g_hash_table_lookup (data->map_iface_name_to_iface, info->name);
363 g_assert (iface != NULL);
365 if (data->manager->priv->connection != NULL)
366 g_dbus_interface_skeleton_unexport (iface);
368 g_warn_if_fail (g_hash_table_remove (data->map_iface_name_to_iface, info->name));
370 /* if we are already exported, then... */
373 const gchar *interfaces[2];
374 /* emit InterfacesRemoved on the ObjectManager object */
375 interfaces[0] = info->name;
376 interfaces[1] = NULL;
377 g_dbus_object_manager_server_emit_interfaces_removed (data->manager, data, interfaces);
381 /* ---------------------------------------------------------------------------------------------------- */
384 on_interface_added (GDBusObject *object,
385 GDBusInterface *interface,
388 RegistrationData *data = user_data;
389 registration_data_export_interface (data, G_DBUS_INTERFACE_SKELETON (interface));
393 on_interface_removed (GDBusObject *object,
394 GDBusInterface *interface,
397 RegistrationData *data = user_data;
398 registration_data_unexport_interface (data, G_DBUS_INTERFACE_SKELETON (interface));
401 /* ---------------------------------------------------------------------------------------------------- */
405 registration_data_free (RegistrationData *data)
408 GDBusInterfaceSkeleton *iface;
410 data->exported = FALSE;
412 g_hash_table_iter_init (&iter, data->map_iface_name_to_iface);
413 while (g_hash_table_iter_next (&iter, NULL, (gpointer) &iface))
415 if (data->manager->priv->connection != NULL)
416 g_dbus_interface_skeleton_unexport (iface);
419 g_signal_handlers_disconnect_by_func (data->object, G_CALLBACK (on_interface_added), data);
420 g_signal_handlers_disconnect_by_func (data->object, G_CALLBACK (on_interface_removed), data);
421 g_object_unref (data->object);
422 g_hash_table_destroy (data->map_iface_name_to_iface);
426 /* ---------------------------------------------------------------------------------------------------- */
429 * g_dbus_object_manager_server_export:
430 * @manager: A #GDBusObjectManagerServer.
431 * @object: A #GDBusObjectSkeleton.
433 * Exports @object on @manager.
435 * If there is already a #GDBusObject exported at the object path,
436 * then the old object is removed.
438 * The object path for @object must be in the hierarchy rooted by the
439 * object path for @manager.
441 * Note that @manager will take a reference on @object for as long as
447 g_dbus_object_manager_server_export (GDBusObjectManagerServer *manager,
448 GDBusObjectSkeleton *object)
450 RegistrationData *data;
451 GList *existing_interfaces;
453 GPtrArray *interface_names;
454 const gchar *object_path;
456 object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
458 g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
459 g_return_if_fail (G_IS_DBUS_OBJECT (object));
460 g_return_if_fail (g_str_has_prefix (object_path, manager->priv->object_path_ending_in_slash));
462 interface_names = g_ptr_array_new ();
464 data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
466 g_dbus_object_manager_server_unexport (manager, object_path);
468 data = g_new0 (RegistrationData, 1);
469 data->object = g_object_ref (object);
470 data->manager = manager;
471 data->map_iface_name_to_iface = g_hash_table_new_full (g_str_hash,
474 (GDestroyNotify) g_object_unref);
476 g_signal_connect (object,
478 G_CALLBACK (on_interface_added),
480 g_signal_connect (object,
482 G_CALLBACK (on_interface_removed),
485 /* Register all known interfaces - note that data->exported is FALSE so
486 * we don't emit any InterfacesAdded signals.
488 existing_interfaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (object));
489 for (l = existing_interfaces; l != NULL; l = l->next)
491 GDBusInterfaceSkeleton *interface_skeleton = G_DBUS_INTERFACE_SKELETON (l->data);
492 registration_data_export_interface (data, interface_skeleton);
493 g_ptr_array_add (interface_names, g_dbus_interface_skeleton_get_info (interface_skeleton)->name);
495 g_list_foreach (existing_interfaces, (GFunc) g_object_unref, NULL);
496 g_list_free (existing_interfaces);
497 g_ptr_array_add (interface_names, NULL);
499 data->exported = TRUE;
501 /* now emit InterfacesAdded() for all the interfaces */
502 g_dbus_object_manager_server_emit_interfaces_added (manager, data, (const gchar *const *) interface_names->pdata);
503 g_ptr_array_unref (interface_names);
505 g_hash_table_insert (manager->priv->map_object_path_to_data,
506 g_strdup (object_path),
511 * g_dbus_object_manager_server_export_uniquely:
512 * @manager: A #GDBusObjectManagerServer.
513 * @object: An object.
515 * Like g_dbus_object_manager_server_export() but appends a string of
516 * the form <literal>_N</literal> (with N being a natural number) to
517 * @object<!-- -->'s object path if an object with the given path
518 * already exists. As such, the #GDBusObjectProxy:object-path property
519 * of @object may be modified.
524 g_dbus_object_manager_server_export_uniquely (GDBusObjectManagerServer *manager,
525 GDBusObjectSkeleton *object)
527 gchar *orig_object_path;
532 orig_object_path = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
534 g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
535 g_return_if_fail (G_IS_DBUS_OBJECT (object));
536 g_return_if_fail (g_str_has_prefix (orig_object_path, manager->priv->object_path_ending_in_slash));
538 object_path = g_strdup (orig_object_path);
543 RegistrationData *data;
544 data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
549 g_free (object_path);
550 object_path = g_strdup_printf ("%s_%d", orig_object_path, count++);
555 g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (object), object_path);
557 g_dbus_object_manager_server_export (manager, object);
559 g_free (object_path);
560 g_free (orig_object_path);
564 * g_dbus_object_manager_server_unexport:
565 * @manager: A #GDBusObjectManagerServer.
566 * @object_path: An object path.
568 * If @manager has an object at @path, removes the object. Otherwise
571 * Note that @object_path must be in the hierarchy rooted by the
572 * object path for @manager.
574 * Returns: %TRUE if object at @object_path was removed, %FALSE otherwise.
579 g_dbus_object_manager_server_unexport (GDBusObjectManagerServer *manager,
580 const gchar *object_path)
582 RegistrationData *data;
585 g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), FALSE);
586 g_return_val_if_fail (g_variant_is_object_path (object_path), FALSE);
587 g_return_val_if_fail (g_str_has_prefix (object_path, manager->priv->object_path_ending_in_slash), FALSE);
591 data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
594 GPtrArray *interface_names;
596 const gchar *iface_name;
598 interface_names = g_ptr_array_new ();
599 g_hash_table_iter_init (&iter, data->map_iface_name_to_iface);
600 while (g_hash_table_iter_next (&iter, (gpointer) &iface_name, NULL))
601 g_ptr_array_add (interface_names, (gpointer) iface_name);
602 g_ptr_array_add (interface_names, NULL);
603 /* now emit InterfacesRemoved() for all the interfaces */
604 g_dbus_object_manager_server_emit_interfaces_removed (manager, data, (const gchar *const *) interface_names->pdata);
605 g_ptr_array_unref (interface_names);
607 g_hash_table_remove (manager->priv->map_object_path_to_data, object_path);
615 /* ---------------------------------------------------------------------------------------------------- */
617 static const GDBusArgInfo manager_interfaces_added_signal_info_arg0 =
622 (GDBusAnnotationInfo**) NULL,
625 static const GDBusArgInfo manager_interfaces_added_signal_info_arg1 =
628 "interfaces_and_properties",
630 (GDBusAnnotationInfo**) NULL,
633 static const GDBusArgInfo * const manager_interfaces_added_signal_info_arg_pointers[] =
635 &manager_interfaces_added_signal_info_arg0,
636 &manager_interfaces_added_signal_info_arg1,
640 static const GDBusSignalInfo manager_interfaces_added_signal_info =
644 (GDBusArgInfo**) &manager_interfaces_added_signal_info_arg_pointers,
645 (GDBusAnnotationInfo**) NULL
650 static const GDBusArgInfo manager_interfaces_removed_signal_info_arg0 =
655 (GDBusAnnotationInfo**) NULL,
658 static const GDBusArgInfo manager_interfaces_removed_signal_info_arg1 =
663 (GDBusAnnotationInfo**) NULL,
666 static const GDBusArgInfo * const manager_interfaces_removed_signal_info_arg_pointers[] =
668 &manager_interfaces_removed_signal_info_arg0,
669 &manager_interfaces_removed_signal_info_arg1,
673 static const GDBusSignalInfo manager_interfaces_removed_signal_info =
677 (GDBusArgInfo**) &manager_interfaces_removed_signal_info_arg_pointers,
678 (GDBusAnnotationInfo**) NULL
683 static const GDBusSignalInfo * const manager_signal_info_pointers[] =
685 &manager_interfaces_added_signal_info,
686 &manager_interfaces_removed_signal_info,
692 static const GDBusArgInfo manager_get_all_method_info_out_arg0 =
695 "object_paths_interfaces_and_properties",
697 (GDBusAnnotationInfo**) NULL,
700 static const GDBusArgInfo * const manager_get_all_method_info_out_arg_pointers[] =
702 &manager_get_all_method_info_out_arg0,
706 static const GDBusMethodInfo manager_get_all_method_info =
710 (GDBusArgInfo**) NULL,
711 (GDBusArgInfo**) &manager_get_all_method_info_out_arg_pointers,
712 (GDBusAnnotationInfo**) NULL
715 static const GDBusMethodInfo * const manager_method_info_pointers[] =
717 &manager_get_all_method_info,
723 static const GDBusInterfaceInfo manager_interface_info =
726 "org.freedesktop.DBus.ObjectManager",
727 (GDBusMethodInfo **) manager_method_info_pointers,
728 (GDBusSignalInfo **) manager_signal_info_pointers,
729 (GDBusPropertyInfo **) NULL,
730 (GDBusAnnotationInfo **) NULL
734 manager_method_call (GDBusConnection *connection,
736 const gchar *object_path,
737 const gchar *interface_name,
738 const gchar *method_name,
739 GVariant *parameters,
740 GDBusMethodInvocation *invocation,
743 GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (user_data);
744 GVariantBuilder array_builder;
745 GHashTableIter object_iter;
746 RegistrationData *data;
748 if (g_strcmp0 (method_name, "GetManagedObjects") == 0)
750 g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a{oa{sa{sv}}}"));
751 g_hash_table_iter_init (&object_iter, manager->priv->map_object_path_to_data);
752 while (g_hash_table_iter_next (&object_iter, NULL, (gpointer) &data))
754 GVariantBuilder interfaces_builder;
755 GHashTableIter interface_iter;
756 GDBusInterfaceSkeleton *iface;
757 const gchar *iter_object_path;
759 g_variant_builder_init (&interfaces_builder, G_VARIANT_TYPE ("a{sa{sv}}"));
760 g_hash_table_iter_init (&interface_iter, data->map_iface_name_to_iface);
761 while (g_hash_table_iter_next (&interface_iter, NULL, (gpointer) &iface))
763 g_variant_builder_add_value (&interfaces_builder,
764 g_variant_new ("{s@a{sv}}",
765 g_dbus_interface_skeleton_get_info (iface)->name,
766 g_dbus_interface_skeleton_get_properties (iface)));
768 iter_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
769 g_variant_builder_add (&array_builder,
772 &interfaces_builder);
775 g_dbus_method_invocation_return_value (invocation,
776 g_variant_new ("(a{oa{sa{sv}}})",
781 g_dbus_method_invocation_return_error (invocation,
783 G_DBUS_ERROR_UNKNOWN_METHOD,
784 "Unknown method %s - only GetManagedObjects() is supported",
789 static const GDBusInterfaceVTable manager_interface_vtable =
791 manager_method_call, /* handle_method_call */
792 NULL, /* get_property */
793 NULL /* set_property */
796 /* ---------------------------------------------------------------------------------------------------- */
799 g_dbus_object_manager_server_constructed (GObject *object)
801 GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);
803 if (manager->priv->connection != NULL)
804 export_all (manager);
806 if (G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->constructed != NULL)
807 G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->constructed (object);
811 g_dbus_object_manager_server_emit_interfaces_added (GDBusObjectManagerServer *manager,
812 RegistrationData *data,
813 const gchar *const *interfaces)
815 GVariantBuilder array_builder;
818 const gchar *object_path;
820 if (data->manager->priv->connection == NULL)
823 g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a{sa{sv}}"));
824 for (n = 0; interfaces[n] != NULL; n++)
826 GDBusInterfaceSkeleton *iface;
827 iface = g_hash_table_lookup (data->map_iface_name_to_iface, interfaces[n]);
828 g_assert (iface != NULL);
829 g_variant_builder_add_value (&array_builder,
830 g_variant_new ("{s@a{sv}}",
832 g_dbus_interface_skeleton_get_properties (iface)));
836 object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
837 g_dbus_connection_emit_signal (data->manager->priv->connection,
838 NULL, /* destination_bus_name */
839 manager->priv->object_path,
840 manager_interface_info.name,
842 g_variant_new ("(oa{sa{sv}})",
846 g_assert_no_error (error);
852 g_dbus_object_manager_server_emit_interfaces_removed (GDBusObjectManagerServer *manager,
853 RegistrationData *data,
854 const gchar *const *interfaces)
856 GVariantBuilder array_builder;
859 const gchar *object_path;
861 if (data->manager->priv->connection == NULL)
864 g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("as"));
865 for (n = 0; interfaces[n] != NULL; n++)
866 g_variant_builder_add (&array_builder, "s", interfaces[n]);
869 object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
870 g_dbus_connection_emit_signal (data->manager->priv->connection,
871 NULL, /* destination_bus_name */
872 manager->priv->object_path,
873 manager_interface_info.name,
875 g_variant_new ("(oas)",
879 g_assert_no_error (error);
884 /* ---------------------------------------------------------------------------------------------------- */
887 g_dbus_object_manager_server_get_objects (GDBusObjectManager *_manager)
889 GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_manager);
892 RegistrationData *data;
895 g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data);
896 while (g_hash_table_iter_next (&iter, NULL, (gpointer) &data))
898 ret = g_list_prepend (ret, g_object_ref (data->object));
905 g_dbus_object_manager_server_get_object_path (GDBusObjectManager *_manager)
907 GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_manager);
908 return manager->priv->object_path;
912 g_dbus_object_manager_server_get_object (GDBusObjectManager *_manager,
913 const gchar *object_path)
915 GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_manager);
917 RegistrationData *data;
920 data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
922 ret = g_object_ref (data->object);
926 static GDBusInterface *
927 g_dbus_object_manager_server_get_interface (GDBusObjectManager *_manager,
928 const gchar *object_path,
929 const gchar *interface_name)
936 object = g_dbus_object_manager_get_object (_manager, object_path);
940 ret = g_dbus_object_get_interface (object, interface_name);
941 g_object_unref (object);
948 dbus_object_manager_interface_init (GDBusObjectManagerIface *iface)
950 iface->get_object_path = g_dbus_object_manager_server_get_object_path;
951 iface->get_objects = g_dbus_object_manager_server_get_objects;
952 iface->get_object = g_dbus_object_manager_server_get_object;
953 iface->get_interface = g_dbus_object_manager_server_get_interface;
956 /* ---------------------------------------------------------------------------------------------------- */
959 export_all (GDBusObjectManagerServer *manager)
962 const gchar *object_path;
963 RegistrationData *data;
964 GHashTableIter iface_iter;
965 GDBusInterfaceSkeleton *iface;
968 g_return_if_fail (manager->priv->connection != NULL);
971 g_warn_if_fail (manager->priv->manager_reg_id == 0);
972 manager->priv->manager_reg_id = g_dbus_connection_register_object (manager->priv->connection,
973 manager->priv->object_path,
974 (GDBusInterfaceInfo *) &manager_interface_info,
975 &manager_interface_vtable,
977 NULL, /* user_data_free_func */
979 if (manager->priv->manager_reg_id == 0)
981 g_warning ("%s: Error registering manager at %s: %s",
983 manager->priv->object_path,
985 g_error_free (error);
988 g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data);
989 while (g_hash_table_iter_next (&iter, (gpointer) &object_path, (gpointer) &data))
991 g_hash_table_iter_init (&iface_iter, data->map_iface_name_to_iface);
992 while (g_hash_table_iter_next (&iface_iter, NULL, (gpointer) &iface))
994 g_warn_if_fail (g_dbus_interface_skeleton_get_connection (iface) == NULL);
996 if (!g_dbus_interface_skeleton_export (iface,
997 manager->priv->connection,
1001 g_warning ("%s: Error registering object at %s with interface %s: %s",
1004 g_dbus_interface_skeleton_get_info (iface)->name,
1006 g_error_free (error);
1013 unexport_all (GDBusObjectManagerServer *manager, gboolean only_manager)
1015 GHashTableIter iter;
1016 RegistrationData *data;
1017 GHashTableIter iface_iter;
1018 GDBusInterfaceSkeleton *iface;
1020 g_return_if_fail (manager->priv->connection != NULL);
1022 g_warn_if_fail (manager->priv->manager_reg_id > 0);
1023 if (manager->priv->manager_reg_id > 0)
1025 g_warn_if_fail (g_dbus_connection_unregister_object (manager->priv->connection,
1026 manager->priv->manager_reg_id));
1027 manager->priv->manager_reg_id = 0;
1032 g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data);
1033 while (g_hash_table_iter_next (&iter, NULL, (gpointer) &data))
1035 g_hash_table_iter_init (&iface_iter, data->map_iface_name_to_iface);
1036 while (g_hash_table_iter_next (&iface_iter, NULL, (gpointer) &iface))
1038 g_warn_if_fail (g_dbus_interface_skeleton_get_connection (iface) != NULL);
1039 g_dbus_interface_skeleton_unexport (iface);
1046 /* ---------------------------------------------------------------------------------------------------- */