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,
73 const gchar *object_path);
75 static void g_dbus_object_manager_server_emit_interfaces_removed (GDBusObjectManagerServer *manager,
76 RegistrationData *data,
77 const gchar *const *interfaces);
79 static gboolean g_dbus_object_manager_server_unexport_unlocked (GDBusObjectManagerServer *manager,
80 const gchar *object_path);
82 struct _GDBusObjectManagerServerPrivate
85 GDBusConnection *connection;
87 gchar *object_path_ending_in_slash;
88 GHashTable *map_object_path_to_data;
99 static void dbus_object_manager_interface_init (GDBusObjectManagerIface *iface);
101 G_DEFINE_TYPE_WITH_CODE (GDBusObjectManagerServer, g_dbus_object_manager_server, G_TYPE_OBJECT,
102 G_ADD_PRIVATE (GDBusObjectManagerServer)
103 G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT_MANAGER, dbus_object_manager_interface_init))
105 static void g_dbus_object_manager_server_constructed (GObject *object);
108 g_dbus_object_manager_server_finalize (GObject *object)
110 GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);
112 if (manager->priv->connection != NULL)
114 unexport_all (manager, TRUE);
115 g_object_unref (manager->priv->connection);
117 g_hash_table_unref (manager->priv->map_object_path_to_data);
118 g_free (manager->priv->object_path);
119 g_free (manager->priv->object_path_ending_in_slash);
121 g_mutex_clear (&manager->priv->lock);
123 if (G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->finalize != NULL)
124 G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->finalize (object);
128 g_dbus_object_manager_server_get_property (GObject *object,
133 GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);
137 case PROP_CONNECTION:
138 g_mutex_lock (&manager->priv->lock);
139 g_value_set_object (value, manager->priv->connection);
140 g_mutex_unlock (&manager->priv->lock);
143 case PROP_OBJECT_PATH:
144 g_value_set_string (value, g_dbus_object_manager_get_object_path (G_DBUS_OBJECT_MANAGER (manager)));
148 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
154 g_dbus_object_manager_server_set_property (GObject *object,
159 GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);
163 case PROP_CONNECTION:
164 g_dbus_object_manager_server_set_connection (manager, g_value_get_object (value));
167 case PROP_OBJECT_PATH:
168 g_assert (manager->priv->object_path == NULL);
169 g_assert (g_variant_is_object_path (g_value_get_string (value)));
170 manager->priv->object_path = g_value_dup_string (value);
171 manager->priv->object_path_ending_in_slash = g_strdup_printf ("%s/", manager->priv->object_path);
175 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
181 g_dbus_object_manager_server_class_init (GDBusObjectManagerServerClass *klass)
183 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
185 gobject_class->finalize = g_dbus_object_manager_server_finalize;
186 gobject_class->constructed = g_dbus_object_manager_server_constructed;
187 gobject_class->set_property = g_dbus_object_manager_server_set_property;
188 gobject_class->get_property = g_dbus_object_manager_server_get_property;
191 * GDBusObjectManagerServer:connection:
193 * The #GDBusConnection to export objects on.
197 g_object_class_install_property (gobject_class,
199 g_param_spec_object ("connection",
201 "The connection to export objects on",
202 G_TYPE_DBUS_CONNECTION,
205 G_PARAM_STATIC_STRINGS));
208 * GDBusObjectManagerServer:object-path:
210 * The object path to register the manager object at.
214 g_object_class_install_property (gobject_class,
216 g_param_spec_string ("object-path",
218 "The object path to register the manager object at",
222 G_PARAM_CONSTRUCT_ONLY |
223 G_PARAM_STATIC_STRINGS));
227 g_dbus_object_manager_server_init (GDBusObjectManagerServer *manager)
229 manager->priv = g_dbus_object_manager_server_get_instance_private (manager);
230 g_mutex_init (&manager->priv->lock);
231 manager->priv->map_object_path_to_data = g_hash_table_new_full (g_str_hash,
234 (GDestroyNotify) registration_data_free);
238 * g_dbus_object_manager_server_new:
239 * @object_path: The object path to export the manager object at.
241 * Creates a new #GDBusObjectManagerServer object.
243 * The returned server isn't yet exported on any connection. To do so,
244 * use g_dbus_object_manager_server_set_connection(). Normally you
245 * want to export all of your objects before doing so to avoid <ulink
246 * url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager">InterfacesAdded</ulink>
247 * signals being emitted.
249 * Returns: A #GDBusObjectManagerServer object. Free with g_object_unref().
253 GDBusObjectManagerServer *
254 g_dbus_object_manager_server_new (const gchar *object_path)
256 g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
257 return G_DBUS_OBJECT_MANAGER_SERVER (g_object_new (G_TYPE_DBUS_OBJECT_MANAGER_SERVER,
258 "object-path", object_path,
263 * g_dbus_object_manager_server_set_connection:
264 * @manager: A #GDBusObjectManagerServer.
265 * @connection: (allow-none): A #GDBusConnection or %NULL.
267 * Exports all objects managed by @manager on @connection. If
268 * @connection is %NULL, stops exporting objects.
271 g_dbus_object_manager_server_set_connection (GDBusObjectManagerServer *manager,
272 GDBusConnection *connection)
274 g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
275 g_return_if_fail (connection == NULL || G_IS_DBUS_CONNECTION (connection));
277 g_mutex_lock (&manager->priv->lock);
279 if (manager->priv->connection == connection)
281 g_mutex_unlock (&manager->priv->lock);
285 if (manager->priv->connection != NULL)
287 unexport_all (manager, FALSE);
288 g_object_unref (manager->priv->connection);
289 manager->priv->connection = NULL;
292 manager->priv->connection = connection != NULL ? g_object_ref (connection) : NULL;
293 if (manager->priv->connection != NULL)
294 export_all (manager);
296 g_mutex_unlock (&manager->priv->lock);
298 g_object_notify (G_OBJECT (manager), "connection");
304 * g_dbus_object_manager_server_get_connection:
305 * @manager: A #GDBusObjectManagerServer
307 * Gets the #GDBusConnection used by @manager.
309 * Returns: (transfer full): A #GDBusConnection object or %NULL if
310 * @manager isn't exported on a connection. The returned object should
311 * be freed with g_object_unref().
316 g_dbus_object_manager_server_get_connection (GDBusObjectManagerServer *manager)
318 GDBusConnection *ret;
319 g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), NULL);
320 g_mutex_lock (&manager->priv->lock);
321 ret = manager->priv->connection != NULL ? g_object_ref (manager->priv->connection) : NULL;
322 g_mutex_unlock (&manager->priv->lock);
326 /* ---------------------------------------------------------------------------------------------------- */
329 registration_data_export_interface (RegistrationData *data,
330 GDBusInterfaceSkeleton *interface_skeleton,
331 const gchar *object_path)
333 GDBusInterfaceInfo *info;
336 info = g_dbus_interface_skeleton_get_info (interface_skeleton);
338 if (data->manager->priv->connection != NULL)
340 if (!g_dbus_interface_skeleton_export (interface_skeleton,
341 data->manager->priv->connection,
345 g_warning ("%s: Error registering object at %s with interface %s: %s",
350 g_error_free (error);
354 g_assert (g_hash_table_lookup (data->map_iface_name_to_iface, info->name) == NULL);
355 g_hash_table_insert (data->map_iface_name_to_iface,
357 g_object_ref (interface_skeleton));
359 /* if we are already exported, then... */
362 const gchar *interfaces[2];
363 /* emit InterfacesAdded on the ObjectManager object */
364 interfaces[0] = info->name;
365 interfaces[1] = NULL;
366 g_dbus_object_manager_server_emit_interfaces_added (data->manager, data, interfaces, object_path);
371 registration_data_unexport_interface (RegistrationData *data,
372 GDBusInterfaceSkeleton *interface_skeleton)
374 GDBusInterfaceInfo *info;
375 GDBusInterfaceSkeleton *iface;
377 info = g_dbus_interface_skeleton_get_info (interface_skeleton);
378 iface = g_hash_table_lookup (data->map_iface_name_to_iface, info->name);
379 g_assert (iface != NULL);
381 if (data->manager->priv->connection != NULL)
382 g_dbus_interface_skeleton_unexport (iface);
384 g_warn_if_fail (g_hash_table_remove (data->map_iface_name_to_iface, info->name));
386 /* if we are already exported, then... */
389 const gchar *interfaces[2];
390 /* emit InterfacesRemoved on the ObjectManager object */
391 interfaces[0] = info->name;
392 interfaces[1] = NULL;
393 g_dbus_object_manager_server_emit_interfaces_removed (data->manager, data, interfaces);
397 /* ---------------------------------------------------------------------------------------------------- */
400 on_interface_added (GDBusObject *object,
401 GDBusInterface *interface,
404 RegistrationData *data = user_data;
405 const gchar *object_path;
406 g_mutex_lock (&data->manager->priv->lock);
407 object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
408 registration_data_export_interface (data, G_DBUS_INTERFACE_SKELETON (interface), object_path);
409 g_mutex_unlock (&data->manager->priv->lock);
413 on_interface_removed (GDBusObject *object,
414 GDBusInterface *interface,
417 RegistrationData *data = user_data;
418 g_mutex_lock (&data->manager->priv->lock);
419 registration_data_unexport_interface (data, G_DBUS_INTERFACE_SKELETON (interface));
420 g_mutex_unlock (&data->manager->priv->lock);
423 /* ---------------------------------------------------------------------------------------------------- */
427 registration_data_free (RegistrationData *data)
430 GDBusInterfaceSkeleton *iface;
432 data->exported = FALSE;
434 g_hash_table_iter_init (&iter, data->map_iface_name_to_iface);
435 while (g_hash_table_iter_next (&iter, NULL, (gpointer) &iface))
437 if (data->manager->priv->connection != NULL)
438 g_dbus_interface_skeleton_unexport (iface);
441 g_signal_handlers_disconnect_by_func (data->object, G_CALLBACK (on_interface_added), data);
442 g_signal_handlers_disconnect_by_func (data->object, G_CALLBACK (on_interface_removed), data);
443 g_object_unref (data->object);
444 g_hash_table_destroy (data->map_iface_name_to_iface);
448 /* ---------------------------------------------------------------------------------------------------- */
451 g_dbus_object_manager_server_export_unlocked (GDBusObjectManagerServer *manager,
452 GDBusObjectSkeleton *object,
453 const gchar *object_path)
455 RegistrationData *data;
456 GList *existing_interfaces;
458 GPtrArray *interface_names;
460 g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
461 g_return_if_fail (G_IS_DBUS_OBJECT (object));
462 g_return_if_fail (g_str_has_prefix (object_path, manager->priv->object_path_ending_in_slash));
464 interface_names = g_ptr_array_new ();
466 data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
468 g_dbus_object_manager_server_unexport_unlocked (manager, object_path);
470 data = g_new0 (RegistrationData, 1);
471 data->object = g_object_ref (object);
472 data->manager = manager;
473 data->map_iface_name_to_iface = g_hash_table_new_full (g_str_hash,
476 (GDestroyNotify) g_object_unref);
478 g_signal_connect (object,
480 G_CALLBACK (on_interface_added),
482 g_signal_connect (object,
484 G_CALLBACK (on_interface_removed),
487 /* Register all known interfaces - note that data->exported is FALSE so
488 * we don't emit any InterfacesAdded signals.
490 existing_interfaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (object));
491 for (l = existing_interfaces; l != NULL; l = l->next)
493 GDBusInterfaceSkeleton *interface_skeleton = G_DBUS_INTERFACE_SKELETON (l->data);
494 registration_data_export_interface (data, interface_skeleton, object_path);
495 g_ptr_array_add (interface_names, g_dbus_interface_skeleton_get_info (interface_skeleton)->name);
497 g_list_free_full (existing_interfaces, g_object_unref);
498 g_ptr_array_add (interface_names, NULL);
500 data->exported = TRUE;
502 /* now emit InterfacesAdded() for all the interfaces */
503 g_dbus_object_manager_server_emit_interfaces_added (manager, data, (const gchar *const *) interface_names->pdata, object_path);
504 g_ptr_array_unref (interface_names);
506 g_hash_table_insert (manager->priv->map_object_path_to_data,
507 g_strdup (object_path),
512 * g_dbus_object_manager_server_export:
513 * @manager: A #GDBusObjectManagerServer.
514 * @object: A #GDBusObjectSkeleton.
516 * Exports @object on @manager.
518 * If there is already a #GDBusObject exported at the object path,
519 * then the old object is removed.
521 * The object path for @object must be in the hierarchy rooted by the
522 * object path for @manager.
524 * Note that @manager will take a reference on @object for as long as
530 g_dbus_object_manager_server_export (GDBusObjectManagerServer *manager,
531 GDBusObjectSkeleton *object)
533 g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
534 g_mutex_lock (&manager->priv->lock);
535 g_dbus_object_manager_server_export_unlocked (manager, object,
536 g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
537 g_mutex_unlock (&manager->priv->lock);
541 * g_dbus_object_manager_server_export_uniquely:
542 * @manager: A #GDBusObjectManagerServer.
543 * @object: An object.
545 * Like g_dbus_object_manager_server_export() but appends a string of
546 * the form <literal>_N</literal> (with N being a natural number) to
547 * @object<!-- -->'s object path if an object with the given path
548 * already exists. As such, the #GDBusObjectProxy:g-object-path property
549 * of @object may be modified.
554 g_dbus_object_manager_server_export_uniquely (GDBusObjectManagerServer *manager,
555 GDBusObjectSkeleton *object)
557 gchar *orig_object_path;
562 orig_object_path = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
564 g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
565 g_return_if_fail (G_IS_DBUS_OBJECT (object));
566 g_return_if_fail (g_str_has_prefix (orig_object_path, manager->priv->object_path_ending_in_slash));
568 g_mutex_lock (&manager->priv->lock);
570 object_path = g_strdup (orig_object_path);
575 RegistrationData *data;
576 data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
581 g_free (object_path);
582 object_path = g_strdup_printf ("%s_%d", orig_object_path, count++);
586 g_dbus_object_manager_server_export_unlocked (manager, object, object_path);
588 g_mutex_unlock (&manager->priv->lock);
591 g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (object), object_path);
593 g_free (object_path);
594 g_free (orig_object_path);
599 * g_dbus_object_manager_server_is_exported:
600 * @manager: A #GDBusObjectManagerServer.
601 * @object: An object.
603 * Returns whether @object is currently exported on @manager.
605 * Returns: %TRUE if @object is exported
610 g_dbus_object_manager_server_is_exported (GDBusObjectManagerServer *manager,
611 GDBusObjectSkeleton *object)
613 RegistrationData *data = NULL;
614 const gchar *object_path;
615 gboolean object_is_exported;
617 g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), FALSE);
618 g_return_val_if_fail (G_IS_DBUS_OBJECT (object), FALSE);
620 g_mutex_lock (&manager->priv->lock);
622 object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
623 if (object_path != NULL)
624 data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
625 object_is_exported = (data != NULL);
627 g_mutex_unlock (&manager->priv->lock);
629 return object_is_exported;
632 /* ---------------------------------------------------------------------------------------------------- */
635 g_dbus_object_manager_server_unexport_unlocked (GDBusObjectManagerServer *manager,
636 const gchar *object_path)
638 RegistrationData *data;
641 g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), FALSE);
642 g_return_val_if_fail (g_variant_is_object_path (object_path), FALSE);
643 g_return_val_if_fail (g_str_has_prefix (object_path, manager->priv->object_path_ending_in_slash), FALSE);
647 data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
650 GPtrArray *interface_names;
652 const gchar *iface_name;
654 interface_names = g_ptr_array_new ();
655 g_hash_table_iter_init (&iter, data->map_iface_name_to_iface);
656 while (g_hash_table_iter_next (&iter, (gpointer) &iface_name, NULL))
657 g_ptr_array_add (interface_names, (gpointer) iface_name);
658 g_ptr_array_add (interface_names, NULL);
659 /* now emit InterfacesRemoved() for all the interfaces */
660 g_dbus_object_manager_server_emit_interfaces_removed (manager, data, (const gchar *const *) interface_names->pdata);
661 g_ptr_array_unref (interface_names);
663 g_hash_table_remove (manager->priv->map_object_path_to_data, object_path);
671 * g_dbus_object_manager_server_unexport:
672 * @manager: A #GDBusObjectManagerServer.
673 * @object_path: An object path.
675 * If @manager has an object at @path, removes the object. Otherwise
678 * Note that @object_path must be in the hierarchy rooted by the
679 * object path for @manager.
681 * Returns: %TRUE if object at @object_path was removed, %FALSE otherwise.
686 g_dbus_object_manager_server_unexport (GDBusObjectManagerServer *manager,
687 const gchar *object_path)
690 g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), FALSE);
691 g_mutex_lock (&manager->priv->lock);
692 ret = g_dbus_object_manager_server_unexport_unlocked (manager, object_path);
693 g_mutex_unlock (&manager->priv->lock);
698 /* ---------------------------------------------------------------------------------------------------- */
700 static const GDBusArgInfo manager_interfaces_added_signal_info_arg0 =
705 (GDBusAnnotationInfo**) NULL,
708 static const GDBusArgInfo manager_interfaces_added_signal_info_arg1 =
711 "interfaces_and_properties",
713 (GDBusAnnotationInfo**) NULL,
716 static const GDBusArgInfo * const manager_interfaces_added_signal_info_arg_pointers[] =
718 &manager_interfaces_added_signal_info_arg0,
719 &manager_interfaces_added_signal_info_arg1,
723 static const GDBusSignalInfo manager_interfaces_added_signal_info =
727 (GDBusArgInfo**) &manager_interfaces_added_signal_info_arg_pointers,
728 (GDBusAnnotationInfo**) NULL
733 static const GDBusArgInfo manager_interfaces_removed_signal_info_arg0 =
738 (GDBusAnnotationInfo**) NULL,
741 static const GDBusArgInfo manager_interfaces_removed_signal_info_arg1 =
746 (GDBusAnnotationInfo**) NULL,
749 static const GDBusArgInfo * const manager_interfaces_removed_signal_info_arg_pointers[] =
751 &manager_interfaces_removed_signal_info_arg0,
752 &manager_interfaces_removed_signal_info_arg1,
756 static const GDBusSignalInfo manager_interfaces_removed_signal_info =
760 (GDBusArgInfo**) &manager_interfaces_removed_signal_info_arg_pointers,
761 (GDBusAnnotationInfo**) NULL
766 static const GDBusSignalInfo * const manager_signal_info_pointers[] =
768 &manager_interfaces_added_signal_info,
769 &manager_interfaces_removed_signal_info,
775 static const GDBusArgInfo manager_get_all_method_info_out_arg0 =
778 "object_paths_interfaces_and_properties",
780 (GDBusAnnotationInfo**) NULL,
783 static const GDBusArgInfo * const manager_get_all_method_info_out_arg_pointers[] =
785 &manager_get_all_method_info_out_arg0,
789 static const GDBusMethodInfo manager_get_all_method_info =
793 (GDBusArgInfo**) NULL,
794 (GDBusArgInfo**) &manager_get_all_method_info_out_arg_pointers,
795 (GDBusAnnotationInfo**) NULL
798 static const GDBusMethodInfo * const manager_method_info_pointers[] =
800 &manager_get_all_method_info,
806 static const GDBusInterfaceInfo manager_interface_info =
809 "org.freedesktop.DBus.ObjectManager",
810 (GDBusMethodInfo **) manager_method_info_pointers,
811 (GDBusSignalInfo **) manager_signal_info_pointers,
812 (GDBusPropertyInfo **) NULL,
813 (GDBusAnnotationInfo **) NULL
817 manager_method_call (GDBusConnection *connection,
819 const gchar *object_path,
820 const gchar *interface_name,
821 const gchar *method_name,
822 GVariant *parameters,
823 GDBusMethodInvocation *invocation,
826 GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (user_data);
827 GVariantBuilder array_builder;
828 GHashTableIter object_iter;
829 RegistrationData *data;
831 g_mutex_lock (&manager->priv->lock);
833 if (g_strcmp0 (method_name, "GetManagedObjects") == 0)
835 g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a{oa{sa{sv}}}"));
836 g_hash_table_iter_init (&object_iter, manager->priv->map_object_path_to_data);
837 while (g_hash_table_iter_next (&object_iter, NULL, (gpointer) &data))
839 GVariantBuilder interfaces_builder;
840 GHashTableIter interface_iter;
841 GDBusInterfaceSkeleton *iface;
842 const gchar *iter_object_path;
844 g_variant_builder_init (&interfaces_builder, G_VARIANT_TYPE ("a{sa{sv}}"));
845 g_hash_table_iter_init (&interface_iter, data->map_iface_name_to_iface);
846 while (g_hash_table_iter_next (&interface_iter, NULL, (gpointer) &iface))
848 GVariant *properties = g_dbus_interface_skeleton_get_properties (iface);
849 g_variant_builder_add (&interfaces_builder, "{s@a{sv}}",
850 g_dbus_interface_skeleton_get_info (iface)->name,
852 g_variant_unref (properties);
854 iter_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
855 g_variant_builder_add (&array_builder,
858 &interfaces_builder);
861 g_dbus_method_invocation_return_value (invocation,
862 g_variant_new ("(a{oa{sa{sv}}})",
867 g_dbus_method_invocation_return_error (invocation,
869 G_DBUS_ERROR_UNKNOWN_METHOD,
870 "Unknown method %s - only GetManagedObjects() is supported",
873 g_mutex_unlock (&manager->priv->lock);
876 static const GDBusInterfaceVTable manager_interface_vtable =
878 manager_method_call, /* handle_method_call */
879 NULL, /* get_property */
880 NULL /* set_property */
883 /* ---------------------------------------------------------------------------------------------------- */
886 g_dbus_object_manager_server_constructed (GObject *object)
888 GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);
890 if (manager->priv->connection != NULL)
891 export_all (manager);
893 if (G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->constructed != NULL)
894 G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->constructed (object);
898 g_dbus_object_manager_server_emit_interfaces_added (GDBusObjectManagerServer *manager,
899 RegistrationData *data,
900 const gchar *const *interfaces,
901 const gchar *object_path)
903 GVariantBuilder array_builder;
907 if (data->manager->priv->connection == NULL)
910 g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a{sa{sv}}"));
911 for (n = 0; interfaces[n] != NULL; n++)
913 GDBusInterfaceSkeleton *iface;
914 GVariant *properties;
916 iface = g_hash_table_lookup (data->map_iface_name_to_iface, interfaces[n]);
917 g_assert (iface != NULL);
918 properties = g_dbus_interface_skeleton_get_properties (iface);
919 g_variant_builder_add (&array_builder, "{s@a{sv}}", interfaces[n], properties);
920 g_variant_unref (properties);
924 g_dbus_connection_emit_signal (data->manager->priv->connection,
925 NULL, /* destination_bus_name */
926 manager->priv->object_path,
927 manager_interface_info.name,
929 g_variant_new ("(oa{sa{sv}})",
933 g_assert_no_error (error);
939 g_dbus_object_manager_server_emit_interfaces_removed (GDBusObjectManagerServer *manager,
940 RegistrationData *data,
941 const gchar *const *interfaces)
943 GVariantBuilder array_builder;
946 const gchar *object_path;
948 if (data->manager->priv->connection == NULL)
951 g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("as"));
952 for (n = 0; interfaces[n] != NULL; n++)
953 g_variant_builder_add (&array_builder, "s", interfaces[n]);
956 object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
957 g_dbus_connection_emit_signal (data->manager->priv->connection,
958 NULL, /* destination_bus_name */
959 manager->priv->object_path,
960 manager_interface_info.name,
962 g_variant_new ("(oas)",
966 g_assert_no_error (error);
971 /* ---------------------------------------------------------------------------------------------------- */
974 g_dbus_object_manager_server_get_objects (GDBusObjectManager *_manager)
976 GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_manager);
979 RegistrationData *data;
981 g_mutex_lock (&manager->priv->lock);
984 g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data);
985 while (g_hash_table_iter_next (&iter, NULL, (gpointer) &data))
987 ret = g_list_prepend (ret, g_object_ref (data->object));
990 g_mutex_unlock (&manager->priv->lock);
996 g_dbus_object_manager_server_get_object_path (GDBusObjectManager *_manager)
998 GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_manager);
999 return manager->priv->object_path;
1002 static GDBusObject *
1003 g_dbus_object_manager_server_get_object (GDBusObjectManager *_manager,
1004 const gchar *object_path)
1006 GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_manager);
1008 RegistrationData *data;
1012 g_mutex_lock (&manager->priv->lock);
1013 data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
1015 ret = g_object_ref (data->object);
1016 g_mutex_unlock (&manager->priv->lock);
1021 static GDBusInterface *
1022 g_dbus_object_manager_server_get_interface (GDBusObjectManager *_manager,
1023 const gchar *object_path,
1024 const gchar *interface_name)
1026 GDBusInterface *ret;
1027 GDBusObject *object;
1031 object = g_dbus_object_manager_get_object (_manager, object_path);
1035 ret = g_dbus_object_get_interface (object, interface_name);
1036 g_object_unref (object);
1043 dbus_object_manager_interface_init (GDBusObjectManagerIface *iface)
1045 iface->get_object_path = g_dbus_object_manager_server_get_object_path;
1046 iface->get_objects = g_dbus_object_manager_server_get_objects;
1047 iface->get_object = g_dbus_object_manager_server_get_object;
1048 iface->get_interface = g_dbus_object_manager_server_get_interface;
1051 /* ---------------------------------------------------------------------------------------------------- */
1054 export_all (GDBusObjectManagerServer *manager)
1056 GHashTableIter iter;
1057 const gchar *object_path;
1058 RegistrationData *data;
1059 GHashTableIter iface_iter;
1060 GDBusInterfaceSkeleton *iface;
1063 g_return_if_fail (manager->priv->connection != NULL);
1066 g_warn_if_fail (manager->priv->manager_reg_id == 0);
1067 manager->priv->manager_reg_id = g_dbus_connection_register_object (manager->priv->connection,
1068 manager->priv->object_path,
1069 (GDBusInterfaceInfo *) &manager_interface_info,
1070 &manager_interface_vtable,
1072 NULL, /* user_data_free_func */
1074 if (manager->priv->manager_reg_id == 0)
1076 g_warning ("%s: Error registering manager at %s: %s",
1078 manager->priv->object_path,
1080 g_error_free (error);
1083 g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data);
1084 while (g_hash_table_iter_next (&iter, (gpointer) &object_path, (gpointer) &data))
1086 g_hash_table_iter_init (&iface_iter, data->map_iface_name_to_iface);
1087 while (g_hash_table_iter_next (&iface_iter, NULL, (gpointer) &iface))
1089 g_warn_if_fail (g_dbus_interface_skeleton_get_connection (iface) == NULL);
1091 if (!g_dbus_interface_skeleton_export (iface,
1092 manager->priv->connection,
1096 g_warning ("%s: Error registering object at %s with interface %s: %s",
1099 g_dbus_interface_skeleton_get_info (iface)->name,
1101 g_error_free (error);
1108 unexport_all (GDBusObjectManagerServer *manager, gboolean only_manager)
1110 GHashTableIter iter;
1111 RegistrationData *data;
1112 GHashTableIter iface_iter;
1113 GDBusInterfaceSkeleton *iface;
1115 g_return_if_fail (manager->priv->connection != NULL);
1117 g_warn_if_fail (manager->priv->manager_reg_id > 0);
1118 if (manager->priv->manager_reg_id > 0)
1120 g_warn_if_fail (g_dbus_connection_unregister_object (manager->priv->connection,
1121 manager->priv->manager_reg_id));
1122 manager->priv->manager_reg_id = 0;
1127 g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data);
1128 while (g_hash_table_iter_next (&iter, NULL, (gpointer) &data))
1130 g_hash_table_iter_init (&iface_iter, data->map_iface_name_to_iface);
1131 while (g_hash_table_iter_next (&iface_iter, NULL, (gpointer) &iface))
1133 g_warn_if_fail (g_dbus_interface_skeleton_get_connection (iface) != NULL);
1134 g_dbus_interface_skeleton_unexport (iface);
1141 /* ---------------------------------------------------------------------------------------------------- */