diff options
author | Tomas Bzatek <tbzatek@redhat.com> | 2011-05-18 13:56:58 +0200 |
---|---|---|
committer | Tomas Bzatek <tbzatek@redhat.com> | 2012-06-04 17:43:50 +0200 |
commit | 8315eaf84e52c6a00a4905f1f6a73182db9e8015 (patch) | |
tree | dc7e1566001c9f4ae07e35c9fd0e531afe5e0fd6 | |
parent | cc34b3774e6ce80551babf20c7d5dfabd9d2ed24 (diff) | |
download | gvfs-8315eaf84e52c6a00a4905f1f6a73182db9e8015.tar.gz |
Port volume monitoring and metadata to GDBus
This is a complete port of volume monitors and metadata to GDBus.
The (private) d-bus API has been mostly preserved except of
MountOp methods.
No difference in functionality should be observed.
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | client/gdaemonfile.c | 72 | ||||
-rw-r--r-- | client/gdaemonvfs.c | 273 | ||||
-rw-r--r-- | client/gdaemonvfs.h | 6 | ||||
-rw-r--r-- | metadata/Makefile.am | 25 | ||||
-rw-r--r-- | metadata/dbus-interface.xml | 57 | ||||
-rw-r--r-- | metadata/meta-daemon.c | 683 | ||||
-rw-r--r-- | metadata/meta-set.c | 139 | ||||
-rw-r--r-- | monitor/afc/Makefile.am | 1 | ||||
-rw-r--r-- | monitor/gdu/Makefile.am | 2 | ||||
-rw-r--r-- | monitor/proxy/Makefile.am | 30 | ||||
-rw-r--r-- | monitor/proxy/dbus-interfaces.xml | 176 | ||||
-rw-r--r-- | monitor/proxy/gproxydrive.c | 484 | ||||
-rw-r--r-- | monitor/proxy/gproxydrive.h | 14 | ||||
-rw-r--r-- | monitor/proxy/gproxymount.c | 188 | ||||
-rw-r--r-- | monitor/proxy/gproxymount.h | 2 | ||||
-rw-r--r-- | monitor/proxy/gproxymountoperation.c | 235 | ||||
-rw-r--r-- | monitor/proxy/gproxymountoperation.h | 27 | ||||
-rw-r--r-- | monitor/proxy/gproxyshadowmount.c | 2 | ||||
-rw-r--r-- | monitor/proxy/gproxyvolume.c | 183 | ||||
-rw-r--r-- | monitor/proxy/gproxyvolume.h | 2 | ||||
-rw-r--r-- | monitor/proxy/gproxyvolumemonitor.c | 1212 | ||||
-rw-r--r-- | monitor/proxy/gproxyvolumemonitor.h | 17 | ||||
-rw-r--r-- | monitor/proxy/gvfsproxyvolumemonitordaemon.c | 1549 |
24 files changed, 2618 insertions, 2763 deletions
@@ -38,3 +38,5 @@ gtk-doc.make *-marshal.[ch] *.gschema.valid *.enums.xml +monitor/proxy/gvfsvolumemonitordbus.* +metadata/metadata-dbus.* diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c index 15c368c8..5ab98d66 100644 --- a/client/gdaemonfile.c +++ b/client/gdaemonfile.c @@ -29,6 +29,7 @@ #include <sys/socket.h> #include "gdaemonfile.h" +#include "gdaemonvfs.h" #include "gvfsdaemondbus.h" #include "gdaemonmount.h" #include <gvfsdaemonprotocol.h> @@ -41,6 +42,7 @@ #include "gmountoperationdbus.h" #include <gio/gio.h> #include "metatree.h" +#include <metadata-dbus.h> static void g_daemon_file_file_iface_init (GFileIface *iface); @@ -2215,53 +2217,57 @@ set_metadata_attribute (GFile *file, GError **error) { GDaemonFile *daemon_file; - DBusMessage *message; char *treename; const char *metatreefile; MetaTree *tree; int appended; gboolean res; + GVfsMetadata *proxy; + GVariantBuilder *builder; daemon_file = G_DAEMON_FILE (file); treename = g_mount_spec_to_string (daemon_file->mount_spec); tree = meta_tree_lookup_by_name (treename, FALSE); g_free (treename); + + res = FALSE; + proxy = _g_daemon_vfs_get_metadata_proxy (cancellable, error); - message = - dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME, - G_VFS_DBUS_METADATA_PATH, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_SET); - g_assert (message != NULL); - metatreefile = meta_tree_get_filename (tree); - _g_dbus_message_append_args (message, - G_DBUS_TYPE_CSTRING, &metatreefile, - G_DBUS_TYPE_CSTRING, &daemon_file->path, - 0); - - appended = _g_daemon_vfs_append_metadata_for_set (message, - tree, - daemon_file->path, - attribute, - type, - value); - - res = TRUE; - if (appended == -1) + if (proxy) { - res = FALSE; - g_set_error (error, G_IO_ERROR, - G_IO_ERROR_INVALID_ARGUMENT, - _("Error setting file metadata: %s"), - _("values must be string or list of strings")); - } - else if (appended > 0 && - !_g_daemon_vfs_send_message_sync (message, - cancellable, error)) - res = FALSE; + builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); - dbus_message_unref (message); + metatreefile = meta_tree_get_filename (tree); + + appended = _g_daemon_vfs_append_metadata_for_set (builder, + tree, + daemon_file->path, + attribute, + type, + value); + + res = TRUE; + if (appended == -1) + { + res = FALSE; + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error setting file metadata: %s"), + _("values must be string or list of strings")); + } + else if (appended > 0 && + !gvfs_metadata_call_set_sync (proxy, + metatreefile, + daemon_file->path, + g_variant_builder_end (builder), + cancellable, + error)) + res = FALSE; + + g_variant_builder_unref (builder); + g_object_unref (proxy); + } meta_tree_unref (tree); diff --git a/client/gdaemonvfs.c b/client/gdaemonvfs.c index e62da9b8..c1315450 100644 --- a/client/gdaemonvfs.c +++ b/client/gdaemonvfs.c @@ -77,6 +77,9 @@ G_DEFINE_DYNAMIC_TYPE (GDaemonVfs, g_daemon_vfs, G_TYPE_VFS) static GDaemonVfs *the_vfs = NULL; +G_LOCK_DEFINE_STATIC (metadata_proxy); +static GVfsMetadata *metadata_proxy = NULL; + G_LOCK_DEFINE_STATIC(mount_cache); @@ -1170,19 +1173,6 @@ g_daemon_vfs_add_writable_namespaces (GVfs *vfs, G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED); } -static void -send_message_oneway (DBusMessage *message) -{ - DBusConnection *connection; - - connection = _g_dbus_connection_get_sync (NULL, NULL); - if (connection == NULL) - return; - - dbus_connection_send (connection, message, NULL); - dbus_connection_flush (connection); -} - /* Sends a message on the session bus and blocks for the reply, using the thread local connection */ gboolean @@ -1239,7 +1229,7 @@ strv_equal (char **a, char **b) /* -1 => error, otherwise number of added items */ int -_g_daemon_vfs_append_metadata_for_set (DBusMessage *message, +_g_daemon_vfs_append_metadata_for_set (GVariantBuilder *builder, MetaTree *tree, const char *path, const char *attribute, @@ -1261,10 +1251,7 @@ _g_daemon_vfs_append_metadata_for_set (DBusMessage *message, if (current == NULL || strcmp (current, val) != 0) { res = 1; - _g_dbus_message_append_args (message, - DBUS_TYPE_STRING, &key, - DBUS_TYPE_STRING, &val, - 0); + g_variant_builder_add (builder, "{sv}", key, g_variant_new_string (val)); } g_free (current); } @@ -1276,10 +1263,7 @@ _g_daemon_vfs_append_metadata_for_set (DBusMessage *message, if (current == NULL || !strv_equal (current, val)) { res = 1; - _g_dbus_message_append_args (message, - DBUS_TYPE_STRING, &key, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &val, g_strv_length (val), - 0); + g_variant_builder_add (builder, "{sv}", key, g_variant_new_strv ((const gchar * const *) val, -1)); } g_strfreev (current); } @@ -1290,10 +1274,7 @@ _g_daemon_vfs_append_metadata_for_set (DBusMessage *message, char c = 0; res = 1; /* Byte => unset */ - _g_dbus_message_append_args (message, - DBUS_TYPE_STRING, &key, - DBUS_TYPE_BYTE, &c, - 0); + g_variant_builder_add (builder, "{sv}", key, g_variant_new_byte (c)); } } else @@ -1302,6 +1283,62 @@ _g_daemon_vfs_append_metadata_for_set (DBusMessage *message, return res; } +static void +metadata_daemon_vanished (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + guint *watcher_id = user_data; + + G_LOCK (metadata_proxy); + g_clear_object (&metadata_proxy); + G_UNLOCK (metadata_proxy); + + if (*watcher_id > 0) + g_bus_unwatch_name (*watcher_id); +} + +GVfsMetadata * +_g_daemon_vfs_get_metadata_proxy (GCancellable *cancellable, GError **error) +{ + GVfsMetadata *proxy; + guint *watcher_id; + + G_LOCK (metadata_proxy); + + proxy = NULL; + if (metadata_proxy == NULL) + { + metadata_proxy = gvfs_metadata_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + G_VFS_DBUS_METADATA_NAME, + G_VFS_DBUS_METADATA_PATH, + cancellable, + error); + + if (proxy != NULL) + { + /* a place in memory to store the returned ID in */ + watcher_id = g_malloc0 (sizeof (guint)); + *watcher_id = g_bus_watch_name_on_connection (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)), + G_VFS_DBUS_METADATA_NAME, + G_BUS_NAME_WATCHER_FLAGS_AUTO_START, + NULL, + metadata_daemon_vanished, + watcher_id, + g_free); + } + } + + if (metadata_proxy != NULL) + /* take the reference so that we don't need to protect returned object against racy metadata_daemon_vanished() */ + proxy = g_object_ref (metadata_proxy); + + G_UNLOCK (metadata_proxy); + + return proxy; +} + static gboolean g_daemon_vfs_local_file_set_attributes (GVfs *vfs, const char *filename, @@ -1319,10 +1356,11 @@ g_daemon_vfs_local_file_set_attributes (GVfs *vfs, MetaTree *tree; int errsv; int i, num_set; - DBusMessage *message; gboolean res; int appended; gpointer value; + GVfsMetadata *proxy; + GVariantBuilder *builder; res = TRUE; if (g_file_info_has_namespace (info, "metadata")) @@ -1352,65 +1390,71 @@ g_daemon_vfs_local_file_set_attributes (GVfs *vfs, statbuf.st_dev, FALSE, &tree_path); - message = - dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME, - G_VFS_DBUS_METADATA_PATH, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_SET); - g_assert (message != NULL); - metatreefile = meta_tree_get_filename (tree); - _g_dbus_message_append_args (message, - G_DBUS_TYPE_CSTRING, &metatreefile, - G_DBUS_TYPE_CSTRING, &tree_path, - 0); - meta_lookup_cache_free (cache); - - num_set = 0; - for (i = 0; attributes[i] != NULL; i++) + + proxy = _g_daemon_vfs_get_metadata_proxy (NULL, error); + if (proxy == NULL) { - if (g_file_info_get_attribute_data (info, attributes[i], &type, &value, NULL)) - { - appended = _g_daemon_vfs_append_metadata_for_set (message, - tree, - tree_path, - attributes[i], - type, - value); - if (appended != -1) - { - num_set += appended; - g_file_info_set_attribute_status (info, attributes[i], - G_FILE_ATTRIBUTE_STATUS_SET); - } - else - { - res = FALSE; - g_set_error (error, G_IO_ERROR, - G_IO_ERROR_INVALID_ARGUMENT, - _("Error setting file metadata: %s"), - _("values must be string or list of strings")); - error = NULL; /* Don't set further errors */ - g_file_info_set_attribute_status (info, attributes[i], - G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING); - } - } + res = FALSE; + error = NULL; /* Don't set further errors */ } - - meta_tree_unref (tree); - g_free (tree_path); - - if (num_set > 0 && - !_g_daemon_vfs_send_message_sync (message, - cancellable, error)) + else { - res = FALSE; - error = NULL; /* Don't set further errors */ - for (i = 0; attributes[i] != NULL; i++) - g_file_info_set_attribute_status (info, attributes[i], - G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING); + builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + metatreefile = meta_tree_get_filename (tree); + num_set = 0; + + for (i = 0; attributes[i] != NULL; i++) + { + if (g_file_info_get_attribute_data (info, attributes[i], &type, &value, NULL)) + { + appended = _g_daemon_vfs_append_metadata_for_set (builder, + tree, + tree_path, + attributes[i], + type, + value); + if (appended != -1) + { + num_set += appended; + g_file_info_set_attribute_status (info, attributes[i], + G_FILE_ATTRIBUTE_STATUS_SET); + } + else + { + res = FALSE; + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error setting file metadata: %s"), + _("values must be string or list of strings")); + error = NULL; /* Don't set further errors */ + g_file_info_set_attribute_status (info, attributes[i], + G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING); + } + } + } + + if (num_set > 0 && + ! gvfs_metadata_call_set_sync (proxy, + metatreefile, + tree_path, + g_variant_builder_end (builder), + NULL, + error)) + { + res = FALSE; + error = NULL; /* Don't set further errors */ + for (i = 0; attributes[i] != NULL; i++) + g_file_info_set_attribute_status (info, attributes[i], + G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING); + } + + g_variant_builder_unref (builder); + + meta_lookup_cache_free (cache); + meta_tree_unref (tree); + g_free (tree_path); + g_object_unref (proxy); } - - dbus_message_unref (message); } g_strfreev (attributes); @@ -1424,10 +1468,10 @@ g_daemon_vfs_local_file_removed (GVfs *vfs, const char *filename) { MetaLookupCache *cache; - DBusMessage *message; const char *metatreefile; MetaTree *tree; char *tree_path; + GVfsMetadata *proxy; cache = meta_lookup_cache_new (); tree = meta_lookup_cache_lookup_path (cache, @@ -1437,19 +1481,23 @@ g_daemon_vfs_local_file_removed (GVfs *vfs, &tree_path); if (tree) { - message = - dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME, - G_VFS_DBUS_METADATA_PATH, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_REMOVE); - g_assert (message != NULL); - metatreefile = meta_tree_get_filename (tree); - _g_dbus_message_append_args (message, - G_DBUS_TYPE_CSTRING, &metatreefile, - G_DBUS_TYPE_CSTRING, &tree_path, - 0); - send_message_oneway (message); - dbus_message_unref (message); + proxy = _g_daemon_vfs_get_metadata_proxy (NULL, NULL); + if (proxy) + { + metatreefile = meta_tree_get_filename (tree); + /* we don't care about the result, let's queue the call and don't block */ + gvfs_metadata_call_remove (proxy, + metatreefile, + tree_path, + NULL, + NULL, /* callback */ + NULL); + /* flush the call with the expense of sending all queued messages on the connection */ + g_dbus_connection_flush_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)), + NULL, NULL); + g_object_unref (proxy); + } + meta_tree_unref (tree); g_free (tree_path); } @@ -1463,10 +1511,10 @@ g_daemon_vfs_local_file_moved (GVfs *vfs, const char *dest) { MetaLookupCache *cache; - DBusMessage *message; const char *metatreefile; MetaTree *tree1, *tree2; char *tree_path1, *tree_path2; + GVfsMetadata *proxy; cache = meta_lookup_cache_new (); tree1 = meta_lookup_cache_lookup_path (cache, @@ -1481,20 +1529,23 @@ g_daemon_vfs_local_file_moved (GVfs *vfs, &tree_path2); if (tree1 && tree2 && tree1 == tree2) { - message = - dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME, - G_VFS_DBUS_METADATA_PATH, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_MOVE); - g_assert (message != NULL); - metatreefile = meta_tree_get_filename (tree1); - _g_dbus_message_append_args (message, - G_DBUS_TYPE_CSTRING, &metatreefile, - G_DBUS_TYPE_CSTRING, &tree_path1, - G_DBUS_TYPE_CSTRING, &tree_path2, - 0); - send_message_oneway (message); - dbus_message_unref (message); + proxy = _g_daemon_vfs_get_metadata_proxy (NULL, NULL); + if (proxy) + { + metatreefile = meta_tree_get_filename (tree1); + /* we don't care about the result, let's queue the call and don't block */ + gvfs_metadata_call_move (proxy, + metatreefile, + tree_path1, + tree_path2, + NULL, + NULL, /* callback */ + NULL); + /* flush the call with the expense of sending all queued messages on the connection */ + g_dbus_connection_flush_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)), + NULL, NULL); + g_object_unref (proxy); + } } if (tree1) diff --git a/client/gdaemonvfs.h b/client/gdaemonvfs.h index 16d01a70..f96ab89a 100644 --- a/client/gdaemonvfs.h +++ b/client/gdaemonvfs.h @@ -29,6 +29,7 @@ #include "gmounttracker.h" #include "gvfsuriutils.h" #include <metatree.h> +#include <metadata-dbus.h> G_BEGIN_DECLS @@ -71,13 +72,16 @@ DBusConnection *_g_daemon_vfs_get_async_bus (void); gboolean _g_daemon_vfs_send_message_sync (DBusMessage *message, GCancellable *cancellable, GError **error); -int _g_daemon_vfs_append_metadata_for_set (DBusMessage *message, +int _g_daemon_vfs_append_metadata_for_set (GVariantBuilder *builder, MetaTree *tree, const char *path, const char *attribute, GFileAttributeType type, gpointer value); +GVfsMetadata * _g_daemon_vfs_get_metadata_proxy (GCancellable *cancellable, + GError **error); + G_END_DECLS diff --git a/metadata/Makefile.am b/metadata/Makefile.am index d3f25be3..4bf2d04e 100644 --- a/metadata/Makefile.am +++ b/metadata/Makefile.am @@ -1,5 +1,16 @@ NULL = +dbus_built_sources = metadata-dbus.c metadata-dbus.h +BUILT_SOURCES = $(dbus_built_sources) + +$(dbus_built_sources) : Makefile.am dbus-interface.xml + gdbus-codegen \ + --interface-prefix org.gtk.vfs. \ + --c-namespace GVfs \ + --generate-c-code metadata-dbus \ + dbus-interface.xml \ + $(NULL) + noinst_LTLIBRARIES=libmetadata.la APPS = \ @@ -30,6 +41,7 @@ libmetadata_la_SOURCES = \ metatree.c metatree.h \ metabuilder.c metabuilder.h \ crc32.c crc32.h \ + $(dbus_built_sources) \ $(NULL) libmetadata_la_LIBADD = $(GLIB_LIBS) $(UDEV_LIBS) @@ -37,7 +49,7 @@ libmetadata_la_LIBADD = $(GLIB_LIBS) $(UDEV_LIBS) meta_ls_LDADD = libmetadata.la meta_ls_SOURCES = meta-ls.c -meta_set_LDADD = libmetadata.la $(DBUS_LIBS) ../common/libgvfscommon.la +meta_set_LDADD = libmetadata.la ../common/libgvfscommon.la meta_set_SOURCES = meta-set.c meta_get_LDADD = libmetadata.la @@ -49,7 +61,7 @@ meta_get_tree_SOURCES = meta-get-tree.c convert_nautilus_metadata_LDADD = libmetadata.la $(LIBXML_LIBS) convert_nautilus_metadata_SOURCES = metadata-nautilus.c -gvfsd_metadata_LDADD = libmetadata.la $(DBUS_LIBS) ../common/libgvfscommon.la +gvfsd_metadata_LDADD = libmetadata.la ../common/libgvfscommon.la gvfsd_metadata_SOURCES = meta-daemon.c # D-BUS service file @@ -60,7 +72,14 @@ servicedir = $(DBUS_SERVICE_DIR) service_in_files = gvfs-metadata.service.in service_DATA = gvfs-metadata.service -EXTRA_DIST = gvfs-metadata.service.in +EXTRA_DIST = \ + gvfs-metadata.service.in \ + dbus-interface.xml \ + $(NULL) clean-local: rm -f gvfs-metadata.service + +CLEANFILES = \ + $(dbus_built_sources) \ + $(NULL) diff --git a/metadata/dbus-interface.xml b/metadata/dbus-interface.xml new file mode 100644 index 00000000..f4d8af83 --- /dev/null +++ b/metadata/dbus-interface.xml @@ -0,0 +1,57 @@ +<!DOCTYPE node PUBLIC +"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> + +<!-- + Copyright (C) 2011 Red Hat, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307, USA. + + Author: Tomas Bzatek <tbzatek@redhat.com> +--> + +<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd"> + <interface name='org.gtk.vfs.Metadata'> + + <method name="Set"> + <arg type='ay' name='treefile' direction='in'/> + <arg type='ay' name='path' direction='in'/> + <arg type='a{sv}' name='data' direction='in'/> + </method> + <method name="Unset"> + <arg type='ay' name='treefile' direction='in'/> + <arg type='ay' name='path' direction='in'/> + <arg type='s' name='key' direction='in'/> + </method> + <method name="Get"> + <arg type='ay' name='treefile' direction='in'/> + <arg type='ay' name='path' direction='in'/> + <arg type='as' name='keys' direction='in'/> + <arg type='a{sv}' name='data' direction='out'/> + </method> + <method name="Remove"> + <arg type='ay' name='treefile' direction='in'/> + <arg type='ay' name='path' direction='in'/> + </method> + <method name="Move"> + <arg type='ay' name='treefile' direction='in'/> + <arg type='ay' name='path' direction='in'/> + <arg type='ay' name='dest_path' direction='in'/> + </method> + + </interface> +</node> + diff --git a/metadata/meta-daemon.c b/metadata/meta-daemon.c index 0e21696b..9c102a56 100644 --- a/metadata/meta-daemon.c +++ b/metadata/meta-daemon.c @@ -27,10 +27,11 @@ #include <glib/gstdio.h> #include <locale.h> #include <stdlib.h> +/* TODO: remove + remove traces in Makefile.am */ #include <dbus/dbus.h> -#include "gvfsdbusutils.h" #include "metatree.h" #include "gvfsdaemonprotocol.h" +#include "metadata-dbus.h" #define WRITEOUT_TIMEOUT_SECS 60 @@ -41,6 +42,7 @@ typedef struct { } TreeInfo; static GHashTable *tree_infos = NULL; +static GVfsMetadata *skeleton = NULL; static void tree_info_free (TreeInfo *info) @@ -109,174 +111,90 @@ tree_info_lookup (const char *filename) } static gboolean -metadata_set (const char *treefile, - const char *path, - DBusMessageIter *iter, - DBusError *derror) +handle_set (GVfsMetadata *object, + GDBusMethodInvocation *invocation, + const gchar *arg_treefile, + const gchar *arg_path, + GVariant *arg_data, + GVfsMetadata *daemon) { TreeInfo *info; - const char *str; - char **strv; - gboolean res; - const char *key; - int n_elements; - char c; + const gchar *str; + const gchar **strv; + const gchar *key; + GError *error; + GVariantIter iter; + GVariant *value; - info = tree_info_lookup (treefile); + info = tree_info_lookup (arg_treefile); if (info == NULL) { - dbus_set_error (derror, - DBUS_ERROR_FILE_NOT_FOUND, - _("Can't find metadata file %s"), - treefile); - return FALSE; + g_dbus_method_invocation_return_error (invocation, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + _("Can't find metadata file %s"), + arg_treefile); + return TRUE; } - res = TRUE; - while (dbus_message_iter_get_arg_type (iter) != 0) - { - if (!_g_dbus_message_iter_get_args (iter, derror, - DBUS_TYPE_STRING, &key, - 0)) - { - res = FALSE; - break; - } + error = NULL; - if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY) + g_variant_iter_init (&iter, arg_data); + while (g_variant_iter_next (&iter, "{&sv}", &key, &value)) + { + if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING_ARRAY)) { /* stringv */ - if (!_g_dbus_message_iter_get_args (iter, derror, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &strv, &n_elements, - 0)) + strv = g_variant_get_strv (value, NULL); + if (!meta_tree_set_stringv (info->tree, arg_path, key, (gchar **) strv)) { - res = FALSE; - break; + g_set_error_literal (&error, G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unable to set metadata key")); } - if (!meta_tree_set_stringv (info->tree, path, key, strv)) - { - dbus_set_error (derror, - DBUS_ERROR_FAILED, - _("Unable to set metadata key")); - res = FALSE; - } - g_strfreev (strv); + g_free (strv); } - else if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING) + else if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) { /* string */ - if (!_g_dbus_message_iter_get_args (iter, derror, - DBUS_TYPE_STRING, &str, - 0)) - { - res = FALSE; - break; - } - if (!meta_tree_set_string (info->tree, path, key, str)) + str = g_variant_get_string (value, NULL); + if (!meta_tree_set_string (info->tree, arg_path, key, str)) { - dbus_set_error (derror, - DBUS_ERROR_FAILED, - _("Unable to set metadata key")); - res = FALSE; + g_set_error_literal (&error, G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unable to set metadata key")); } } - else if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_BYTE) + else if (g_variant_is_of_type (value, G_VARIANT_TYPE_BYTE)) { /* Unset */ - if (!_g_dbus_message_iter_get_args (iter, derror, - DBUS_TYPE_BYTE, &c, - 0)) + if (!meta_tree_unset (info->tree, arg_path, key)) { - res = FALSE; - break; - } - if (!meta_tree_unset (info->tree, path, key)) - { - dbus_set_error (derror, - DBUS_ERROR_FAILED, - _("Unable to unset metadata key")); - res = FALSE; + g_set_error_literal (&error, G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unable to unset metadata key")); } } + g_variant_unref (value); } tree_info_schedule_writeout (info); - return res; -} - -static void -append_string (DBusMessageIter *iter, - const char *key, - const char *string) -{ - DBusMessageIter variant_iter, struct_iter; - - if (!dbus_message_iter_open_container (iter, - DBUS_TYPE_STRUCT, - NULL, - &struct_iter)) - _g_dbus_oom (); - - if (!dbus_message_iter_append_basic (&struct_iter, - DBUS_TYPE_STRING, - &key)) - _g_dbus_oom (); - - if (!dbus_message_iter_open_container (&struct_iter, - DBUS_TYPE_VARIANT, - DBUS_TYPE_STRING_AS_STRING, - &variant_iter)) - _g_dbus_oom (); - - if (!dbus_message_iter_append_basic (&variant_iter, - DBUS_TYPE_STRING, &string)) - _g_dbus_oom (); - - if (!dbus_message_iter_close_container (&struct_iter, &variant_iter)) - _g_dbus_oom (); - - if (!dbus_message_iter_close_container (iter, &struct_iter)) - _g_dbus_oom (); -} - -static void -append_stringv (DBusMessageIter *iter, - const char *key, - char **stringv) -{ - DBusMessageIter variant_iter, struct_iter; - - if (!dbus_message_iter_open_container (iter, - DBUS_TYPE_STRUCT, - NULL, - &struct_iter)) - _g_dbus_oom (); - - if (!dbus_message_iter_append_basic (&struct_iter, - DBUS_TYPE_STRING, - &key)) - _g_dbus_oom (); - - if (!dbus_message_iter_open_container (&struct_iter, - DBUS_TYPE_VARIANT, - DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, - &variant_iter)) - _g_dbus_oom (); - - _g_dbus_message_iter_append_args (&variant_iter, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &stringv, g_strv_length (stringv), - 0); - - if (!dbus_message_iter_close_container (&struct_iter, &variant_iter)) - _g_dbus_oom (); - - if (!dbus_message_iter_close_container (iter, &struct_iter)) - _g_dbus_oom (); + if (error) + { + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + } + else + { + gvfs_metadata_complete_set (object, invocation); + } + + return TRUE; } static void -append_key (DBusMessageIter *iter, +append_key (GVariantBuilder *builder, MetaTree *tree, const char *path, const char *key) @@ -290,13 +208,13 @@ append_key (DBusMessageIter *iter, if (keytype == META_KEY_TYPE_STRING) { str = meta_tree_lookup_string (tree, path, key); - append_string (iter, key, str); + g_variant_builder_add (builder, "{sv}", key, g_variant_new_string (str)); g_free (str); } else if (keytype == META_KEY_TYPE_STRINGV) { strv = meta_tree_lookup_stringv (tree, path, key); - append_stringv (iter, key, strv); + g_variant_builder_add (builder, "{sv}", key, g_variant_new_strv ((const gchar * const *) strv, -1)); g_strfreev (strv); } } @@ -313,382 +231,217 @@ enum_keys (const char *key, return TRUE; } -static DBusMessage * -metadata_get (const char *treefile, - const char *path, - DBusMessage *message, - DBusMessageIter *iter, - DBusError *derror) +static gboolean +handle_get (GVfsMetadata *object, + GDBusMethodInvocation *invocation, + const gchar *arg_treefile, + const gchar *arg_path, + const gchar *const *arg_keys, + GVfsMetadata *daemon) { TreeInfo *info; - char *key; - DBusMessage *reply; - DBusMessageIter reply_iter; - GPtrArray *keys; - int i; + GPtrArray *meta_keys; gboolean free_keys; + gchar **iter_keys; + gchar **i; + GVariantBuilder *builder; - info = tree_info_lookup (treefile); + info = tree_info_lookup (arg_treefile); if (info == NULL) { - dbus_set_error (derror, - DBUS_ERROR_FILE_NOT_FOUND, - _("Can't find metadata file %s"), - treefile); - return NULL; + g_dbus_method_invocation_return_error (invocation, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + _("Can't find metadata file %s"), + arg_treefile); + return TRUE; } - reply = dbus_message_new_method_return (message); - dbus_message_iter_init_append (reply, &reply_iter); - - keys = g_ptr_array_new (); - if (dbus_message_iter_get_arg_type (iter) == 0) + if (arg_keys == NULL) { /* Get all keys */ free_keys = TRUE; - meta_tree_enumerate_keys (info->tree, path, enum_keys, keys); + meta_keys = g_ptr_array_new (); + meta_tree_enumerate_keys (info->tree, arg_path, enum_keys, meta_keys); + iter_keys = (gchar **) g_ptr_array_free (meta_keys, FALSE); } else { free_keys = FALSE; - while (dbus_message_iter_get_arg_type (iter) != 0) - { - if (!_g_dbus_message_iter_get_args (iter, derror, - DBUS_TYPE_STRING, &key, - 0)) - break; - - g_ptr_array_add (keys, key); - } + iter_keys = (gchar **) arg_keys; } - for (i = 0; i < keys->len; i++) - { - key = g_ptr_array_index (keys, i); - append_key (&reply_iter, info->tree, path, key); - if (free_keys) - g_free (key); - } - g_ptr_array_free (keys, TRUE); + builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + + for (i = iter_keys; *i; i++) + append_key (builder, info->tree, arg_path, *i); + if (free_keys) + g_strfreev (iter_keys); + + gvfs_metadata_complete_get (object, invocation, + g_variant_builder_end (builder)); + g_variant_builder_unref (builder); - return reply; + return TRUE; } static gboolean -metadata_unset (const char *treefile, - const char *path, - const char *key, - DBusError *derror) +handle_unset (GVfsMetadata *object, + GDBusMethodInvocation *invocation, + const gchar *arg_treefile, + const gchar *arg_path, + const gchar *arg_key, + GVfsMetadata *daemon) { TreeInfo *info; - info = tree_info_lookup (treefile); + info = tree_info_lookup (arg_treefile); if (info == NULL) { - dbus_set_error (derror, - DBUS_ERROR_FILE_NOT_FOUND, - _("Can't find metadata file %s"), - treefile); - return FALSE; + g_dbus_method_invocation_return_error (invocation, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + _("Can't find metadata file %s"), + arg_treefile); + return TRUE; } - if (!meta_tree_unset (info->tree, path, key)) + if (!meta_tree_unset (info->tree, arg_path, arg_key)) { - dbus_set_error (derror, - DBUS_ERROR_FAILED, - _("Unable to unset metadata key")); - return FALSE; + g_dbus_method_invocation_return_error_literal (invocation, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unable to unset metadata key")); + return TRUE; } tree_info_schedule_writeout (info); + gvfs_metadata_complete_unset (object, invocation); + return TRUE; } static gboolean -metadata_remove (const char *treefile, - const char *path, - DBusError *derror) +handle_remove (GVfsMetadata *object, + GDBusMethodInvocation *invocation, + const gchar *arg_treefile, + const gchar *arg_path, + GVfsMetadata *daemon) { TreeInfo *info; - info = tree_info_lookup (treefile); + info = tree_info_lookup (arg_treefile); if (info == NULL) { - dbus_set_error (derror, - DBUS_ERROR_FILE_NOT_FOUND, - _("Can't find metadata file %s"), - treefile); - return FALSE; + g_dbus_method_invocation_return_error (invocation, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + _("Can't find metadata file %s"), + arg_treefile); + return TRUE; } - if (!meta_tree_remove (info->tree, path)) + if (!meta_tree_remove (info->tree, arg_path)) { - dbus_set_error (derror, - DBUS_ERROR_FAILED, - _("Unable to remove metadata keys")); - return FALSE; + g_dbus_method_invocation_return_error_literal (invocation, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unable to remove metadata keys")); + return TRUE; } tree_info_schedule_writeout (info); + gvfs_metadata_complete_remove (object, invocation); + return TRUE; } static gboolean -metadata_move (const char *treefile, - const char *src_path, - const char *dest_path, - DBusError *derror) +handle_move (GVfsMetadata *object, + GDBusMethodInvocation *invocation, + const gchar *arg_treefile, + const gchar *arg_path, + const gchar *arg_dest_path, + GVfsMetadata *daemon) { TreeInfo *info; - info = tree_info_lookup (treefile); + info = tree_info_lookup (arg_treefile); if (info == NULL) { - dbus_set_error (derror, - DBUS_ERROR_FILE_NOT_FOUND, - _("Can't find metadata file %s"), - treefile); - return FALSE; + g_dbus_method_invocation_return_error (invocation, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + _("Can't find metadata file %s"), + arg_treefile); + return TRUE; } /* Overwrites any dest */ - if (!meta_tree_copy (info->tree, src_path, dest_path)) + if (!meta_tree_copy (info->tree, arg_path, arg_dest_path)) { - dbus_set_error (derror, - DBUS_ERROR_FAILED, - _("Unable to move metadata keys")); - return FALSE; + g_dbus_method_invocation_return_error_literal (invocation, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unable to move metadata keys")); + return TRUE; } /* Remove source if copy succeeded (ignoring errors) */ - meta_tree_remove (info->tree, src_path); + meta_tree_remove (info->tree, arg_path); tree_info_schedule_writeout (info); + gvfs_metadata_complete_move (object, invocation); + return TRUE; } -static gboolean -register_name (DBusConnection *conn, - gboolean replace) -{ - DBusError error; - unsigned int flags; - int ret; - - flags = DBUS_NAME_FLAG_ALLOW_REPLACEMENT | DBUS_NAME_FLAG_DO_NOT_QUEUE; - if (replace) - flags |= DBUS_NAME_FLAG_REPLACE_EXISTING; - - dbus_error_init (&error); - ret = dbus_bus_request_name (conn, G_VFS_DBUS_METADATA_NAME, flags, &error); - if (ret == -1) - { - g_printerr ("Failed to acquire daemon name: %s", error.message); - dbus_error_free (&error); - return FALSE; - } - else if (ret == DBUS_REQUEST_NAME_REPLY_EXISTS) - { - g_printerr ("Metadata daemon already running, exiting.\n"); - return FALSE; - } - else if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) - { - g_printerr ("Not primary owner of the service, exiting.\n"); - return FALSE; - } - return TRUE; -} - -static DBusHandlerResult -dbus_message_filter_func (DBusConnection *conn, - DBusMessage *message, - gpointer data) +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) { - char *name; + GError *error; + + skeleton = gvfs_metadata_skeleton_new (); + + g_signal_connect (skeleton, "handle-set", G_CALLBACK (handle_set), skeleton); + g_signal_connect (skeleton, "handle-unset", G_CALLBACK (handle_unset), skeleton); + g_signal_connect (skeleton, "handle-get", G_CALLBACK (handle_get), skeleton); + g_signal_connect (skeleton, "handle-remove", G_CALLBACK (handle_remove), skeleton); + g_signal_connect (skeleton, "handle-move", G_CALLBACK (handle_move), skeleton); - if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameLost")) + error = NULL; + if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton), connection, + G_VFS_DBUS_METADATA_PATH, &error)) { - if (dbus_message_get_args (message, NULL, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID) && - strcmp (name, G_VFS_DBUS_METADATA_NAME) == 0) - { - /* Someone else got the name (i.e. someone used --replace), exit */ - exit (1); - } + g_printerr ("Error exporting volume monitor: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } static void -metadata_unregistered (DBusConnection *connection, - void *user_data) +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) { -} - -static DBusHandlerResult -metadata_message (DBusConnection *connection, - DBusMessage *message, - void *user_data) -{ - DBusMessageIter iter; - DBusError derror; - DBusMessage *reply; - char *treefile; - char *path, *dest_path; - const char *key; - - reply = NULL; - dbus_message_iter_init (message, &iter); - dbus_error_init (&derror); - - if (dbus_message_is_method_call (message, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_SET)) - { - treefile = NULL; - path = NULL; - if (!_g_dbus_message_iter_get_args (&iter, &derror, - G_DBUS_TYPE_CSTRING, &treefile, - G_DBUS_TYPE_CSTRING, &path, - 0) || - !metadata_set (treefile, path, &iter, &derror)) - { - reply = dbus_message_new_error (message, - derror.name, - derror.message); - dbus_error_free (&derror); - } - else - reply = dbus_message_new_method_return (message); - - g_free (treefile); - g_free (path); - } - - else if (dbus_message_is_method_call (message, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_UNSET)) - { - treefile = NULL; - path = NULL; - if (!_g_dbus_message_iter_get_args (&iter, &derror, - G_DBUS_TYPE_CSTRING, &treefile, - G_DBUS_TYPE_CSTRING, &path, - DBUS_TYPE_STRING, &key, - 0) || - !metadata_unset (treefile, path, key, &derror)) - { - reply = dbus_message_new_error (message, - derror.name, - derror.message); - dbus_error_free (&derror); - } - else - reply = dbus_message_new_method_return (message); - - g_free (treefile); - g_free (path); - } - - if (dbus_message_is_method_call (message, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_GET)) - { - treefile = NULL; - path = NULL; - if (!_g_dbus_message_iter_get_args (&iter, &derror, - G_DBUS_TYPE_CSTRING, &treefile, - G_DBUS_TYPE_CSTRING, &path, - 0) || - (reply = metadata_get (treefile, path, message, &iter, &derror)) == NULL) - { - reply = dbus_message_new_error (message, - derror.name, - derror.message); - dbus_error_free (&derror); - } - - g_free (treefile); - g_free (path); - } - - else if (dbus_message_is_method_call (message, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_REMOVE)) - { - treefile = NULL; - path = NULL; - if (!_g_dbus_message_iter_get_args (&iter, &derror, - G_DBUS_TYPE_CSTRING, &treefile, - G_DBUS_TYPE_CSTRING, &path, - 0) || - !metadata_remove (treefile, path, &derror)) - { - reply = dbus_message_new_error (message, - derror.name, - derror.message); - dbus_error_free (&derror); - } - else - reply = dbus_message_new_method_return (message); - - g_free (treefile); - g_free (path); - } + GMainLoop *loop = user_data; - else if (dbus_message_is_method_call (message, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_MOVE)) - { - treefile = NULL; - path = NULL; - dest_path = NULL; - if (!_g_dbus_message_iter_get_args (&iter, &derror, - G_DBUS_TYPE_CSTRING, &treefile, - G_DBUS_TYPE_CSTRING, &path, - G_DBUS_TYPE_CSTRING, &dest_path, - 0) || - !metadata_move (treefile, path, dest_path, &derror)) - { - reply = dbus_message_new_error (message, - derror.name, - derror.message); - dbus_error_free (&derror); - } - else - reply = dbus_message_new_method_return (message); - - g_free (treefile); - g_free (path); - g_free (dest_path); - } - - if (reply) - { - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); - return DBUS_HANDLER_RESULT_HANDLED; - } - else - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + /* means that someone has claimed our name (we allow replacement) */ + g_main_loop_quit (loop); } -static struct DBusObjectPathVTable metadata_dbus_vtable = { - metadata_unregistered, - metadata_message -}; int main (int argc, char *argv[]) { GMainLoop *loop; - DBusConnection *conn; + GDBusConnection *conn; gboolean replace; GError *error; - DBusError derror; + guint name_owner_id; + GBusNameOwnerFlags flags; GOptionContext *context; const GOptionEntry options[] = { { "replace", 'r', 0, G_OPTION_ARG_NONE, &replace, N_("Replace old daemon."), NULL }, @@ -709,6 +462,7 @@ main (int argc, char *argv[]) g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE); replace = FALSE; + name_owner_id = 0; error = NULL; if (!g_option_context_parse (context, &argc, &argv, &error)) @@ -731,56 +485,43 @@ main (int argc, char *argv[]) loop = g_main_loop_new (NULL, FALSE); - dbus_error_init (&derror); - conn = dbus_bus_get (DBUS_BUS_SESSION, &derror); + error = NULL; + conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); if (!conn) { - g_printerr ("Failed to connect to the D-BUS daemon: %s\n", - derror.message); - - dbus_error_free (&derror); - return 1; - } - - dbus_bus_add_match (conn, - "type='signal'," - "interface='org.freedesktop.DBus'," - "member='NameOwnerChanged'," - "arg0='"G_VFS_DBUS_METADATA_NAME"'", - &derror); - if (dbus_error_is_set (&derror)) - { - g_printerr ("Failed to add dbus match: %s\n", derror.message); - dbus_error_free (&derror); - return 1; - } - - if (!dbus_connection_add_filter (conn, - dbus_message_filter_func, NULL, NULL)) - { - g_printerr ("Failed to add dbus filter\n"); - return 1; - } - - if (!dbus_connection_register_object_path (conn, - G_VFS_DBUS_METADATA_PATH, - &metadata_dbus_vtable, NULL)) - { - g_printerr ("Failed to register object path\n"); + g_printerr ("Failed to connect to the D-BUS daemon: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); return 1; } - - if (!register_name (conn, replace)) - return 1; - - _g_dbus_connection_integrate_with_main (conn); - + + flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT; + if (replace) + flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE; + + name_owner_id = g_bus_own_name_on_connection (conn, + G_VFS_DBUS_METADATA_NAME, + flags, + on_name_acquired, + on_name_lost, + loop, + NULL); + tree_infos = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)tree_info_free); g_main_loop_run (loop); + + if (skeleton) + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (skeleton)); + if (name_owner_id != 0) + g_bus_unown_name (name_owner_id); + if (conn) + g_object_unref (conn); + if (loop != NULL) + g_main_loop_unref (loop); return 0; } diff --git a/metadata/meta-set.c b/metadata/meta-set.c index 22af1fcd..04a6b38e 100644 --- a/metadata/meta-set.c +++ b/metadata/meta-set.c @@ -1,9 +1,10 @@ #include "config.h" #include "metatree.h" #include <glib/gstdio.h> +/* TODO: remove + remove traces in Makefile.am */ #include <dbus/dbus.h> #include "gvfsdaemonprotocol.h" -#include "gvfsdbusutils.h" +#include "metadata-dbus.h" static gboolean unset = FALSE; static gboolean list = FALSE; @@ -28,12 +29,12 @@ main (int argc, MetaLookupCache *lookup; struct stat statbuf; const char *path, *key; - DBusConnection *connection; - DBusMessage *message, *reply; const char *metatreefile; - DBusError derror; char *tree_path; - + GVfsMetadata *proxy; + + g_type_init(); + context = g_option_context_new ("<path> <key> <value> - set metadata"); g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); if (!g_option_context_parse (context, &argc, &argv, &error)) @@ -96,39 +97,42 @@ main (int argc, } } - connection = NULL; + proxy = NULL; if (use_dbus) { - dbus_error_init (&derror); - connection = dbus_bus_get (DBUS_BUS_SESSION, &derror); - if (connection == NULL) + proxy = gvfs_metadata_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + G_VFS_DBUS_METADATA_NAME, + G_VFS_DBUS_METADATA_PATH, + NULL, + &error); + + if (proxy == NULL) { - g_printerr ("Unable to connect to dbus: %s\n", derror.message); - dbus_error_free (&derror); + g_printerr ("Unable to connect to dbus: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); return 1; } + + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), 1000*30); } if (unset) { if (use_dbus) { - message = - dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME, - G_VFS_DBUS_METADATA_PATH, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_UNSET); - metatreefile = meta_tree_get_filename (tree); - _g_dbus_message_append_args (message, - G_DBUS_TYPE_CSTRING, &metatreefile, - G_DBUS_TYPE_CSTRING, &tree_path, - DBUS_TYPE_STRING, &key, - 0); - reply = dbus_connection_send_with_reply_and_block (connection, message, 1000*30, - &derror); - if (reply == NULL) + metatreefile = meta_tree_get_filename (tree); + + if (! gvfs_metadata_call_unset_sync (proxy, + metatreefile, + tree_path, + key, + NULL, + &error)) { - g_printerr ("Unset error: %s\n", derror.message); + g_printerr ("Unset error: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); return 1; } } @@ -146,26 +150,27 @@ main (int argc, if (use_dbus) { char **strv; - message = - dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME, - G_VFS_DBUS_METADATA_PATH, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_SET); - metatreefile = meta_tree_get_filename (tree); - strv = &argv[3]; - _g_dbus_message_append_args (message, - G_DBUS_TYPE_CSTRING, &metatreefile, - G_DBUS_TYPE_CSTRING, &tree_path, - DBUS_TYPE_STRING, &key, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &strv, argc - 3, - 0); - reply = dbus_connection_send_with_reply_and_block (connection, message, 1000*30, - &derror); - if (reply == NULL) - { - g_printerr ("SetStringv error: %s\n", derror.message); - return 1; - } + GVariantBuilder *builder; + + metatreefile = meta_tree_get_filename (tree); + strv = &argv[3]; + + builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (builder, "{sv}", key, g_variant_new_strv ((const gchar * const *) strv, -1)); + + if (! gvfs_metadata_call_set_sync (proxy, + metatreefile, + tree_path, + g_variant_builder_end (builder), + NULL, + &error)) + { + g_printerr ("SetStringv error: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + return 1; + } + + g_variant_builder_unref (builder); } else { @@ -180,25 +185,26 @@ main (int argc, { if (use_dbus) { - message = - dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME, - G_VFS_DBUS_METADATA_PATH, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_SET); - metatreefile = meta_tree_get_filename (tree); - _g_dbus_message_append_args (message, - G_DBUS_TYPE_CSTRING, &metatreefile, - G_DBUS_TYPE_CSTRING, &tree_path, - DBUS_TYPE_STRING, &key, - DBUS_TYPE_STRING, &argv[3], - 0); - reply = dbus_connection_send_with_reply_and_block (connection, message, 1000*30, - &derror); - if (reply == NULL) - { - g_printerr ("SetString error: %s\n", derror.message); - return 1; - } + GVariantBuilder *builder; + + metatreefile = meta_tree_get_filename (tree); + + builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (builder, "{sv}", key, g_variant_new_string (argv[3])); + + if (! gvfs_metadata_call_set_sync (proxy, + metatreefile, + tree_path, + g_variant_builder_end (builder), + NULL, + &error)) + { + g_printerr ("SetString error: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + return 1; + } + + g_variant_builder_unref (builder); } else { @@ -210,5 +216,8 @@ main (int argc, } } + if (proxy) + g_object_unref (proxy); + return 0; } diff --git a/monitor/afc/Makefile.am b/monitor/afc/Makefile.am index e524481e..0b022b29 100644 --- a/monitor/afc/Makefile.am +++ b/monitor/afc/Makefile.am @@ -23,7 +23,6 @@ gvfs_afc_volume_monitor_CFLAGS = \ gvfs_afc_volume_monitor_LDADD = \ $(GLIB_LIBS) \ - $(DBUS_LIBS) \ $(AFC_LIBS) \ $(top_builddir)/common/libgvfscommon.la \ $(top_builddir)/monitor/proxy/libgvfsproxyvolumemonitordaemon-noin.la \ diff --git a/monitor/gdu/Makefile.am b/monitor/gdu/Makefile.am index 49454456..5d49cbc9 100644 --- a/monitor/gdu/Makefile.am +++ b/monitor/gdu/Makefile.am @@ -19,7 +19,6 @@ gvfs_gdu_volume_monitor_CFLAGS = \ $(GLIB_CFLAGS) \ $(GDU_CFLAGS) \ $(GUDEV_CFLAGS) \ - $(DBUS_CFLAGS) \ -DGIO_MODULE_DIR=\"$(GIO_MODULE_DIR)\" \ -DGVFS_LOCALEDIR=\""$(localedir)"\" \ -DGDU_API_IS_SUBJECT_TO_CHANGE \ @@ -32,7 +31,6 @@ gvfs_gdu_volume_monitor_LDADD = \ $(GLIB_LIBS) \ $(GDU_LIBS) \ $(GUDEV_LIBS) \ - $(DBUS_LIBS) \ $(top_builddir)/common/libgvfscommon.la \ $(top_builddir)/monitor/proxy/libgvfsproxyvolumemonitordaemon-noin.la \ $(NULL) diff --git a/monitor/proxy/Makefile.am b/monitor/proxy/Makefile.am index bd3b451d..1c0fc7ec 100644 --- a/monitor/proxy/Makefile.am +++ b/monitor/proxy/Makefile.am @@ -5,6 +5,19 @@ remote_volume_monitorsdir = $(datadir)/gvfs/remote-volume-monitors module_flags = -export_dynamic -avoid-version -module -no-undefined -export-symbols-regex '^g_io_module_(load|unload|query)' +dbus_built_sources = gvfsvolumemonitordbus.c gvfsvolumemonitordbus.h +BUILT_SOURCES = $(dbus_built_sources) + +$(dbus_built_sources) : Makefile.am dbus-interfaces.xml + gdbus-codegen \ + --interface-prefix org.gtk.Private. \ + --c-namespace GVfs \ + --generate-c-code gvfsvolumemonitordbus \ + dbus-interfaces.xml \ + $(NULL) + + + giomodules_LTLIBRARIES = libgioremote-volume-monitor.la libgioremote_volume_monitor_la_SOURCES = \ @@ -15,13 +28,13 @@ libgioremote_volume_monitor_la_SOURCES = \ gproxyshadowmount.c gproxyshadowmount.h \ gproxyvolumemonitor.c gproxyvolumemonitor.h \ gproxymountoperation.c gproxymountoperation.h \ + $(dbus_built_sources) \ $(NULL) libgioremote_volume_monitor_la_CFLAGS = \ -DG_LOG_DOMAIN=\"GVFS-RemoteVolumeMonitor\" \ -I$(top_srcdir)/common \ $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ -DGIO_MODULE_DIR=\"$(GIO_MODULE_DIR)\" \ -DREMOTE_VOLUME_MONITORS_DIR=\"$(remote_volume_monitorsdir)\" \ -DGVFS_LOCALEDIR=\""$(localedir)"\" \ @@ -33,7 +46,6 @@ libgioremote_volume_monitor_la_LDFLAGS = \ libgioremote_volume_monitor_la_LIBADD = \ $(GLIB_LIBS) \ - $(DBUS_LIBS) \ $(top_builddir)/common/libgvfscommon.la \ $(NULL) @@ -43,12 +55,13 @@ noinst_LTLIBRARIES = libgvfsproxyvolumemonitordaemon-noin.la libgvfsproxyvolumemonitordaemon_noin_la_SOURCES = \ gvfsproxyvolumemonitordaemon.c \ - gvfsproxyvolumemonitordaemon.h + gvfsproxyvolumemonitordaemon.h \ + $(dbus_built_sources) \ + $(NULL) libgvfsproxyvolumemonitordaemon_noin_la_CFLAGS = \ -I$(top_srcdir)/common \ $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ $(GDU_CFLAGS) \ -DG_LOG_DOMAIN=\"GVFS-RemoteVolumeMonitorDaemon\" \ -DGVFS_LOCALEDIR=\""$(localedir)"\" \ @@ -56,7 +69,6 @@ libgvfsproxyvolumemonitordaemon_noin_la_CFLAGS = \ libgvfsproxyvolumemonitordaemon_noin_la_LIBADD = \ $(GLIB_LIBS) \ - $(DBUS_LIBS) \ $(top_builddir)/common/libgvfscommon.la \ $(NULL) @@ -65,3 +77,11 @@ clean-local: install-data-local: mkdir -p $(DESTDIR)$(remote_volume_monitorsdir) + +EXTRA_DIST = \ + dbus-interfaces.xml \ + $(NULL) + +CLEANFILES = \ + $(dbus_built_sources) \ + $(NULL) diff --git a/monitor/proxy/dbus-interfaces.xml b/monitor/proxy/dbus-interfaces.xml new file mode 100644 index 00000000..49af8c76 --- /dev/null +++ b/monitor/proxy/dbus-interfaces.xml @@ -0,0 +1,176 @@ +<!DOCTYPE node PUBLIC +"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> + +<!-- + Copyright (C) 2011 Red Hat, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307, USA. + + Author: Tomas Bzatek <tbzatek@redhat.com> +--> + +<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd"> + <interface name='org.gtk.Private.RemoteVolumeMonitor'> + + <!-- GIO side --> + <signal name="DriveChanged"> + <arg type='s' name='dbus_name'/> + <arg type='s' name='id'/> + <arg type='(sssbbbbbbbbuasa{ss}sa{sv})' name='drive'/> + </signal> + <signal name="DriveConnected"> + <arg type='s' name='dbus_name'/> + <arg type='s' name='id'/> + <arg type='(sssbbbbbbbbuasa{ss}sa{sv})' name='drive'/> + </signal> + <signal name="DriveDisconnected"> + <arg type='s' name='dbus_name'/> + <arg type='s' name='id'/> + <arg type='(sssbbbbbbbbuasa{ss}sa{sv})' name='drive'/> + </signal> + <signal name="DriveEjectButton"> + <arg type='s' name='dbus_name'/> + <arg type='s' name='id'/> + <arg type='(sssbbbbbbbbuasa{ss}sa{sv})' name='drive'/> + </signal> + <signal name="DriveStopButton"> + <arg type='s' name='dbus_name'/> + <arg type='s' name='id'/> + <arg type='(sssbbbbbbbbuasa{ss}sa{sv})' name='drive'/> + </signal> + <signal name="VolumeChanged"> + <arg type='s' name='dbus_name'/> + <arg type='s' name='id'/> + <arg type='(sssssbbssa{ss}sa{sv})' name='volume'/> + </signal> + <signal name="VolumeAdded"> + <arg type='s' name='dbus_name'/> + <arg type='s' name='id'/> + <arg type='(sssssbbssa{ss}sa{sv})' name='volume'/> + </signal> + <signal name="VolumeRemoved"> + <arg type='s' name='dbus_name'/> + <arg type='s' name='id'/> + <arg type='(sssssbbssa{ss}sa{sv})' name='volume'/> + </signal> + <signal name="MountChanged"> + <arg type='s' name='dbus_name'/> + <arg type='s' name='id'/> + <arg type='(sssssbsassa{sv})' name='mount'/> + </signal> + <signal name="MountAdded"> + <arg type='s' name='dbus_name'/> + <arg type='s' name='id'/> + <arg type='(sssssbsassa{sv})' name='mount'/> + </signal> + <signal name="MountPreUnmount"> + <arg type='s' name='dbus_name'/> + <arg type='s' name='id'/> + <arg type='(sssssbsassa{sv})' name='mount'/> + </signal> + <signal name="MountRemoved"> + <arg type='s' name='dbus_name'/> + <arg type='s' name='id'/> + <arg type='(sssssbsassa{sv})' name='mount'/> + </signal> + <signal name="MountOpAskPassword"> + <arg type='s' name='dbus_name'/> + <arg type='s' name='id'/> + <arg type='s' name='message_to_show'/> + <arg type='s' name='default_user'/> + <arg type='s' name='default_domain'/> + <arg type='u' name='flags'/> + </signal> + <signal name="MountOpAskQuestion"> + <arg type='s' name='dbus_name'/> + <arg type='s' name='id'/> + <arg type='s' name='message_to_show'/> + <arg type='as' name='choices'/> + </signal> + <signal name="MountOpShowProcesses"> + <arg type='s' name='dbus_name'/> + <arg type='s' name='id'/> + <arg type='s' name='message_to_show'/> + <arg type='ai' name='pid'/> + <arg type='as' name='choices'/> + </signal> + <signal name="MountOpAborted"> + <arg type='s' name='dbus_name'/> + <arg type='s' name='id'/> + </signal> + + + <!-- Particular volume monitor implementations --> + <method name="IsSupported"> + <arg type='b' name='is_supported' direction='out'/> + </method> + <method name="List"> + <arg type='a(sssbbbbbbbbuasa{ss}sa{sv})' name='drives' direction='out'/> + <arg type='a(sssssbbssa{ss}sa{sv})' name='volumes' direction='out'/> + <arg type='a(sssssbsassa{sv})' name='mounts' direction='out'/> + </method> + <method name="CancelOperation"> + <arg type='s' name='cancellation_id' direction='in'/> + <arg type='b' name='was_cancelled' direction='out'/> + </method> + <method name="MountUnmount"> + <arg type='s' name='id' direction='in'/> + <arg type='s' name='cancellation_id' direction='in'/> + <arg type='u' name='unmount_flags' direction='in'/> + <arg type='s' name='mount_op_id' direction='in'/> + </method> + <method name="VolumeMount"> + <arg type='s' name='id' direction='in'/> + <arg type='s' name='cancellation_id' direction='in'/> + <arg type='u' name='mount_flags' direction='in'/> + <arg type='s' name='mount_op_id' direction='in'/> + </method> + <method name="DriveEject"> + <arg type='s' name='id' direction='in'/> + <arg type='s' name='cancellation_id' direction='in'/> + <arg type='u' name='unmount_flags' direction='in'/> + <arg type='s' name='mount_op_id' direction='in'/> + </method> + <method name="DrivePollForMedia"> + <arg type='s' name='id' direction='in'/> + <arg type='s' name='cancellation_id' direction='in'/> + </method> + <method name="DriveStart"> + <arg type='s' name='id' direction='in'/> + <arg type='s' name='cancellation_id' direction='in'/> + <arg type='u' name='flags' direction='in'/> + <arg type='s' name='mount_op_id' direction='in'/> + </method> + <method name="DriveStop"> + <arg type='s' name='id' direction='in'/> + <arg type='s' name='cancellation_id' direction='in'/> + <arg type='u' name='unmount_flags' direction='in'/> + <arg type='s' name='mount_op_id' direction='in'/> + </method> + <method name="MountOpReply"> + <arg type='s' name='mount_op_id' direction='in'/> + <arg type='i' name='result' direction='in'/> + <arg type='s' name='user_name' direction='in'/> + <arg type='s' name='domain' direction='in'/> + <arg type='s' name='encoded_password' direction='in'/> + <arg type='i' name='password_save' direction='in'/> + <arg type='i' name='choice' direction='in'/> + <arg type='b' name='anonymous' direction='in'/> + </method> + </interface> +</node> + diff --git a/monitor/proxy/gproxydrive.c b/monitor/proxy/gproxydrive.c index be2b600f..558913f2 100644 --- a/monitor/proxy/gproxydrive.c +++ b/monitor/proxy/gproxydrive.c @@ -30,12 +30,11 @@ #include <glib.h> #include <glib/gi18n-lib.h> -#include <gvfsdbusutils.h> - #include "gproxyvolumemonitor.h" #include "gproxydrive.h" #include "gproxyvolume.h" #include "gproxymountoperation.h" +#include "gvfsvolumemonitordbus.h" /* Protects all fields of GProxyDrive that can change */ G_LOCK_DEFINE_STATIC(proxy_drive); @@ -139,80 +138,52 @@ g_proxy_drive_new (GProxyVolumeMonitor *volume_monitor) * string sort_key * a{sv} expansion */ -#define DRIVE_STRUCT_TYPE "(sssbbbbbbbbuasa{ss}sa{sv})" +#define DRIVE_STRUCT_TYPE "(&s&s&sbbbbbbbbuasa{ss}&sa{sv})" void -g_proxy_drive_update (GProxyDrive *drive, - DBusMessageIter *iter) +g_proxy_drive_update (GProxyDrive *drive, + GVariant *iter) { - DBusMessageIter iter_struct; - DBusMessageIter iter_volume_ids_iter; const char *id; const char *name; const char *gicon_data; - dbus_bool_t can_eject; - dbus_bool_t can_poll_for_media; - dbus_bool_t has_media; - dbus_bool_t is_media_removable; - dbus_bool_t is_media_check_automatic; - dbus_bool_t can_start; - dbus_bool_t can_start_degraded; - dbus_bool_t can_stop; - dbus_uint32_t start_stop_type; + gboolean can_eject; + gboolean can_poll_for_media; + gboolean has_media; + gboolean is_media_removable; + gboolean is_media_check_automatic; + gboolean can_start; + gboolean can_start_degraded; + gboolean can_stop; + guint32 start_stop_type; GPtrArray *volume_ids; GHashTable *identifiers; const char *sort_key; + const gchar *volume_id; + GVariantIter *iter_volume_ids; + GVariantIter *iter_identifiers; + GVariantIter *iter_expansion; - dbus_message_iter_recurse (iter, &iter_struct); - dbus_message_iter_get_basic (&iter_struct, &id); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &name); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &gicon_data); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &can_eject); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &can_poll_for_media); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &has_media); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &is_media_removable); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &is_media_check_automatic); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &can_start); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &can_start_degraded); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &can_stop); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &start_stop_type); - dbus_message_iter_next (&iter_struct); + + sort_key = NULL; + g_variant_get (iter, DRIVE_STRUCT_TYPE, + &id, &name, &gicon_data, + &can_eject, &can_poll_for_media, + &has_media, &is_media_removable, + &is_media_check_automatic, + &can_start, &can_start_degraded, + &can_stop, &start_stop_type, + &iter_volume_ids, + &iter_identifiers, + &sort_key, + &iter_expansion); volume_ids = g_ptr_array_new (); - dbus_message_iter_recurse (&iter_struct, &iter_volume_ids_iter); - while (dbus_message_iter_get_arg_type (&iter_volume_ids_iter) != DBUS_TYPE_INVALID) - { - const char *volume_id; - dbus_message_iter_get_basic (&iter_volume_ids_iter, &volume_id); - dbus_message_iter_next (&iter_volume_ids_iter); - g_ptr_array_add (volume_ids, (gpointer) volume_id); - } + while (g_variant_iter_loop (iter_volume_ids, "&s", &volume_id)) + g_ptr_array_add (volume_ids, (gpointer) volume_id); g_ptr_array_add (volume_ids, NULL); - dbus_message_iter_next (&iter_struct); - - identifiers = _get_identifiers (&iter_struct); - dbus_message_iter_next (&iter_struct); - - /* make sure we are backwards compat with old daemon instance */ - sort_key = NULL; - if (dbus_message_iter_has_next (&iter_struct)) - { - dbus_message_iter_get_basic (&iter_struct, &sort_key); - dbus_message_iter_next (&iter_struct); - /* TODO: decode expansion, once used */ - } + identifiers = _get_identifiers (iter_identifiers); if (drive->id != NULL && strcmp (drive->id, id) != 0) { g_warning ("id mismatch during update of drive"); @@ -255,7 +226,12 @@ g_proxy_drive_update (GProxyDrive *drive, drive->volume_ids = g_strdupv ((char **) volume_ids->pdata); drive->sort_key = g_strdup (sort_key); + /* TODO: decode expansion, once used */ + out: + g_variant_iter_free (iter_volume_ids); + g_variant_iter_free (iter_identifiers); + g_variant_iter_free (iter_expansion); g_ptr_array_free (volume_ids, TRUE); g_hash_table_unref (identifiers); } @@ -511,13 +487,20 @@ typedef struct { } DBusOp; static void -cancel_operation_reply_cb (DBusMessage *reply, - GError *error, - gpointer user_data) +cancel_operation_reply_cb (GVfsRemoteVolumeMonitor *proxy, + GAsyncResult *res, + gpointer user_data) { - if (error != NULL) + gboolean out_WasCancelled; + GError *error = NULL; + + if (!gvfs_remote_volume_monitor_call_cancel_operation_finish (proxy, + &out_WasCancelled, + res, + &error)) { g_warning ("Error from CancelOperation(): %s", error->message); + g_error_free (error); } } @@ -527,9 +510,7 @@ operation_cancelled (GCancellable *cancellable, { DBusOp *data = user_data; GSimpleAsyncResult *simple; - DBusConnection *connection; - DBusMessage *message; - const char *name; + GVfsRemoteVolumeMonitor *proxy; G_LOCK (proxy_drive); @@ -543,35 +524,31 @@ operation_cancelled (GCancellable *cancellable, g_object_unref (simple); /* Now tell the remote volume monitor that the op has been cancelled */ - connection = g_proxy_volume_monitor_get_dbus_connection (data->drive->volume_monitor); - name = g_proxy_volume_monitor_get_dbus_name (data->drive->volume_monitor); - message = dbus_message_new_method_call (name, - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "CancelOperation"); - dbus_message_append_args (message, - DBUS_TYPE_STRING, - &(data->cancellation_id), - DBUS_TYPE_INVALID); + proxy = g_proxy_volume_monitor_get_dbus_proxy (data->drive->volume_monitor); + gvfs_remote_volume_monitor_call_cancel_operation (proxy, + data->cancellation_id, + NULL, + (GAsyncReadyCallback) cancel_operation_reply_cb, + NULL); + g_object_unref (proxy); G_UNLOCK (proxy_drive); - - _g_dbus_connection_call_async (connection, - message, - -1, - (GAsyncDBusCallback) cancel_operation_reply_cb, - NULL); - dbus_message_unref (message); - dbus_connection_unref (connection); } /* ---------------------------------------------------------------------------------------------------- */ static void -eject_cb (DBusMessage *reply, - GError *error, - DBusOp *data) +eject_cb (GVfsRemoteVolumeMonitor *proxy, + GAsyncResult *res, + gpointer user_data) { + DBusOp *data = user_data; + GError *error = NULL; + + gvfs_remote_volume_monitor_call_drive_eject_finish (proxy, + res, + &error); + if (data->cancelled_handler_id > 0) g_signal_handler_disconnect (data->cancellable, data->cancelled_handler_id); @@ -580,15 +557,20 @@ eject_cb (DBusMessage *reply, GSimpleAsyncResult *simple; if (error != NULL) - simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive), - data->callback, - data->user_data, - error); + { + g_dbus_error_strip_remote_error (error); + simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive), + data->callback, + data->user_data, + error); + } else - simple = g_simple_async_result_new (G_OBJECT (data->drive), - data->callback, - data->user_data, - NULL); + { + simple = g_simple_async_result_new (G_OBJECT (data->drive), + data->callback, + data->user_data, + NULL); + } g_simple_async_result_complete (simple); g_object_unref (simple); } @@ -599,6 +581,8 @@ eject_cb (DBusMessage *reply, if (data->cancellable != NULL) g_object_unref (data->cancellable); g_free (data); + if (error != NULL) + g_error_free (error); } static void @@ -610,11 +594,8 @@ g_proxy_drive_eject_with_operation (GDrive *drive, gpointer user_data) { GProxyDrive *proxy_drive = G_PROXY_DRIVE (drive); - DBusConnection *connection; - const char *name; - DBusMessage *message; DBusOp *data; - dbus_uint32_t _flags = flags; + GVfsRemoteVolumeMonitor *proxy; G_LOCK (proxy_drive); @@ -653,32 +634,23 @@ g_proxy_drive_eject_with_operation (GDrive *drive, data->cancellation_id = g_strdup (""); } - connection = g_proxy_volume_monitor_get_dbus_connection (proxy_drive->volume_monitor); - name = g_proxy_volume_monitor_get_dbus_name (proxy_drive->volume_monitor); - - message = dbus_message_new_method_call (name, - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "DriveEject"); - dbus_message_append_args (message, - DBUS_TYPE_STRING, - &(proxy_drive->id), - DBUS_TYPE_STRING, - &(data->cancellation_id), - DBUS_TYPE_UINT32, - &_flags, - DBUS_TYPE_STRING, - &(data->mount_op_id), - DBUS_TYPE_INVALID); + proxy = g_proxy_volume_monitor_get_dbus_proxy (data->drive->volume_monitor); + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT); /* 30 minute timeout */ + + gvfs_remote_volume_monitor_call_drive_eject (proxy, + proxy_drive->id, + data->cancellation_id, + flags, + data->mount_op_id, + NULL, + (GAsyncReadyCallback) eject_cb, + data); + + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), -1); + g_object_unref (proxy); + G_UNLOCK (proxy_drive); - _g_dbus_connection_call_async (connection, - message, - G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT, /* 30 minute timeout */ - (GAsyncDBusCallback) eject_cb, - data); - dbus_connection_unref (connection); - dbus_message_unref (message); out: ; } @@ -716,10 +688,17 @@ g_proxy_drive_eject_finish (GDrive *drive, /* ---------------------------------------------------------------------------------------------------- */ static void -stop_cb (DBusMessage *reply, - GError *error, - DBusOp *data) +stop_cb (GVfsRemoteVolumeMonitor *proxy, + GAsyncResult *res, + gpointer user_data) { + DBusOp *data = user_data; + GError *error = NULL; + + gvfs_remote_volume_monitor_call_drive_stop_finish (proxy, + res, + &error); + if (data->cancelled_handler_id > 0) g_signal_handler_disconnect (data->cancellable, data->cancelled_handler_id); @@ -728,15 +707,20 @@ stop_cb (DBusMessage *reply, GSimpleAsyncResult *simple; if (error != NULL) - simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive), - data->callback, - data->user_data, - error); + { + g_dbus_error_strip_remote_error (error); + simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive), + data->callback, + data->user_data, + error); + } else - simple = g_simple_async_result_new (G_OBJECT (data->drive), - data->callback, - data->user_data, - NULL); + { + simple = g_simple_async_result_new (G_OBJECT (data->drive), + data->callback, + data->user_data, + NULL); + } g_simple_async_result_complete (simple); g_object_unref (simple); } @@ -747,6 +731,8 @@ stop_cb (DBusMessage *reply, if (data->cancellable != NULL) g_object_unref (data->cancellable); g_free (data); + if (error != NULL) + g_error_free (error); } static void @@ -758,11 +744,8 @@ g_proxy_drive_stop (GDrive *drive, gpointer user_data) { GProxyDrive *proxy_drive = G_PROXY_DRIVE (drive); - DBusConnection *connection; - const char *name; - DBusMessage *message; DBusOp *data; - dbus_uint32_t _flags = flags; + GVfsRemoteVolumeMonitor *proxy; G_LOCK (proxy_drive); @@ -801,32 +784,23 @@ g_proxy_drive_stop (GDrive *drive, data->cancellation_id = g_strdup (""); } - connection = g_proxy_volume_monitor_get_dbus_connection (proxy_drive->volume_monitor); - name = g_proxy_volume_monitor_get_dbus_name (proxy_drive->volume_monitor); - - message = dbus_message_new_method_call (name, - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "DriveStop"); - dbus_message_append_args (message, - DBUS_TYPE_STRING, - &(proxy_drive->id), - DBUS_TYPE_STRING, - &(data->cancellation_id), - DBUS_TYPE_UINT32, - &_flags, - DBUS_TYPE_STRING, - &(data->mount_op_id), - DBUS_TYPE_INVALID); + proxy = g_proxy_volume_monitor_get_dbus_proxy (data->drive->volume_monitor); + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT); /* 30 minute timeout */ + + gvfs_remote_volume_monitor_call_drive_stop (proxy, + proxy_drive->id, + data->cancellation_id, + flags, + data->mount_op_id, + NULL, + (GAsyncReadyCallback) stop_cb, + data); + + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), -1); + g_object_unref (proxy); + G_UNLOCK (proxy_drive); - _g_dbus_connection_call_async (connection, - message, - G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT, /* 30 minute timeout */ - (GAsyncDBusCallback) stop_cb, - data); - dbus_connection_unref (connection); - dbus_message_unref (message); out: ; } @@ -856,11 +830,18 @@ typedef struct { } DBusStartOp; static void -start_cb (DBusMessage *reply, - GError *error, - DBusStartOp *data) +start_cb (GVfsRemoteVolumeMonitor *proxy, + GAsyncResult *res, + gpointer user_data) { - if (data->cancelled_handler_id > 0) + DBusStartOp *data = user_data; + GError *error = NULL; + + gvfs_remote_volume_monitor_call_drive_start_finish (proxy, + res, + &error); + +if (data->cancelled_handler_id > 0) g_signal_handler_disconnect (data->cancellable, data->cancelled_handler_id); if (!g_cancellable_is_cancelled (data->cancellable)) @@ -868,15 +849,20 @@ start_cb (DBusMessage *reply, GSimpleAsyncResult *simple; if (error != NULL) - simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive), - data->callback, - data->user_data, - error); + { + g_dbus_error_strip_remote_error (error); + simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive), + data->callback, + data->user_data, + error); + } else - simple = g_simple_async_result_new (G_OBJECT (data->drive), - data->callback, - data->user_data, - NULL); + { + simple = g_simple_async_result_new (G_OBJECT (data->drive), + data->callback, + data->user_data, + NULL); + } g_simple_async_result_complete_in_idle (simple); g_object_unref (simple); } @@ -890,6 +876,8 @@ start_cb (DBusMessage *reply, g_object_unref (data->cancellable); g_free (data); + if (error != NULL) + g_error_free (error); } static void @@ -898,9 +886,7 @@ start_cancelled (GCancellable *cancellable, { DBusStartOp *data = user_data; GSimpleAsyncResult *simple; - DBusConnection *connection; - DBusMessage *message; - const char *name; + GVfsRemoteVolumeMonitor *proxy; G_LOCK (proxy_drive); @@ -914,26 +900,15 @@ start_cancelled (GCancellable *cancellable, g_object_unref (simple); /* Now tell the remote drive monitor that the op has been cancelled */ - connection = g_proxy_volume_monitor_get_dbus_connection (data->drive->volume_monitor); - name = g_proxy_volume_monitor_get_dbus_name (data->drive->volume_monitor); - message = dbus_message_new_method_call (name, - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "CancelOperation"); - dbus_message_append_args (message, - DBUS_TYPE_STRING, - &(data->cancellation_id), - DBUS_TYPE_INVALID); + proxy = g_proxy_volume_monitor_get_dbus_proxy (data->drive->volume_monitor); + gvfs_remote_volume_monitor_call_cancel_operation (proxy, + data->cancellation_id, + NULL, + (GAsyncReadyCallback) cancel_operation_reply_cb, + NULL); + g_object_unref (proxy); G_UNLOCK (proxy_drive); - - _g_dbus_connection_call_async (connection, - message, - -1, - (GAsyncDBusCallback) cancel_operation_reply_cb, - NULL); - dbus_message_unref (message); - dbus_connection_unref (connection); } static void @@ -946,9 +921,7 @@ g_proxy_drive_start (GDrive *drive, { GProxyDrive *proxy_drive = G_PROXY_DRIVE (drive); DBusStartOp *data; - DBusConnection *connection; - const char *name; - DBusMessage *message; + GVfsRemoteVolumeMonitor *proxy; G_LOCK (proxy_drive); @@ -987,33 +960,22 @@ g_proxy_drive_start (GDrive *drive, data->mount_op_id = g_proxy_mount_operation_wrap (mount_operation, proxy_drive->volume_monitor); - connection = g_proxy_volume_monitor_get_dbus_connection (proxy_drive->volume_monitor); - name = g_proxy_volume_monitor_get_dbus_name (proxy_drive->volume_monitor); - - message = dbus_message_new_method_call (name, - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "DriveStart"); - dbus_message_append_args (message, - DBUS_TYPE_STRING, - &(proxy_drive->id), - DBUS_TYPE_STRING, - &(data->cancellation_id), - DBUS_TYPE_UINT32, - &(flags), - DBUS_TYPE_STRING, - &(data->mount_op_id), - DBUS_TYPE_INVALID); - G_UNLOCK (proxy_drive); + proxy = g_proxy_volume_monitor_get_dbus_proxy (data->drive->volume_monitor); + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT); /* 30 minute timeout */ + + gvfs_remote_volume_monitor_call_drive_start (proxy, + proxy_drive->id, + data->cancellation_id, + flags, + data->mount_op_id, + NULL, + (GAsyncReadyCallback) start_cb, + data); - _g_dbus_connection_call_async (connection, - message, - G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT, - (GAsyncDBusCallback) start_cb, - data); - dbus_message_unref (message); - dbus_connection_unref (connection); + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), -1); + g_object_unref (proxy); + G_UNLOCK (proxy_drive); out: ; } @@ -1031,24 +993,36 @@ g_proxy_drive_start_finish (GDrive *drive, /* ---------------------------------------------------------------------------------------------------- */ static void -poll_for_media_cb (DBusMessage *reply, - GError *error, - DBusOp *data) +poll_for_media_cb (GVfsRemoteVolumeMonitor *proxy, + GAsyncResult *res, + gpointer user_data) { + DBusOp *data = user_data; + GError *error = NULL; + + gvfs_remote_volume_monitor_call_drive_poll_for_media_finish (proxy, + res, + &error); + if (!g_cancellable_is_cancelled (data->cancellable)) { GSimpleAsyncResult *simple; if (error != NULL) - simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive), - data->callback, - data->user_data, - error); + { + g_dbus_error_strip_remote_error (error); + simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive), + data->callback, + data->user_data, + error); + } else - simple = g_simple_async_result_new (G_OBJECT (data->drive), - data->callback, - data->user_data, - NULL); + { + simple = g_simple_async_result_new (G_OBJECT (data->drive), + data->callback, + data->user_data, + NULL); + } g_simple_async_result_complete (simple); g_object_unref (simple); } @@ -1060,6 +1034,8 @@ poll_for_media_cb (DBusMessage *reply, if (data->cancellable != NULL) g_object_unref (data->cancellable); g_free (data); + if (error != NULL) + g_error_free (error); } static void @@ -1069,10 +1045,8 @@ g_proxy_drive_poll_for_media (GDrive *drive, gpointer user_data) { GProxyDrive *proxy_drive = G_PROXY_DRIVE (drive); - DBusConnection *connection; - const char *name; - DBusMessage *message; DBusOp *data; + GVfsRemoteVolumeMonitor *proxy; G_LOCK (proxy_drive); @@ -1109,29 +1083,17 @@ g_proxy_drive_poll_for_media (GDrive *drive, { data->cancellation_id = g_strdup (""); } + + proxy = g_proxy_volume_monitor_get_dbus_proxy (data->drive->volume_monitor); + gvfs_remote_volume_monitor_call_drive_poll_for_media (proxy, + proxy_drive->id, + data->cancellation_id, + NULL, + (GAsyncReadyCallback) poll_for_media_cb, + data); + g_object_unref (proxy); - connection = g_proxy_volume_monitor_get_dbus_connection (proxy_drive->volume_monitor); - name = g_proxy_volume_monitor_get_dbus_name (proxy_drive->volume_monitor); - - message = dbus_message_new_method_call (name, - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "DrivePollForMedia"); - dbus_message_append_args (message, - DBUS_TYPE_STRING, - &(proxy_drive->id), - DBUS_TYPE_STRING, - &(data->cancellation_id), - DBUS_TYPE_INVALID); G_UNLOCK (proxy_drive); - - _g_dbus_connection_call_async (connection, - message, - -1, - (GAsyncDBusCallback) poll_for_media_cb, - data); - dbus_connection_unref (connection); - dbus_message_unref (message); out: ; } diff --git a/monitor/proxy/gproxydrive.h b/monitor/proxy/gproxydrive.h index ab26244d..206ea1c3 100644 --- a/monitor/proxy/gproxydrive.h +++ b/monitor/proxy/gproxydrive.h @@ -47,17 +47,17 @@ GType g_proxy_drive_get_type (void) G_GNUC_CONST; void g_proxy_drive_register (GIOModule *module); GProxyDrive *g_proxy_drive_new (GProxyVolumeMonitor *volume_monitor); void g_proxy_drive_update (GProxyDrive *drive, - DBusMessageIter *iter); + GVariant *iter); const char *g_proxy_drive_get_id (GProxyDrive *drive); -void g_proxy_drive_handle_start_op_ask_password (GProxyDrive *drive, - DBusMessageIter *iter); +void g_proxy_drive_handle_start_op_ask_password (GProxyDrive *drive, + GVariant *iter); -void g_proxy_drive_handle_start_op_ask_question (GProxyDrive *drive, - DBusMessageIter *iter); +void g_proxy_drive_handle_start_op_ask_question (GProxyDrive *drive, + GVariant *iter); -void g_proxy_drive_handle_start_op_aborted (GProxyDrive *drive, - DBusMessageIter *iter); +void g_proxy_drive_handle_start_op_aborted (GProxyDrive *drive, + GVariant *iter); G_END_DECLS diff --git a/monitor/proxy/gproxymount.c b/monitor/proxy/gproxymount.c index cd3ca49b..88aa955c 100644 --- a/monitor/proxy/gproxymount.c +++ b/monitor/proxy/gproxymount.c @@ -31,8 +31,6 @@ #include <glib/gi18n-lib.h> #include <gio/gio.h> -#include <gvfsdbusutils.h> - #include "gproxyvolumemonitor.h" #include "gproxymount.h" #include "gproxyvolume.h" @@ -145,58 +143,38 @@ g_proxy_mount_has_mount_path (GProxyMount *mount, const char *mount_path) * array:string x-content-types */ +#define MOUNT_STRUCT_TYPE "(&s&s&s&s&sb&sas&sa{sv})" + void g_proxy_mount_update (GProxyMount *mount, - DBusMessageIter *iter) + GVariant *iter) { - DBusMessageIter iter_struct; - DBusMessageIter iter_x_content_types; const char *id; const char *name; const char *gicon_data; const char *uuid; const char *root_uri; - dbus_bool_t can_unmount; + gboolean can_unmount; const char *volume_id; GPtrArray *x_content_types; const gchar *sort_key; + const char *x_content_type; + GVariantIter *iter_content_types; + GVariantIter *iter_expansion; - dbus_message_iter_recurse (iter, &iter_struct); - dbus_message_iter_get_basic (&iter_struct, &id); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &name); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &gicon_data); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &uuid); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &root_uri); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &can_unmount); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &volume_id); - dbus_message_iter_next (&iter_struct); + sort_key = NULL; + g_variant_get (iter, MOUNT_STRUCT_TYPE, + &id, &name, &gicon_data, + &uuid, &root_uri, + &can_unmount, &volume_id, + &iter_content_types, + &sort_key, + &iter_expansion); x_content_types = g_ptr_array_new (); - dbus_message_iter_recurse (&iter_struct, &iter_x_content_types); - while (dbus_message_iter_get_arg_type (&iter_x_content_types) != DBUS_TYPE_INVALID) - { - const char *x_content_type; - dbus_message_iter_get_basic (&iter_x_content_types, &x_content_type); - dbus_message_iter_next (&iter_x_content_types); - g_ptr_array_add (x_content_types, (gpointer) x_content_type); - } + while (g_variant_iter_loop (iter_content_types, "&s", &x_content_type)) + g_ptr_array_add (x_content_types, (gpointer) x_content_type); g_ptr_array_add (x_content_types, NULL); - dbus_message_iter_next (&iter_struct); - - /* make sure we are backwards compat with old daemon instance */ - sort_key = NULL; - if (dbus_message_iter_has_next (&iter_struct)) - { - dbus_message_iter_get_basic (&iter_struct, &sort_key); - dbus_message_iter_next (&iter_struct); - /* TODO: decode expansion, once used */ - } if (mount->id != NULL && strcmp (mount->id, id) != 0) { @@ -237,7 +215,11 @@ g_proxy_mount_update (GProxyMount *mount, mount->x_content_types = g_strdupv ((char **) x_content_types->pdata); mount->sort_key = g_strdup (sort_key); + /* TODO: decode expansion, once used */ + out: + g_variant_iter_free (iter_content_types); + g_variant_iter_free (iter_expansion); g_ptr_array_free (x_content_types, TRUE); } @@ -458,13 +440,20 @@ typedef struct { } DBusOp; static void -cancel_operation_reply_cb (DBusMessage *reply, - GError *error, - gpointer user_data) -{ - if (error != NULL) +cancel_operation_reply_cb (GVfsRemoteVolumeMonitor *proxy, + GAsyncResult *res, + gpointer user_data) +{ + gboolean out_WasCancelled; + GError *error = NULL; + + if (!gvfs_remote_volume_monitor_call_cancel_operation_finish (proxy, + &out_WasCancelled, + res, + &error)) { g_warning ("Error from CancelOperation(): %s", error->message); + g_error_free (error); } } @@ -474,9 +463,7 @@ operation_cancelled (GCancellable *cancellable, { DBusOp *data = user_data; GSimpleAsyncResult *simple; - DBusConnection *connection; - DBusMessage *message; - const char *name; + GVfsRemoteVolumeMonitor *proxy; G_LOCK (proxy_mount); @@ -490,33 +477,29 @@ operation_cancelled (GCancellable *cancellable, g_object_unref (simple); /* Now tell the remote volume monitor that the op has been cancelled */ - connection = g_proxy_volume_monitor_get_dbus_connection (data->mount->volume_monitor); - name = g_proxy_volume_monitor_get_dbus_name (data->mount->volume_monitor); - message = dbus_message_new_method_call (name, - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "CancelOperation"); - dbus_message_append_args (message, - DBUS_TYPE_STRING, - &(data->cancellation_id), - DBUS_TYPE_INVALID); + proxy = g_proxy_volume_monitor_get_dbus_proxy (data->mount->volume_monitor); + gvfs_remote_volume_monitor_call_cancel_operation (proxy, + data->cancellation_id, + NULL, + (GAsyncReadyCallback) cancel_operation_reply_cb, + NULL); + g_object_unref (proxy); G_UNLOCK (proxy_mount); - - _g_dbus_connection_call_async (connection, - message, - -1, - (GAsyncDBusCallback) cancel_operation_reply_cb, - NULL); - dbus_message_unref (message); - dbus_connection_unref (connection); } static void -unmount_cb (DBusMessage *reply, - GError *error, - DBusOp *data) +unmount_cb (GVfsRemoteVolumeMonitor *proxy, + GAsyncResult *res, + gpointer user_data) { + DBusOp *data = user_data; + GError *error = NULL; + + gvfs_remote_volume_monitor_call_mount_unmount_finish (proxy, + res, + &error); + if (data->cancelled_handler_id > 0) g_signal_handler_disconnect (data->cancellable, data->cancelled_handler_id); @@ -524,15 +507,20 @@ unmount_cb (DBusMessage *reply, { GSimpleAsyncResult *simple; if (error != NULL) - simple = g_simple_async_result_new_from_error (G_OBJECT (data->mount), - data->callback, - data->user_data, - error); + { + g_dbus_error_strip_remote_error (error); + simple = g_simple_async_result_new_from_error (G_OBJECT (data->mount), + data->callback, + data->user_data, + error); + } else - simple = g_simple_async_result_new (G_OBJECT (data->mount), - data->callback, - data->user_data, - NULL); + { + simple = g_simple_async_result_new (G_OBJECT (data->mount), + data->callback, + data->user_data, + NULL); + } g_simple_async_result_complete (simple); g_object_unref (simple); } @@ -543,6 +531,8 @@ unmount_cb (DBusMessage *reply, if (data->cancellable != NULL) g_object_unref (data->cancellable); g_free (data); + if (error != NULL) + g_error_free (error); } static void @@ -554,11 +544,8 @@ g_proxy_mount_unmount_with_operation (GMount *mount, gpointer user_data) { GProxyMount *proxy_mount = G_PROXY_MOUNT (mount); - DBusConnection *connection; - const char *name; - DBusMessage *message; DBusOp *data; - dbus_uint32_t _flags = flags; + GVfsRemoteVolumeMonitor *proxy; G_LOCK (proxy_mount); @@ -596,34 +583,23 @@ g_proxy_mount_unmount_with_operation (GMount *mount, { data->cancellation_id = g_strdup (""); } + + proxy = g_proxy_volume_monitor_get_dbus_proxy (proxy_mount->volume_monitor); + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT); /* 30 minute timeout */ + + gvfs_remote_volume_monitor_call_mount_unmount (proxy, + proxy_mount->id, + data->cancellation_id, + flags, + data->mount_op_id, + NULL, + (GAsyncReadyCallback) unmount_cb, + data); + + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), -1); + g_object_unref (proxy); - connection = g_proxy_volume_monitor_get_dbus_connection (proxy_mount->volume_monitor); - name = g_proxy_volume_monitor_get_dbus_name (proxy_mount->volume_monitor); - - message = dbus_message_new_method_call (name, - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "MountUnmount"); - dbus_message_append_args (message, - DBUS_TYPE_STRING, - &(proxy_mount->id), - DBUS_TYPE_STRING, - &(data->cancellation_id), - DBUS_TYPE_UINT32, - &_flags, - DBUS_TYPE_STRING, - &(data->mount_op_id), - DBUS_TYPE_INVALID); G_UNLOCK (proxy_mount); - - _g_dbus_connection_call_async (connection, - message, - G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT, /* 30 minute timeout */ - (GAsyncDBusCallback) unmount_cb, - data); - - dbus_message_unref (message); - dbus_connection_unref (connection); out: ; } diff --git a/monitor/proxy/gproxymount.h b/monitor/proxy/gproxymount.h index c6356518..50262fdf 100644 --- a/monitor/proxy/gproxymount.h +++ b/monitor/proxy/gproxymount.h @@ -47,7 +47,7 @@ GType g_proxy_mount_get_type (void) G_GNUC_CONST; void g_proxy_mount_register (GIOModule *module); GProxyMount *g_proxy_mount_new (GProxyVolumeMonitor *volume_monitor); void g_proxy_mount_update (GProxyMount *mount, - DBusMessageIter *iter); + GVariant *iter); const char *g_proxy_mount_get_id (GProxyMount *mount); gboolean g_proxy_mount_has_mount_path (GProxyMount *mount, const char *mount_path); diff --git a/monitor/proxy/gproxymountoperation.c b/monitor/proxy/gproxymountoperation.c index 8826f318..5253d59e 100644 --- a/monitor/proxy/gproxymountoperation.c +++ b/monitor/proxy/gproxymountoperation.c @@ -27,8 +27,6 @@ #include <sys/types.h> #include <unistd.h> -#include <gvfsdbusutils.h> - #include "gproxymountoperation.h" /* for protecting the id_to_op and id_count */ @@ -109,13 +107,18 @@ g_proxy_mount_operation_wrap (GMountOperation *op, /* ---------------------------------------------------------------------------------------------------- */ static void -mount_op_reply_cb (DBusMessage *reply, - GError *error, - gpointer user_data) +mount_op_reply_cb (GVfsRemoteVolumeMonitor *proxy, + GAsyncResult *res, + gpointer user_data) { - if (error != NULL) + GError *error = NULL; + + if (!gvfs_remote_volume_monitor_call_mount_op_reply_finish (proxy, + res, + &error)) { g_warning ("Error from MountOpReply(): %s", error->message); + g_error_free (error); } } @@ -125,20 +128,15 @@ mount_operation_reply (GMountOperation *mount_operation, gpointer user_data) { ProxyMountOpData *data = user_data; - DBusConnection *connection; - const gchar *name; - DBusMessage *message; + GVfsRemoteVolumeMonitor *proxy; const gchar *user_name; const gchar *domain; const gchar *password; gchar *encoded_password; - dbus_uint32_t password_save; - dbus_uint32_t choice; - dbus_bool_t anonymous; - - connection = g_proxy_volume_monitor_get_dbus_connection (data->monitor); - name = g_proxy_volume_monitor_get_dbus_name (data->monitor); - + gint password_save; + gint choice; + gboolean anonymous; + user_name = g_mount_operation_get_username (mount_operation); domain = g_mount_operation_get_domain (mount_operation); password = g_mount_operation_get_password (mount_operation); @@ -158,79 +156,46 @@ mount_operation_reply (GMountOperation *mount_operation, */ encoded_password = g_base64_encode ((const guchar *) password, (gsize) (strlen (password) + 1)); - message = dbus_message_new_method_call (name, - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "MountOpReply"); - dbus_message_append_args (message, - DBUS_TYPE_STRING, - &(data->id), - DBUS_TYPE_INT32, - &result, - DBUS_TYPE_STRING, - &user_name, - DBUS_TYPE_STRING, - &domain, - DBUS_TYPE_STRING, - &encoded_password, - DBUS_TYPE_INT32, - &password_save, - DBUS_TYPE_INT32, - &choice, - DBUS_TYPE_BOOLEAN, - &anonymous, - DBUS_TYPE_INVALID); - - _g_dbus_connection_call_async (connection, - message, - -1, - (GAsyncDBusCallback) mount_op_reply_cb, - data); - + proxy = g_proxy_volume_monitor_get_dbus_proxy (data->monitor); + gvfs_remote_volume_monitor_call_mount_op_reply (proxy, + data->id, + result, + user_name, + domain, + encoded_password, + password_save, + choice, + anonymous, + NULL, + (GAsyncReadyCallback) mount_op_reply_cb, + data); + g_object_unref (proxy); g_free (encoded_password); - dbus_message_unref (message); - dbus_connection_unref (connection); } /* ---------------------------------------------------------------------------------------------------- */ void -g_proxy_mount_operation_handle_ask_password (const gchar *wrapped_id, - DBusMessageIter *iter) +g_proxy_mount_operation_handle_ask_password (const gchar *wrapped_id, + const gchar *message, + const gchar *default_user, + const gchar *default_domain, + guint flags) { ProxyMountOpData *data; - const gchar *message; - const gchar *default_user; - const gchar *default_domain; - dbus_int32_t flags; g_return_if_fail (wrapped_id != NULL); - g_return_if_fail (iter != NULL); + if (id_to_op == NULL) + goto out; + G_LOCK (proxy_op); data = g_hash_table_lookup (id_to_op, wrapped_id); G_UNLOCK (proxy_op); if (data == NULL) - { - g_warning ("%s: No GMountOperation for id `%s'", - G_STRFUNC, - wrapped_id); - goto out; - } - - dbus_message_iter_get_basic (iter, &message); - dbus_message_iter_next (iter); - - dbus_message_iter_get_basic (iter, &default_user); - dbus_message_iter_next (iter); - - dbus_message_iter_get_basic (iter, &default_domain); - dbus_message_iter_next (iter); - - dbus_message_iter_get_basic (iter, &flags); - dbus_message_iter_next (iter); - + goto out; + if (data->reply_handler_id == 0) { data->reply_handler_id = g_signal_connect (data->op, @@ -253,45 +218,23 @@ g_proxy_mount_operation_handle_ask_password (const gchar *wrapped_id, /* ---------------------------------------------------------------------------------------------------- */ void -g_proxy_mount_operation_handle_ask_question (const gchar *wrapped_id, - DBusMessageIter *iter) +g_proxy_mount_operation_handle_ask_question (const gchar *wrapped_id, + const gchar *message, + const gchar *const *choices) { ProxyMountOpData *data; - const gchar *message; - GPtrArray *choices; - DBusMessageIter iter_array; g_return_if_fail (wrapped_id != NULL); - g_return_if_fail (iter != NULL); - - choices = NULL; + if (id_to_op == NULL) + goto out; + G_LOCK (proxy_op); data = g_hash_table_lookup (id_to_op, wrapped_id); G_UNLOCK (proxy_op); if (data == NULL) - { - g_warning ("%s: No GMountOperation for id `%s'", - G_STRFUNC, - wrapped_id); - goto out; - } - - dbus_message_iter_get_basic (iter, &message); - dbus_message_iter_next (iter); - - choices = g_ptr_array_new (); - dbus_message_iter_recurse (iter, &iter_array); - while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID) - { - const gchar *choice; - dbus_message_iter_get_basic (&iter_array, &choice); - dbus_message_iter_next (&iter_array); - - g_ptr_array_add (choices, g_strdup (choice)); - } - g_ptr_array_add (choices, NULL); + goto out; if (data->reply_handler_id == 0) { @@ -304,70 +247,44 @@ g_proxy_mount_operation_handle_ask_question (const gchar *wrapped_id, g_signal_emit_by_name (data->op, "ask-question", message, - choices->pdata); + choices); out: - g_ptr_array_free (choices, TRUE); + ; } /* ---------------------------------------------------------------------------------------------------- */ void -g_proxy_mount_operation_handle_show_processes (const gchar *wrapped_id, - DBusMessageIter *iter) +g_proxy_mount_operation_handle_show_processes (const gchar *wrapped_id, + const gchar *message, + GVariant *pids, + const gchar *const *choices) { ProxyMountOpData *data; - const gchar *message; - GPtrArray *choices; GArray *processes; - DBusMessageIter iter_array; + GVariantIter iter; + GPid pid; g_return_if_fail (wrapped_id != NULL); - g_return_if_fail (iter != NULL); - choices = NULL; processes = NULL; + if (id_to_op == NULL) + goto out; + G_LOCK (proxy_op); data = g_hash_table_lookup (id_to_op, wrapped_id); G_UNLOCK (proxy_op); if (data == NULL) - { - g_warning ("%s: No GMountOperation for id `%s'", - G_STRFUNC, - wrapped_id); - goto out; - } - - dbus_message_iter_get_basic (iter, &message); - dbus_message_iter_next (iter); - + goto out; + processes = g_array_new (FALSE, FALSE, sizeof (GPid)); - dbus_message_iter_recurse (iter, &iter_array); - while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID) - { - GPid pid; - - dbus_message_iter_get_basic (&iter_array, &pid); - dbus_message_iter_next (&iter_array); - g_array_append_val (processes, pid); - } - - dbus_message_iter_next (iter); - - choices = g_ptr_array_new (); - dbus_message_iter_recurse (iter, &iter_array); - while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID) - { - const gchar *choice; - dbus_message_iter_get_basic (&iter_array, &choice); - dbus_message_iter_next (&iter_array); - - g_ptr_array_add (choices, g_strdup (choice)); - } - g_ptr_array_add (choices, NULL); - + g_variant_iter_init (&iter, pids); + while (g_variant_iter_loop (&iter, "i", &pid)) + g_array_append_val (processes, pid); + if (data->reply_handler_id == 0) { data->reply_handler_id = g_signal_connect (data->op, @@ -380,11 +297,9 @@ g_proxy_mount_operation_handle_show_processes (const gchar *wrapped_id, "show-processes", message, processes, - choices->pdata); + choices); out: - if (choices) - g_ptr_array_free (choices, TRUE); if (processes) g_array_unref (processes); } @@ -392,25 +307,21 @@ g_proxy_mount_operation_handle_show_processes (const gchar *wrapped_id, /* ---------------------------------------------------------------------------------------------------- */ void -g_proxy_mount_operation_handle_aborted (const gchar *wrapped_id, - DBusMessageIter *iter) +g_proxy_mount_operation_handle_aborted (const gchar *wrapped_id) { ProxyMountOpData *data; g_return_if_fail (wrapped_id != NULL); - g_return_if_fail (iter != NULL); + + if (id_to_op == NULL) + goto out; G_LOCK (proxy_op); data = g_hash_table_lookup (id_to_op, wrapped_id); G_UNLOCK (proxy_op); if (data == NULL) - { - g_warning ("%s: No GMountOperation for id `%s'", - G_STRFUNC, - wrapped_id); - goto out; - } + goto out; g_signal_emit_by_name (data->op, "aborted"); @@ -428,13 +339,11 @@ g_proxy_mount_operation_destroy (const gchar *wrapped_id) if (strlen (wrapped_id) == 0) return; + if (id_to_op == NULL) + return; + G_LOCK (proxy_op); - if (!g_hash_table_remove (id_to_op, wrapped_id)) - { - g_warning ("%s: No GMountOperation for id `%s'", - G_STRFUNC, - wrapped_id); - } + g_hash_table_remove (id_to_op, wrapped_id); G_UNLOCK (proxy_op); } diff --git a/monitor/proxy/gproxymountoperation.h b/monitor/proxy/gproxymountoperation.h index a57b50e6..a7d51b8c 100644 --- a/monitor/proxy/gproxymountoperation.h +++ b/monitor/proxy/gproxymountoperation.h @@ -34,17 +34,22 @@ G_BEGIN_DECLS const gchar *g_proxy_mount_operation_wrap (GMountOperation *op, GProxyVolumeMonitor *monitor); -void g_proxy_mount_operation_handle_ask_password (const gchar *wrapped_id, - DBusMessageIter *iter); - -void g_proxy_mount_operation_handle_ask_question (const gchar *wrapped_id, - DBusMessageIter *iter); - -void g_proxy_mount_operation_handle_show_processes (const gchar *wrapped_id, - DBusMessageIter *iter); - -void g_proxy_mount_operation_handle_aborted (const gchar *wrapped_id, - DBusMessageIter *iter); +void g_proxy_mount_operation_handle_ask_password (const gchar *wrapped_id, + const gchar *message, + const gchar *default_user, + const gchar *default_domain, + guint flags); + +void g_proxy_mount_operation_handle_ask_question (const gchar *wrapped_id, + const gchar *message, + const gchar *const *choices); + +void g_proxy_mount_operation_handle_show_processes (const gchar *wrapped_id, + const gchar *message, + GVariant *pids, + const gchar *const *choices); + +void g_proxy_mount_operation_handle_aborted (const gchar *wrapped_id); void g_proxy_mount_operation_destroy (const gchar *wrapped_id); diff --git a/monitor/proxy/gproxyshadowmount.c b/monitor/proxy/gproxyshadowmount.c index b83d2f1b..02ebe879 100644 --- a/monitor/proxy/gproxyshadowmount.c +++ b/monitor/proxy/gproxyshadowmount.c @@ -31,8 +31,6 @@ #include <glib/gi18n-lib.h> #include <gio/gio.h> -#include <gvfsdbusutils.h> - #include "gproxyvolumemonitor.h" #include "gproxyshadowmount.h" #include "gproxyvolume.h" diff --git a/monitor/proxy/gproxyvolume.c b/monitor/proxy/gproxyvolume.c index b6b8c91b..6f600abe 100644 --- a/monitor/proxy/gproxyvolume.c +++ b/monitor/proxy/gproxyvolume.c @@ -31,8 +31,6 @@ #include <glib/gi18n-lib.h> #include <gio/gio.h> -#include <gvfsdbusutils.h> - #include "gproxydrive.h" #include "gproxyvolume.h" #include "gproxymount.h" @@ -193,7 +191,6 @@ g_proxy_volume_new (GProxyVolumeMonitor *volume_monitor) return volume; } - static void union_monitor_mount_added (GVolumeMonitor *union_monitor, GMount *mount, @@ -356,10 +353,11 @@ update_shadow_mount_in_idle (GProxyVolume *volume) * a{sv} expansion */ +#define VOLUME_STRUCT_TYPE "(&s&s&s&s&sbb&s&sa{ss}&sa{sv})" + void g_proxy_volume_update (GProxyVolume *volume, - DBusMessageIter *iter) + GVariant *iter) { - DBusMessageIter iter_struct; const char *id; const char *name; const char *gicon_data; @@ -367,42 +365,24 @@ void g_proxy_volume_update (GProxyVolume *volume, const char *activation_uri; const char *drive_id; const char *mount_id; - dbus_bool_t can_mount; - dbus_bool_t should_automount; + gboolean can_mount; + gboolean should_automount; GHashTable *identifiers; const gchar *sort_key; + GVariantIter *iter_identifiers; + GVariantIter *iter_expansion; - dbus_message_iter_recurse (iter, &iter_struct); - dbus_message_iter_get_basic (&iter_struct, &id); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &name); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &gicon_data); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &uuid); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &activation_uri); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &can_mount); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &should_automount); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &drive_id); - dbus_message_iter_next (&iter_struct); - dbus_message_iter_get_basic (&iter_struct, &mount_id); - dbus_message_iter_next (&iter_struct); - - identifiers = _get_identifiers (&iter_struct); - dbus_message_iter_next (&iter_struct); - - /* make sure we are backwards compat with old daemon instance */ sort_key = NULL; - if (dbus_message_iter_has_next (&iter_struct)) - { - dbus_message_iter_get_basic (&iter_struct, &sort_key); - dbus_message_iter_next (&iter_struct); - /* TODO: decode expansion, once used */ - } + g_variant_get (iter, VOLUME_STRUCT_TYPE, + &id, &name, &gicon_data, + &uuid, &activation_uri, + &can_mount, &should_automount, + &drive_id, &mount_id, + &iter_identifiers, + &sort_key, + &iter_expansion); + + identifiers = _get_identifiers (iter_identifiers); if (volume->id != NULL && strcmp (volume->id, id) != 0) { @@ -448,10 +428,14 @@ void g_proxy_volume_update (GProxyVolume *volume, volume->identifiers = identifiers != NULL ? g_hash_table_ref (identifiers) : NULL; volume->sort_key = g_strdup (sort_key); + /* TODO: decode expansion, once used */ + /* this calls into the union monitor; do it in idle to avoid locking issues */ update_shadow_mount_in_idle (volume); out: + g_variant_iter_free (iter_identifiers); + g_variant_iter_free (iter_expansion); g_hash_table_unref (identifiers); } @@ -741,10 +725,17 @@ typedef struct { } DBusOp; static void -mount_cb (DBusMessage *reply, - GError *error, - DBusOp *data) +mount_cb (GVfsRemoteVolumeMonitor *proxy, + GAsyncResult *res, + gpointer user_data) { + DBusOp *data = user_data; + GError *error = NULL; + + gvfs_remote_volume_monitor_call_volume_mount_finish (proxy, + res, + &error); + if (data->cancelled_handler_id > 0) g_signal_handler_disconnect (data->cancellable, data->cancelled_handler_id); @@ -753,15 +744,20 @@ mount_cb (DBusMessage *reply, GSimpleAsyncResult *simple; if (error != NULL) - simple = g_simple_async_result_new_from_error (G_OBJECT (data->volume), - data->callback, - data->user_data, - error); + { + g_dbus_error_strip_remote_error (error); + simple = g_simple_async_result_new_from_error (G_OBJECT (data->volume), + data->callback, + data->user_data, + error); + } else - simple = g_simple_async_result_new (G_OBJECT (data->volume), - data->callback, - data->user_data, - NULL); + { + simple = g_simple_async_result_new (G_OBJECT (data->volume), + data->callback, + data->user_data, + NULL); + } g_simple_async_result_complete_in_idle (simple); g_object_unref (simple); } @@ -775,6 +771,8 @@ mount_cb (DBusMessage *reply, g_object_unref (data->cancellable); g_free (data); + if (error != NULL) + g_error_free (error); } typedef struct @@ -796,13 +794,20 @@ mount_foreign_callback (GObject *source_object, } static void -cancel_operation_reply_cb (DBusMessage *reply, - GError *error, - gpointer user_data) +cancel_operation_reply_cb (GVfsRemoteVolumeMonitor *proxy, + GAsyncResult *res, + gpointer user_data) { - if (error != NULL) + gboolean out_WasCancelled; + GError *error = NULL; + + if (!gvfs_remote_volume_monitor_call_cancel_operation_finish (proxy, + &out_WasCancelled, + res, + &error)) { g_warning ("Error from CancelOperation(): %s", error->message); + g_error_free (error); } } @@ -812,9 +817,7 @@ mount_cancelled (GCancellable *cancellable, { DBusOp *data = user_data; GSimpleAsyncResult *simple; - DBusConnection *connection; - DBusMessage *message; - const char *name; + GVfsRemoteVolumeMonitor *proxy; G_LOCK (proxy_volume); @@ -828,26 +831,15 @@ mount_cancelled (GCancellable *cancellable, g_object_unref (simple); /* Now tell the remote volume monitor that the op has been cancelled */ - connection = g_proxy_volume_monitor_get_dbus_connection (data->volume->volume_monitor); - name = g_proxy_volume_monitor_get_dbus_name (data->volume->volume_monitor); - message = dbus_message_new_method_call (name, - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "CancelOperation"); - dbus_message_append_args (message, - DBUS_TYPE_STRING, - &(data->cancellation_id), - DBUS_TYPE_INVALID); + proxy = g_proxy_volume_monitor_get_dbus_proxy (data->volume->volume_monitor); + gvfs_remote_volume_monitor_call_cancel_operation (proxy, + data->cancellation_id, + NULL, + (GAsyncReadyCallback) cancel_operation_reply_cb, + NULL); + g_object_unref (proxy); G_UNLOCK (proxy_volume); - - _g_dbus_connection_call_async (connection, - message, - -1, - (GAsyncDBusCallback) cancel_operation_reply_cb, - NULL); - dbus_message_unref (message); - dbus_connection_unref (connection); } static void @@ -887,10 +879,7 @@ g_proxy_volume_mount (GVolume *volume, else { DBusOp *data; - DBusConnection *connection; - const char *name; - DBusMessage *message; - dbus_uint32_t _flags = flags; + GVfsRemoteVolumeMonitor *proxy; if (g_cancellable_is_cancelled (cancellable)) { @@ -927,32 +916,22 @@ g_proxy_volume_mount (GVolume *volume, data->mount_op_id = g_proxy_mount_operation_wrap (mount_operation, proxy_volume->volume_monitor); - connection = g_proxy_volume_monitor_get_dbus_connection (proxy_volume->volume_monitor); - name = g_proxy_volume_monitor_get_dbus_name (proxy_volume->volume_monitor); - - message = dbus_message_new_method_call (name, - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "VolumeMount"); - dbus_message_append_args (message, - DBUS_TYPE_STRING, - &(proxy_volume->id), - DBUS_TYPE_STRING, - &(data->cancellation_id), - DBUS_TYPE_UINT32, - &_flags, - DBUS_TYPE_STRING, - &(data->mount_op_id), - DBUS_TYPE_INVALID); - G_UNLOCK (proxy_volume); + proxy = g_proxy_volume_monitor_get_dbus_proxy (proxy_volume->volume_monitor); + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT); /* 30 minute timeout */ - _g_dbus_connection_call_async (connection, - message, - G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT, /* 30 minute timeout */ - (GAsyncDBusCallback) mount_cb, - data); - dbus_message_unref (message); - dbus_connection_unref (connection); + gvfs_remote_volume_monitor_call_volume_mount (proxy, + proxy_volume->id, + data->cancellation_id, + flags, + data->mount_op_id, + NULL, + (GAsyncReadyCallback) mount_cb, + data); + + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), -1); + g_object_unref (proxy); + + G_UNLOCK (proxy_volume); } out: diff --git a/monitor/proxy/gproxyvolume.h b/monitor/proxy/gproxyvolume.h index 953b8008..0c6a2c42 100644 --- a/monitor/proxy/gproxyvolume.h +++ b/monitor/proxy/gproxyvolume.h @@ -47,7 +47,7 @@ struct _GProxyVolumeClass { GType g_proxy_volume_get_type (void) G_GNUC_CONST; GProxyVolume *g_proxy_volume_new (GProxyVolumeMonitor *volume_monitor); void g_proxy_volume_update (GProxyVolume *volume, - DBusMessageIter *iter); + GVariant *iter); const char *g_proxy_volume_get_id (GProxyVolume *volume); void g_proxy_volume_register (GIOModule *module); diff --git a/monitor/proxy/gproxyvolumemonitor.c b/monitor/proxy/gproxyvolumemonitor.c index 2c974d14..6aab4dcc 100644 --- a/monitor/proxy/gproxyvolumemonitor.c +++ b/monitor/proxy/gproxyvolumemonitor.c @@ -35,30 +35,30 @@ #include <glib.h> #include <glib/gi18n-lib.h> #include <gio/gio.h> -#include <gvfsdbusutils.h> #include "gproxyvolumemonitor.h" #include "gproxymount.h" #include "gproxyvolume.h" #include "gproxydrive.h" #include "gproxymountoperation.h" +#include "gvfsvolumemonitordbus.h" G_LOCK_DEFINE_STATIC(proxy_vm); -static DBusConnection *the_session_bus = NULL; -static gboolean the_session_bus_is_integrated = FALSE; +static GDBusConnection *the_session_bus = NULL; static GHashTable *the_volume_monitors = NULL; struct _GProxyVolumeMonitor { GNativeVolumeMonitor parent; - DBusConnection *session_bus; + + guint name_owner_id; + GVfsRemoteVolumeMonitor *proxy; GHashTable *drives; GHashTable *volumes; GHashTable *mounts; - /* The unique D-Bus name of the remote monitor or NULL if disconnected */ - gchar *unique_name; + gulong name_watcher_id; }; G_DEFINE_DYNAMIC_TYPE_EXTENDED (GProxyVolumeMonitor, @@ -67,9 +67,9 @@ G_DEFINE_DYNAMIC_TYPE_EXTENDED (GProxyVolumeMonitor, G_TYPE_FLAG_ABSTRACT, {}) -static void seed_monitor (GProxyVolumeMonitor *monitor); +static gboolean g_proxy_volume_monitor_setup_session_bus_connection (void); -static DBusHandlerResult filter_function (DBusConnection *connection, DBusMessage *message, void *user_data); +static void seed_monitor (GProxyVolumeMonitor *monitor); static void signal_emit_in_idle (gpointer object, const char *signal_name, gpointer other_object); @@ -99,25 +99,6 @@ static is_supported_func is_supported_funcs[] = { NULL }; -static char * -get_match_rule_for_signals (GProxyVolumeMonitor *monitor) -{ - return g_strdup_printf ("type='signal'," - "interface='org.gtk.Private.RemoteVolumeMonitor'," - "sender='%s',", - g_proxy_volume_monitor_get_dbus_name (monitor)); -} - -static char * -get_match_rule_for_name_owner_changed (GProxyVolumeMonitor *monitor) -{ - return g_strdup_printf ("type='signal'," - "interface='org.freedesktop.DBus'," - "member='NameOwnerChanged'," - "arg0='%s'", - g_proxy_volume_monitor_get_dbus_name (monitor)); -} - static void g_proxy_volume_monitor_finalize (GObject *object) { @@ -365,6 +346,562 @@ get_mount_for_mount_path (const char *mount_path, return mount; } +static void +drive_changed (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + GVariant *arg_drive, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + GProxyDrive *d; + + G_LOCK (proxy_vm); + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + if (strcmp (arg_dbus_name, klass->dbus_name) != 0) + goto not_for_us; + + d = g_hash_table_lookup (monitor->drives, arg_id); + if (d != NULL) + { + g_proxy_drive_update (d, arg_drive); + signal_emit_in_idle (d, "changed", NULL); + signal_emit_in_idle (monitor, "drive-changed", d); + } + + not_for_us: + G_UNLOCK (proxy_vm); +} + +static void +drive_connected (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + GVariant *arg_drive, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + GProxyDrive *d; + + G_LOCK (proxy_vm); + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + if (strcmp (arg_dbus_name, klass->dbus_name) != 0) + goto not_for_us; + + d = g_hash_table_lookup (monitor->drives, arg_id); + if (d == NULL) + { + d = g_proxy_drive_new (monitor); + g_proxy_drive_update (d, arg_drive); + g_hash_table_insert (monitor->drives, g_strdup (g_proxy_drive_get_id (d)), d); + signal_emit_in_idle (monitor, "drive-connected", d); + } + + not_for_us: + G_UNLOCK (proxy_vm); +} + +static void +drive_disconnected (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + GVariant *arg_drive, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + GProxyDrive *d; + + G_LOCK (proxy_vm); + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + if (strcmp (arg_dbus_name, klass->dbus_name) != 0) + goto not_for_us; + + d = g_hash_table_lookup (monitor->drives, arg_id); + if (d != NULL) + { + g_object_ref (d); + g_hash_table_remove (monitor->drives, arg_id); + signal_emit_in_idle (d, "disconnected", NULL); + signal_emit_in_idle (monitor, "drive-disconnected", d); + g_object_unref (d); + } + + not_for_us: + G_UNLOCK (proxy_vm); +} + +static void +drive_eject_button (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + GVariant *arg_drive, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + GProxyDrive *d; + + G_LOCK (proxy_vm); + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + if (strcmp (arg_dbus_name, klass->dbus_name) != 0) + goto not_for_us; + + d = g_hash_table_lookup (monitor->drives, arg_id); + if (d != NULL) + { + signal_emit_in_idle (d, "eject-button", NULL); + signal_emit_in_idle (monitor, "drive-eject-button", d); + } + + not_for_us: + G_UNLOCK (proxy_vm); +} + +static void +drive_stop_button (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + GVariant *arg_drive, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + GProxyDrive *d; + + G_LOCK (proxy_vm); + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + if (strcmp (arg_dbus_name, klass->dbus_name) != 0) + goto not_for_us; + + d = g_hash_table_lookup (monitor->drives, arg_id); + if (d != NULL) + { + signal_emit_in_idle (d, "stop-button", NULL); + signal_emit_in_idle (monitor, "drive-stop-button", d); + } + + not_for_us: + G_UNLOCK (proxy_vm); +} + +static void +mount_added (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + GVariant *arg_mount, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + GProxyMount *m; + + G_LOCK (proxy_vm); + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + if (strcmp (arg_dbus_name, klass->dbus_name) != 0) + goto not_for_us; + + m = g_hash_table_lookup (monitor->mounts, arg_id); + if (m == NULL) + { + m = g_proxy_mount_new (monitor); + g_proxy_mount_update (m, arg_mount); + g_hash_table_insert (monitor->mounts, g_strdup (g_proxy_mount_get_id (m)), m); + signal_emit_in_idle (monitor, "mount-added", m); + } + + not_for_us: + G_UNLOCK (proxy_vm); +} + +static void +mount_changed (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + GVariant *arg_mount, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + GProxyMount *m; + + G_LOCK (proxy_vm); + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + if (strcmp (arg_dbus_name, klass->dbus_name) != 0) + goto not_for_us; + + m = g_hash_table_lookup (monitor->mounts, arg_id); + if (m != NULL) + { + g_proxy_mount_update (m, arg_mount); + signal_emit_in_idle (m, "changed", NULL); + signal_emit_in_idle (monitor, "mount-changed", m); + } + + not_for_us: + G_UNLOCK (proxy_vm); +} + +static void +mount_pre_unmount (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + GVariant *arg_mount, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + GProxyMount *m; + + G_LOCK (proxy_vm); + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + if (strcmp (arg_dbus_name, klass->dbus_name) != 0) + goto not_for_us; + + m = g_hash_table_lookup (monitor->mounts, arg_id); + if (m != NULL) + { + signal_emit_in_idle (m, "pre-unmount", NULL); + signal_emit_in_idle (monitor, "mount-pre-unmount", m); + } + + not_for_us: + G_UNLOCK (proxy_vm); +} + +static void +mount_removed (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + GVariant *arg_mount, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + GProxyMount *m; + + G_LOCK (proxy_vm); + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + if (strcmp (arg_dbus_name, klass->dbus_name) != 0) + goto not_for_us; + + m = g_hash_table_lookup (monitor->mounts, arg_id); + if (m != NULL) + { + g_object_ref (m); + g_hash_table_remove (monitor->mounts, arg_id); + signal_emit_in_idle (m, "unmounted", NULL); + signal_emit_in_idle (monitor, "mount-removed", m); + g_object_unref (m); + } + + not_for_us: + G_UNLOCK (proxy_vm); +} + +static void +mount_op_aborted (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + + G_LOCK (proxy_vm); + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + if (strcmp (arg_dbus_name, klass->dbus_name) != 0) + goto not_for_us; + + g_proxy_mount_operation_handle_aborted (arg_id); + + not_for_us: + G_UNLOCK (proxy_vm); +} + +static void +mount_op_ask_password (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + const gchar *arg_message_to_show, + const gchar *arg_default_user, + const gchar *arg_default_domain, + guint arg_flags, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + + G_LOCK (proxy_vm); + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + if (strcmp (arg_dbus_name, klass->dbus_name) != 0) + goto not_for_us; + + g_proxy_mount_operation_handle_ask_password (arg_id, + arg_message_to_show, + arg_default_user, + arg_default_domain, + arg_flags); + + not_for_us: + G_UNLOCK (proxy_vm); +} + +static void +mount_op_ask_question (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + const gchar *arg_message_to_show, + const gchar *const *arg_choices, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + + G_LOCK (proxy_vm); + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + if (strcmp (arg_dbus_name, klass->dbus_name) != 0) + goto not_for_us; + + g_proxy_mount_operation_handle_ask_question (arg_id, + arg_message_to_show, + arg_choices); + + not_for_us: + G_UNLOCK (proxy_vm); +} + +static void +mount_op_show_processes (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + const gchar *arg_message_to_show, + GVariant *arg_pid, + const gchar *const *arg_choices, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + + G_LOCK (proxy_vm); + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + if (strcmp (arg_dbus_name, klass->dbus_name) != 0) + goto not_for_us; + + g_proxy_mount_operation_handle_show_processes (arg_id, + arg_message_to_show, + arg_pid, + arg_choices); + + not_for_us: + G_UNLOCK (proxy_vm); +} + +static void +volume_added (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + GVariant *arg_volume, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + GProxyVolume *v; + + G_LOCK (proxy_vm); + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + if (strcmp (arg_dbus_name, klass->dbus_name) != 0) + goto not_for_us; + + v = g_hash_table_lookup (monitor->volumes, arg_id); + if (v == NULL) + { + v = g_proxy_volume_new (monitor); + g_proxy_volume_update (v, arg_volume); + g_hash_table_insert (monitor->volumes, g_strdup (g_proxy_volume_get_id (v)), v); + signal_emit_in_idle (monitor, "volume-added", v); + } + + not_for_us: + G_UNLOCK (proxy_vm); +} + +static void +volume_changed (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + GVariant *arg_volume, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + GProxyVolume *v; + + G_LOCK (proxy_vm); + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + if (strcmp (arg_dbus_name, klass->dbus_name) != 0) + goto not_for_us; + + v = g_hash_table_lookup (monitor->volumes, arg_id); + if (v != NULL) + { + GProxyShadowMount *shadow_mount; + + g_proxy_volume_update (v, arg_volume); + signal_emit_in_idle (v, "changed", NULL); + signal_emit_in_idle (monitor, "volume-changed", v); + + shadow_mount = g_proxy_volume_get_shadow_mount (v); + if (shadow_mount != NULL) + { + signal_emit_in_idle (shadow_mount, "changed", NULL); + signal_emit_in_idle (monitor, "mount-changed", shadow_mount); + g_object_unref (shadow_mount); + } + } + + not_for_us: + G_UNLOCK (proxy_vm); +} + +static void +volume_removed (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + GVariant *arg_volume, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + GProxyVolume *v; + + G_LOCK (proxy_vm); + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + if (strcmp (arg_dbus_name, klass->dbus_name) != 0) + goto not_for_us; + + v = g_hash_table_lookup (monitor->volumes, arg_id); + if (v != NULL) + { + g_object_ref (v); + g_hash_table_remove (monitor->volumes, arg_id); + signal_emit_in_idle (v, "removed", NULL); + signal_emit_in_idle (monitor, "volume-removed", v); + dispose_in_idle (v); + g_object_unref (v); + } + + not_for_us: + G_UNLOCK (proxy_vm); +} + +static void +on_name_owner_appeared (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GHashTableIter hash_iter; + GProxyDrive *drive; + GProxyVolume *volume; + GProxyMount *mount; + + seed_monitor (monitor); + + /* emit signals for all the drives/volumes/mounts "added" */ + g_hash_table_iter_init (&hash_iter, monitor->drives); + while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &drive)) + signal_emit_in_idle (monitor, "drive-connected", drive); + + g_hash_table_iter_init (&hash_iter, monitor->volumes); + while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &volume)) + signal_emit_in_idle (monitor, "volume-added", volume); + + g_hash_table_iter_init (&hash_iter, monitor->mounts); + while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &mount)) + signal_emit_in_idle (monitor, "mount-added", mount); +} + +static void +on_name_owner_vanished (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); + GProxyVolumeMonitorClass *klass; + GHashTableIter hash_iter; + GProxyDrive *drive; + GProxyVolume *volume; + GProxyMount *mount; + + klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); + + g_warning ("Owner of %s of volume monitor %s disconnected from the bus; removing drives/volumes/mounts", + name, + klass->dbus_name); + + g_hash_table_iter_init (&hash_iter, monitor->mounts); + while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &mount)) + { + signal_emit_in_idle (mount, "unmounted", NULL); + signal_emit_in_idle (monitor, "mount-removed", mount); + } + g_hash_table_remove_all (monitor->mounts); + + g_hash_table_iter_init (&hash_iter, monitor->volumes); + while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &volume)) + { + signal_emit_in_idle (volume, "removed", NULL); + signal_emit_in_idle (monitor, "volume-removed", volume); + } + g_hash_table_remove_all (monitor->volumes); + + g_hash_table_iter_init (&hash_iter, monitor->drives); + while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &drive)) + { + signal_emit_in_idle (drive, "disconnected", NULL); + signal_emit_in_idle (monitor, "drive-disconnected", drive); + } + g_hash_table_remove_all (monitor->drives); + + /* TODO: maybe try to relaunch the monitor? */ +} + static GObject * g_proxy_volume_monitor_constructor (GType type, guint n_construct_properties, @@ -374,8 +911,8 @@ g_proxy_volume_monitor_constructor (GType type, GProxyVolumeMonitor *monitor; GProxyVolumeMonitorClass *klass; GObjectClass *parent_class; - DBusError dbus_error; - char *match_rule; + GError *error; + const char *dbus_name; G_LOCK (proxy_vm); @@ -387,6 +924,8 @@ g_proxy_volume_monitor_constructor (GType type, goto out; } + dbus_name = klass->dbus_name; + /* Invoke parent constructor. */ klass = G_PROXY_VOLUME_MONITOR_CLASS (g_type_class_peek (G_TYPE_PROXY_VOLUME_MONITOR)); parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass)); @@ -396,37 +935,52 @@ g_proxy_volume_monitor_constructor (GType type, monitor = G_PROXY_VOLUME_MONITOR (object); - dbus_error_init (&dbus_error); - monitor->session_bus = dbus_connection_ref (the_session_bus); + error = NULL; + monitor->proxy = gvfs_remote_volume_monitor_proxy_new_sync (the_session_bus, + G_DBUS_PROXY_FLAGS_NONE, + dbus_name, + "/org/gtk/Private/RemoteVolumeMonitor", + NULL, + &error); + if (monitor->proxy == NULL) + { + g_printerr ("Error creating proxy: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); + goto out; + } + + /* listen to volume monitor signals */ + g_signal_connect (monitor->proxy, "drive-changed", G_CALLBACK (drive_changed), monitor); + g_signal_connect (monitor->proxy, "drive-connected", G_CALLBACK (drive_connected), monitor); + g_signal_connect (monitor->proxy, "drive-disconnected", G_CALLBACK (drive_disconnected), monitor); + g_signal_connect (monitor->proxy, "drive-eject-button", G_CALLBACK (drive_eject_button), monitor); + g_signal_connect (monitor->proxy, "drive-stop-button", G_CALLBACK (drive_stop_button), monitor); + g_signal_connect (monitor->proxy, "mount-added", G_CALLBACK (mount_added), monitor); + g_signal_connect (monitor->proxy, "mount-changed", G_CALLBACK (mount_changed), monitor); + g_signal_connect (monitor->proxy, "mount-op-aborted", G_CALLBACK (mount_op_aborted), monitor); + g_signal_connect (monitor->proxy, "mount-op-ask-password", G_CALLBACK (mount_op_ask_password), monitor); + g_signal_connect (monitor->proxy, "mount-op-ask-question", G_CALLBACK (mount_op_ask_question), monitor); + g_signal_connect (monitor->proxy, "mount-op-show-processes", G_CALLBACK (mount_op_show_processes), monitor); + g_signal_connect (monitor->proxy, "mount-pre-unmount", G_CALLBACK (mount_pre_unmount), monitor); + g_signal_connect (monitor->proxy, "mount-removed", G_CALLBACK (mount_removed), monitor); + g_signal_connect (monitor->proxy, "volume-added", G_CALLBACK (volume_added), monitor); + g_signal_connect (monitor->proxy, "volume-changed", G_CALLBACK (volume_changed), monitor); + g_signal_connect (monitor->proxy, "volume-removed", G_CALLBACK (volume_removed), monitor); + monitor->drives = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); monitor->volumes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); monitor->mounts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - dbus_connection_add_filter (monitor->session_bus, filter_function, monitor, NULL); - - /* listen to volume monitor signals */ - match_rule = get_match_rule_for_signals (monitor); - dbus_bus_add_match (monitor->session_bus, - match_rule, - &dbus_error); - if (dbus_error_is_set (&dbus_error)) { - g_warning ("cannot add match rule '%s': %s: %s", match_rule, dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - } - g_free (match_rule); - /* listen to when the owner of the service appears/disappears */ - match_rule = get_match_rule_for_name_owner_changed (monitor); - dbus_bus_add_match (monitor->session_bus, - match_rule, - &dbus_error); - if (dbus_error_is_set (&dbus_error)) { - g_warning ("cannot add match rule '%s': %s: %s", match_rule, dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - } - g_free (match_rule); - - seed_monitor (monitor); + /* this will automatically call on_name_owner_appeared() when the daemon is ready and seed drives/volumes/mounts */ + monitor->name_watcher_id = g_bus_watch_name_on_connection (the_session_bus, + dbus_name, + G_BUS_NAME_WATCHER_FLAGS_AUTO_START, + on_name_owner_appeared, + on_name_owner_vanished, + monitor, + NULL); g_hash_table_insert (the_volume_monitors, (gpointer) type, object); @@ -491,336 +1045,10 @@ dispose_in_idle (gpointer object) g_idle_add ((GSourceFunc) dispose_in_idle_do, g_object_ref (object)); } - - -static DBusHandlerResult -filter_function (DBusConnection *connection, DBusMessage *message, void *user_data) -{ - GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data); - DBusMessageIter iter; - const char *id; - const char *the_dbus_name; - const char *member; - GProxyDrive *drive; - GProxyVolume *volume; - GProxyMount *mount; - GProxyVolumeMonitorClass *klass; - - G_LOCK (proxy_vm); - - klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor)); - - member = dbus_message_get_member (message); - - if (dbus_message_is_signal (message, "org.freedesktop.DBus", "NameOwnerChanged")) - { - GHashTableIter hash_iter; - GProxyMount *mount; - GProxyVolume *volume; - GProxyDrive *drive; - const gchar *name; - const gchar *old_owner; - const gchar *new_owner; - - dbus_message_iter_init (message, &iter); - dbus_message_iter_get_basic (&iter, &name); - dbus_message_iter_next (&iter); - dbus_message_iter_get_basic (&iter, &old_owner); - dbus_message_iter_next (&iter); - dbus_message_iter_get_basic (&iter, &new_owner); - dbus_message_iter_next (&iter); - - if (strcmp (name, klass->dbus_name) != 0) - goto not_for_us; - - if (monitor->unique_name != NULL && g_strcmp0 (new_owner, monitor->unique_name) != 0) - { - g_warning ("Owner %s of volume monitor %s disconnected from the bus; removing drives/volumes/mounts", - monitor->unique_name, - klass->dbus_name); - - g_hash_table_iter_init (&hash_iter, monitor->mounts); - while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &mount)) - { - signal_emit_in_idle (mount, "unmounted", NULL); - signal_emit_in_idle (monitor, "mount-removed", mount); - } - g_hash_table_remove_all (monitor->mounts); - - g_hash_table_iter_init (&hash_iter, monitor->volumes); - while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &volume)) - { - signal_emit_in_idle (volume, "removed", NULL); - signal_emit_in_idle (monitor, "volume-removed", volume); - } - g_hash_table_remove_all (monitor->volumes); - - g_hash_table_iter_init (&hash_iter, monitor->drives); - while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &drive)) - { - signal_emit_in_idle (drive, "disconnected", NULL); - signal_emit_in_idle (monitor, "drive-disconnected", drive); - } - g_hash_table_remove_all (monitor->drives); - - g_free (monitor->unique_name); - monitor->unique_name = NULL; - - /* TODO: maybe try to relaunch the monitor? */ - - } - - if (strlen (new_owner) > 0 && monitor->unique_name == NULL) - { - g_warning ("New owner %s for volume monitor %s connected to the bus; seeding drives/volumes/mounts", - new_owner, - klass->dbus_name); - - seed_monitor (monitor); - - /* emit signals for all the drives/volumes/mounts "added" */ - g_hash_table_iter_init (&hash_iter, monitor->drives); - while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &drive)) - signal_emit_in_idle (monitor, "drive-connected", drive); - - g_hash_table_iter_init (&hash_iter, monitor->volumes); - while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &volume)) - signal_emit_in_idle (monitor, "volume-added", volume); - - g_hash_table_iter_init (&hash_iter, monitor->mounts); - while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &mount)) - signal_emit_in_idle (monitor, "mount-added", mount); - } - - } - else if (dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveChanged") || - dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveConnected") || - dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveDisconnected") || - dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveEjectButton") || - dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveStopButton")) - { - - dbus_message_iter_init (message, &iter); - dbus_message_iter_get_basic (&iter, &the_dbus_name); - dbus_message_iter_next (&iter); - dbus_message_iter_get_basic (&iter, &id); - dbus_message_iter_next (&iter); - - if (strcmp (the_dbus_name, klass->dbus_name) != 0) - goto not_for_us; - - if (strcmp (member, "DriveChanged") == 0) - { - drive = g_hash_table_lookup (monitor->drives, id); - if (drive != NULL) - { - g_proxy_drive_update (drive, &iter); - signal_emit_in_idle (drive, "changed", NULL); - signal_emit_in_idle (monitor, "drive-changed", drive); - } - } - else if (strcmp (member, "DriveConnected") == 0) - { - drive = g_hash_table_lookup (monitor->drives, id); - if (drive == NULL) - { - drive = g_proxy_drive_new (monitor); - g_proxy_drive_update (drive, &iter); - g_hash_table_insert (monitor->drives, g_strdup (g_proxy_drive_get_id (drive)), drive); - signal_emit_in_idle (monitor, "drive-connected", drive); - } - } - else if (strcmp (member, "DriveDisconnected") == 0) - { - drive = g_hash_table_lookup (monitor->drives, id); - if (drive != NULL) - { - g_object_ref (drive); - g_hash_table_remove (monitor->drives, id); - signal_emit_in_idle (drive, "disconnected", NULL); - signal_emit_in_idle (monitor, "drive-disconnected", drive); - g_object_unref (drive); - } - } - else if (strcmp (member, "DriveEjectButton") == 0) - { - drive = g_hash_table_lookup (monitor->drives, id); - if (drive != NULL) - { - signal_emit_in_idle (drive, "eject-button", NULL); - signal_emit_in_idle (monitor, "drive-eject-button", drive); - } - } - else if (strcmp (member, "DriveStopButton") == 0) - { - drive = g_hash_table_lookup (monitor->drives, id); - if (drive != NULL) - { - signal_emit_in_idle (drive, "stop-button", NULL); - signal_emit_in_idle (monitor, "drive-stop-button", drive); - } - } - - } - else if (dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "VolumeChanged") || - dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "VolumeAdded") || - dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "VolumeRemoved")) - { - dbus_message_iter_init (message, &iter); - dbus_message_iter_get_basic (&iter, &the_dbus_name); - dbus_message_iter_next (&iter); - dbus_message_iter_get_basic (&iter, &id); - dbus_message_iter_next (&iter); - - if (strcmp (the_dbus_name, klass->dbus_name) != 0) - goto not_for_us; - - if (strcmp (member, "VolumeChanged") == 0) - { - volume = g_hash_table_lookup (monitor->volumes, id); - if (volume != NULL) - { - GProxyShadowMount *shadow_mount; - - g_proxy_volume_update (volume, &iter); - signal_emit_in_idle (volume, "changed", NULL); - signal_emit_in_idle (monitor, "volume-changed", volume); - - shadow_mount = g_proxy_volume_get_shadow_mount (volume); - if (shadow_mount != NULL) - { - signal_emit_in_idle (shadow_mount, "changed", NULL); - signal_emit_in_idle (monitor, "mount-changed", shadow_mount); - g_object_unref (shadow_mount); - } - } - } - else if (strcmp (member, "VolumeAdded") == 0) - { - volume = g_hash_table_lookup (monitor->volumes, id); - if (volume == NULL) - { - volume = g_proxy_volume_new (monitor); - g_proxy_volume_update (volume, &iter); - g_hash_table_insert (monitor->volumes, g_strdup (g_proxy_volume_get_id (volume)), volume); - signal_emit_in_idle (monitor, "volume-added", volume); - } - } - else if (strcmp (member, "VolumeRemoved") == 0) - { - volume = g_hash_table_lookup (monitor->volumes, id); - if (volume != NULL) - { - g_object_ref (volume); - g_hash_table_remove (monitor->volumes, id); - signal_emit_in_idle (volume, "removed", NULL); - signal_emit_in_idle (monitor, "volume-removed", volume); - dispose_in_idle (volume); - g_object_unref (volume); - } - } - - } - else if (dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "MountChanged") || - dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "MountAdded") || - dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "MountPreUnmount") || - dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "MountRemoved")) - { - - dbus_message_iter_init (message, &iter); - dbus_message_iter_get_basic (&iter, &the_dbus_name); - dbus_message_iter_next (&iter); - dbus_message_iter_get_basic (&iter, &id); - dbus_message_iter_next (&iter); - - if (strcmp (the_dbus_name, klass->dbus_name) != 0) - goto not_for_us; - - if (strcmp (member, "MountChanged") == 0) - { - mount = g_hash_table_lookup (monitor->mounts, id); - if (mount != NULL) - { - g_proxy_mount_update (mount, &iter); - signal_emit_in_idle (mount, "changed", NULL); - signal_emit_in_idle (monitor, "mount-changed", mount); - } - } - else if (strcmp (member, "MountAdded") == 0) - { - mount = g_hash_table_lookup (monitor->mounts, id); - if (mount == NULL) - { - mount = g_proxy_mount_new (monitor); - g_proxy_mount_update (mount, &iter); - g_hash_table_insert (monitor->mounts, g_strdup (g_proxy_mount_get_id (mount)), mount); - signal_emit_in_idle (monitor, "mount-added", mount); - } - } - else if (strcmp (member, "MountPreUnmount") == 0) - { - mount = g_hash_table_lookup (monitor->mounts, id); - if (mount != NULL) - { - signal_emit_in_idle (mount, "pre-unmount", NULL); - signal_emit_in_idle (monitor, "mount-pre-unmount", mount); - } - } - else if (strcmp (member, "MountRemoved") == 0) - { - mount = g_hash_table_lookup (monitor->mounts, id); - if (mount != NULL) - { - g_object_ref (mount); - g_hash_table_remove (monitor->mounts, id); - signal_emit_in_idle (mount, "unmounted", NULL); - signal_emit_in_idle (monitor, "mount-removed", mount); - g_object_unref (mount); - } - } - } - else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "MountOpAskPassword") || - dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "MountOpAskQuestion") || - dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "MountOpShowProcesses") || - dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "MountOpAborted")) - { - dbus_message_iter_init (message, &iter); - dbus_message_iter_get_basic (&iter, &the_dbus_name); - dbus_message_iter_next (&iter); - dbus_message_iter_get_basic (&iter, &id); - dbus_message_iter_next (&iter); - - if (strcmp (the_dbus_name, klass->dbus_name) != 0) - goto not_for_us; - - if (strcmp (member, "MountOpAskPassword") == 0) - { - g_proxy_mount_operation_handle_ask_password (id, &iter); - } - else if (strcmp (member, "MountOpAskQuestion") == 0) - { - g_proxy_mount_operation_handle_ask_question (id, &iter); - } - else if (strcmp (member, "MountOpShowProcesses") == 0) - { - g_proxy_mount_operation_handle_show_processes (id, &iter); - } - else if (strcmp (member, "MountOpAborted") == 0) - { - g_proxy_mount_operation_handle_aborted (id, &iter); - } - } - - not_for_us: - G_UNLOCK (proxy_vm); - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - static void g_proxy_volume_monitor_init (GProxyVolumeMonitor *monitor) { - g_proxy_volume_monitor_setup_session_bus_connection (TRUE); + g_proxy_volume_monitor_setup_session_bus_connection (); } static void @@ -855,6 +1083,7 @@ static void g_proxy_volume_monitor_class_intern_init_pre (GProxyVolumeMonitorClass *klass, gconstpointer class_data) { ProxyClassData *data = (ProxyClassData *) class_data; + klass->dbus_name = g_strdup (data->dbus_name); klass->is_native = data->is_native; klass->is_supported_nr = data->is_supported_nr; @@ -864,56 +1093,45 @@ g_proxy_volume_monitor_class_intern_init_pre (GProxyVolumeMonitorClass *klass, g static gboolean is_remote_monitor_supported (const char *dbus_name) { - DBusMessage *message; - DBusMessage *reply; - DBusError dbus_error; - dbus_bool_t is_supported; + gboolean is_supported; + GVfsRemoteVolumeMonitor *proxy; + GError *error; - message = NULL; - reply = NULL; is_supported = FALSE; + error = NULL; - message = dbus_message_new_method_call (dbus_name, - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "IsSupported"); - if (message == NULL) - { - g_warning ("Cannot allocate memory for DBusMessage"); - goto fail; - } - dbus_error_init (&dbus_error); - reply = dbus_connection_send_with_reply_and_block (the_session_bus, - message, - -1, - &dbus_error); - if (dbus_error_is_set (&dbus_error)) + proxy = gvfs_remote_volume_monitor_proxy_new_sync (the_session_bus, + G_DBUS_PROXY_FLAGS_NONE, + dbus_name, + "/org/gtk/Private/RemoteVolumeMonitor", + NULL, + &error); + if (proxy == NULL) { - g_warning ("invoking IsSupported() failed for remote volume monitor with dbus name %s: %s: %s", - dbus_name, - dbus_error.name, - dbus_error.message); - dbus_error_free (&dbus_error); - goto fail; + g_printerr ("Error creating proxy: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); + goto out; } - if (!dbus_message_get_args (reply, &dbus_error, - DBUS_TYPE_BOOLEAN, &is_supported, - DBUS_TYPE_INVALID)) + error = NULL; + if (!gvfs_remote_volume_monitor_call_is_supported_sync (proxy, + &is_supported, + NULL, + &error)) { - g_warning ("Error parsing args in reply for IsSupported(): %s: %s", dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - goto fail; + g_printerr ("invoking IsSupported() failed for remote volume monitor with dbus name %s:: %s (%s, %d)\n", + dbus_name, error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); + goto out; } - + if (!is_supported) g_warning ("remote volume monitor with dbus name %s is not supported", dbus_name); - fail: - if (message != NULL) - dbus_message_unref (message); - if (reply != NULL) - dbus_message_unref (reply); + out: + if (proxy != NULL) + g_object_unref (proxy); return is_supported; } @@ -923,7 +1141,7 @@ is_supported (GProxyVolumeMonitorClass *klass) gboolean res; G_LOCK (proxy_vm); - res = g_proxy_volume_monitor_setup_session_bus_connection (FALSE); + res = g_proxy_volume_monitor_setup_session_bus_connection (); G_UNLOCK (proxy_vm); if (res) @@ -961,86 +1179,70 @@ g_proxy_volume_monitor_class_init (GProxyVolumeMonitorClass *klass) static void seed_monitor (GProxyVolumeMonitor *monitor) { - DBusMessage *message; - DBusMessage *reply; - DBusError dbus_error; - DBusMessageIter iter_reply; - DBusMessageIter iter_array; - - message = dbus_message_new_method_call (g_proxy_volume_monitor_get_dbus_name (monitor), - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "List"); - if (message == NULL) - { - g_warning ("Cannot allocate memory for DBusMessage"); - goto fail; - } - dbus_error_init (&dbus_error); - reply = dbus_connection_send_with_reply_and_block (monitor->session_bus, - message, - -1, - &dbus_error); - dbus_message_unref (message); - if (dbus_error_is_set (&dbus_error)) + GVariant *Drives; + GVariant *Volumes; + GVariant *Mounts; + GVariantIter iter; + GVariant *child; + GError *error; + + error = NULL; + if (!gvfs_remote_volume_monitor_call_list_sync (monitor->proxy, + &Drives, + &Volumes, + &Mounts, + NULL, + &error)) { - g_warning ("invoking List() failed for type %s: %s: %s", + g_warning ("invoking List() failed for type %s: %s (%s, %d)", G_OBJECT_TYPE_NAME (monitor), - dbus_error.name, - dbus_error.message); - dbus_error_free (&dbus_error); + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); goto fail; } - dbus_message_iter_init (reply, &iter_reply); - - /* TODO: verify signature */ - /* drives */ - dbus_message_iter_recurse (&iter_reply, &iter_array); - while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID) + g_variant_iter_init (&iter, Drives); + while ((child = g_variant_iter_next_value (&iter))) { GProxyDrive *drive; const char *id; drive = g_proxy_drive_new (monitor); - g_proxy_drive_update (drive, &iter_array); + g_proxy_drive_update (drive, child); id = g_proxy_drive_get_id (drive); g_hash_table_insert (monitor->drives, g_strdup (id), drive); - dbus_message_iter_next (&iter_array); + g_variant_unref (child); } - dbus_message_iter_next (&iter_reply); /* volumes */ - dbus_message_iter_recurse (&iter_reply, &iter_array); - while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID) + g_variant_iter_init (&iter, Volumes); + while ((child = g_variant_iter_next_value (&iter))) { GProxyVolume *volume; const char *id; volume = g_proxy_volume_new (monitor); - g_proxy_volume_update (volume, &iter_array); + g_proxy_volume_update (volume, child); id = g_proxy_volume_get_id (volume); g_hash_table_insert (monitor->volumes, g_strdup (id), volume); - dbus_message_iter_next (&iter_array); + g_variant_unref (child); } - dbus_message_iter_next (&iter_reply); /* mounts */ - dbus_message_iter_recurse (&iter_reply, &iter_array); - while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID) + g_variant_iter_init (&iter, Mounts); + while ((child = g_variant_iter_next_value (&iter))) { GProxyMount *mount; const char *id; mount = g_proxy_mount_new (monitor); - g_proxy_mount_update (mount, &iter_array); + g_proxy_mount_update (mount, child); id = g_proxy_mount_get_id (mount); g_hash_table_insert (monitor->mounts, g_strdup (id), mount); - dbus_message_iter_next (&iter_array); + g_variant_unref (child); } - dbus_message_iter_next (&iter_reply); - - monitor->unique_name = g_strdup (dbus_message_get_sender (reply)); - dbus_message_unref (reply); + g_variant_unref (Drives); + g_variant_unref (Volumes); + g_variant_unref (Mounts); fail: ; @@ -1093,47 +1295,27 @@ g_proxy_volume_monitor_get_mount_for_id (GProxyVolumeMonitor *volume_monitor, GHashTable * -_get_identifiers (DBusMessageIter *iter) +_get_identifiers (GVariantIter *iter) { GHashTable *hash_table; - DBusMessageIter iter_array; + char *key; + char *value; hash_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - dbus_message_iter_recurse (iter, &iter_array); - while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID) - { - DBusMessageIter iter_dict_entry; - const char *key; - const char *value; - - dbus_message_iter_recurse (&iter_array, &iter_dict_entry); - dbus_message_iter_get_basic (&iter_dict_entry, &key); - dbus_message_iter_next (&iter_dict_entry); - dbus_message_iter_get_basic (&iter_dict_entry, &value); - - g_hash_table_insert (hash_table, g_strdup (key), g_strdup (value)); - - dbus_message_iter_next (&iter_array); - } - + while (g_variant_iter_next (iter, "{ss}", &key, &value)) + g_hash_table_insert (hash_table, key, value); + return hash_table; } -DBusConnection * -g_proxy_volume_monitor_get_dbus_connection (GProxyVolumeMonitor *volume_monitor) +GVfsRemoteVolumeMonitor * +g_proxy_volume_monitor_get_dbus_proxy (GProxyVolumeMonitor *volume_monitor) { - return dbus_connection_ref (volume_monitor->session_bus); -} - -const char * -g_proxy_volume_monitor_get_dbus_name (GProxyVolumeMonitor *volume_monitor) -{ - GProxyVolumeMonitorClass *klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (volume_monitor)); - return klass->dbus_name; + return g_object_ref (volume_monitor->proxy); } static void @@ -1171,11 +1353,11 @@ register_volume_monitor (GTypeModule *type_module, } /* Call with proxy_vm lock held */ -gboolean -g_proxy_volume_monitor_setup_session_bus_connection (gboolean need_integration) +static gboolean +g_proxy_volume_monitor_setup_session_bus_connection (void) { gboolean ret; - DBusError dbus_error; + GError *error; ret = FALSE; @@ -1189,25 +1371,21 @@ g_proxy_volume_monitor_setup_session_bus_connection (gboolean need_integration) if (g_getenv ("DBUS_SESSION_BUS_ADDRESS") == NULL) goto out; - dbus_error_init (&dbus_error); - the_session_bus = dbus_bus_get_private (DBUS_BUS_SESSION, &dbus_error); - if (dbus_error_is_set (&dbus_error)) + error = NULL; + the_session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + if (error != NULL) { - g_warning ("cannot connect to the session bus: %s: %s", dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); + g_printerr ("cannot connect to the session bus: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); goto out; } + g_dbus_connection_set_exit_on_close (the_session_bus, FALSE); the_volume_monitors = g_hash_table_new (g_direct_hash, g_direct_equal); has_bus_already: - - if (need_integration && !the_session_bus_is_integrated) - { - _g_dbus_connection_integrate_with_main (the_session_bus); - the_session_bus_is_integrated = TRUE; - } - + ret = TRUE; out: @@ -1220,10 +1398,8 @@ g_proxy_volume_monitor_teardown_session_bus_connection (void) G_LOCK (proxy_vm); if (the_session_bus != NULL) { - if (the_session_bus_is_integrated) - _g_dbus_connection_remove_from_main (the_session_bus); - the_session_bus_is_integrated = FALSE; - dbus_connection_close (the_session_bus); + g_dbus_connection_close_sync (the_session_bus, NULL, NULL); + g_object_unref (the_session_bus); the_session_bus = NULL; g_hash_table_unref (the_volume_monitors); diff --git a/monitor/proxy/gproxyvolumemonitor.h b/monitor/proxy/gproxyvolumemonitor.h index 3d29d7b2..137e56b3 100644 --- a/monitor/proxy/gproxyvolumemonitor.h +++ b/monitor/proxy/gproxyvolumemonitor.h @@ -27,7 +27,8 @@ #include <glib-object.h> #include <gio/gio.h> #include <gio/gunixmounts.h> -#include <dbus/dbus.h> + +#include "gvfsvolumemonitordbus.h" G_BEGIN_DECLS @@ -64,21 +65,19 @@ struct _GProxyVolumeMonitorClass { GType g_proxy_volume_monitor_get_type (void) G_GNUC_CONST; -void g_proxy_volume_monitor_register (GIOModule *module); -GProxyDrive *g_proxy_volume_monitor_get_drive_for_id (GProxyVolumeMonitor *volume_monitor, +void g_proxy_volume_monitor_register (GIOModule *module); +GProxyDrive *g_proxy_volume_monitor_get_drive_for_id (GProxyVolumeMonitor *volume_monitor, const char *id); -GProxyVolume *g_proxy_volume_monitor_get_volume_for_id (GProxyVolumeMonitor *volume_monitor, +GProxyVolume *g_proxy_volume_monitor_get_volume_for_id (GProxyVolumeMonitor *volume_monitor, const char *id); -GProxyMount *g_proxy_volume_monitor_get_mount_for_id (GProxyVolumeMonitor *volume_monitor, +GProxyMount *g_proxy_volume_monitor_get_mount_for_id (GProxyVolumeMonitor *volume_monitor, const char *id); -DBusConnection *g_proxy_volume_monitor_get_dbus_connection (GProxyVolumeMonitor *volume_monitor); -const char *g_proxy_volume_monitor_get_dbus_name (GProxyVolumeMonitor *volume_monitor); +GVfsRemoteVolumeMonitor *g_proxy_volume_monitor_get_dbus_proxy (GProxyVolumeMonitor *volume_monitor); -gboolean g_proxy_volume_monitor_setup_session_bus_connection (gboolean need_integration); void g_proxy_volume_monitor_teardown_session_bus_connection (void); -GHashTable *_get_identifiers (DBusMessageIter *iter); +GHashTable *_get_identifiers (GVariantIter *identifiers); G_END_DECLS diff --git a/monitor/proxy/gvfsproxyvolumemonitordaemon.c b/monitor/proxy/gvfsproxyvolumemonitordaemon.c index fe2f1a7b..713250c5 100644 --- a/monitor/proxy/gvfsproxyvolumemonitordaemon.c +++ b/monitor/proxy/gvfsproxyvolumemonitordaemon.c @@ -25,25 +25,26 @@ #include <string.h> #include <locale.h> #include <gio/gio.h> -#include <dbus/dbus.h> #include <glib/gi18n.h> #include <stdlib.h> #include <glib/gprintf.h> -#include "gvfsdbusutils.h" #include "gvfsproxyvolumemonitordaemon.h" +#include "gvfsvolumemonitordbus.h" /* ---------------------------------------------------------------------------------------------------- */ +static GMainLoop *loop = NULL; static GVolumeMonitor *monitor = NULL; -static DBusConnection *connection = NULL; static GType the_volume_monitor_type; static const char *the_dbus_name = NULL; static GList *outstanding_ops = NULL; static GList *outstanding_mount_op_objects = NULL; static GHashTable *unique_names_being_watched = NULL; -/* #define DEBUG_ENABLED */ +static GVfsRemoteVolumeMonitor *monitor_daemon = NULL; + +#define DEBUG_ENABLED #ifdef DEBUG_ENABLED static void @@ -136,31 +137,23 @@ g_proxy_mount_operation_class_init (GProxyMountOperationClass *klass) } static void -ask_password_cb (GMountOperation *mount_operation, - const gchar *message_to_show, - const gchar *default_user, - const gchar *default_domain, - GAskPasswordFlags flags, - gpointer user_data) +ask_password_cb (GMountOperation *mount_operation, + const gchar *message_to_show, + const gchar *default_user, + const gchar *default_domain, + GAskPasswordFlags flags, + GVfsRemoteVolumeMonitor *monitor) { - DBusMessage *message; - DBusMessageIter iter; const gchar *mount_op_id; const gchar *mount_op_owner; + GDBusConnection *connection; + GError *error; print_debug ("in ask_password_cb %s", message_to_show); mount_op_id = g_object_get_data (G_OBJECT (mount_operation), "mount_op_id"); mount_op_owner = g_object_get_data (G_OBJECT (mount_operation), "mount_op_owner"); - message = dbus_message_new_method_call (mount_op_owner, - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "MountOpAskPassword"); - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &the_dbus_name); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &mount_op_id); - if (message_to_show == NULL) message_to_show = ""; @@ -170,129 +163,178 @@ ask_password_cb (GMountOperation *mount_operation, if (default_domain == NULL) default_domain = ""; - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &message_to_show); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &default_user); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &default_domain); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &flags); - - dbus_connection_send (connection, message, NULL); - dbus_message_unref (message); + connection = g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (monitor)); + g_assert (connection != NULL); + + error = NULL; + if (!g_dbus_connection_emit_signal (connection, + mount_op_owner, + "/org/gtk/Private/RemoteVolumeMonitor", + "org.gtk.Private.RemoteVolumeMonitor", + "MountOpAskPassword", + g_variant_new ("(sssssu)", + the_dbus_name, + mount_op_id, + message_to_show, + default_user, + default_domain, + flags), + &error)) + { + g_printerr ("Error emitting signal: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); + } } static void -ask_question_cb (GMountOperation *mount_operation, - const gchar *message_to_show, - gchar **choices, - gpointer user_data) +ask_question_cb (GMountOperation *mount_operation, + const gchar *message_to_show, + gchar **choices, + GVfsRemoteVolumeMonitor *monitor) { - DBusMessage *message; - DBusMessageIter iter; - DBusMessageIter iter_string_array; const gchar *mount_op_id; const gchar *mount_op_owner; guint n; + GVariantBuilder *choices_array; + GDBusConnection *connection; + GError *error; print_debug ("in ask_question_cb %s", message_to_show); mount_op_id = g_object_get_data (G_OBJECT (mount_operation), "mount_op_id"); mount_op_owner = g_object_get_data (G_OBJECT (mount_operation), "mount_op_owner"); - message = dbus_message_new_method_call (mount_op_owner, - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "MountOpAskQuestion"); - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &the_dbus_name); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &mount_op_id); - if (message_to_show == NULL) message_to_show = ""; - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &message_to_show); - - dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &iter_string_array); + choices_array = g_variant_builder_new (G_VARIANT_TYPE_STRING_ARRAY); for (n = 0; choices != NULL && choices[n] != NULL; n++) - dbus_message_iter_append_basic (&iter_string_array, DBUS_TYPE_STRING, &(choices[n])); - dbus_message_iter_close_container (&iter, &iter_string_array); + { + g_variant_builder_add (choices_array, "s", choices[n]); + } + + connection = g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (monitor)); + g_assert (connection != NULL); + + error = NULL; + if (!g_dbus_connection_emit_signal (connection, + mount_op_owner, + "/org/gtk/Private/RemoteVolumeMonitor", + "org.gtk.Private.RemoteVolumeMonitor", + "MountOpAskQuestion", + g_variant_new ("(sssas)", + the_dbus_name, + mount_op_id, + message_to_show, + choices_array), + &error)) + { + g_printerr ("Error emitting signal: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); + } - dbus_connection_send (connection, message, NULL); - dbus_message_unref (message); + g_variant_builder_unref (choices_array); } static void -show_processes_cb (GMountOperation *mount_operation, - const gchar *message_to_show, - GArray *processes, - gchar **choices, - gpointer user_data) +show_processes_cb (GMountOperation *mount_operation, + const gchar *message_to_show, + GArray *processes, + gchar **choices, + GVfsRemoteVolumeMonitor *monitor) { - DBusMessage *message; - DBusMessageIter iter; - DBusMessageIter iter_string_array; const gchar *mount_op_id; const gchar *mount_op_owner; guint n; + GVariantBuilder *pids; + GVariantBuilder *choices_array; + GDBusConnection *connection; + GError *error; print_debug ("in show_processes_cb %s", message_to_show); mount_op_id = g_object_get_data (G_OBJECT (mount_operation), "mount_op_id"); mount_op_owner = g_object_get_data (G_OBJECT (mount_operation), "mount_op_owner"); - message = dbus_message_new_method_call (mount_op_owner, - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "MountOpShowProcesses"); - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &the_dbus_name); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &mount_op_id); + print_debug (" owner = '%s'", mount_op_owner); if (message_to_show == NULL) message_to_show = ""; - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &message_to_show); - - dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_INT32_AS_STRING, &iter_string_array); + pids = g_variant_builder_new (G_VARIANT_TYPE ("ai")); for (n = 0; processes != NULL && n < processes->len; n++) { GPid pid; pid = g_array_index (processes, GPid, n); - dbus_message_iter_append_basic (&iter_string_array, DBUS_TYPE_INT32, &pid); + g_variant_builder_add (pids, "i", pid); } - dbus_message_iter_close_container (&iter, &iter_string_array); - dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &iter_string_array); + choices_array = g_variant_builder_new (G_VARIANT_TYPE_STRING_ARRAY); for (n = 0; choices != NULL && choices[n] != NULL; n++) - dbus_message_iter_append_basic (&iter_string_array, DBUS_TYPE_STRING, &(choices[n])); - dbus_message_iter_close_container (&iter, &iter_string_array); + { + g_variant_builder_add (choices_array, "s", choices[n]); + } + + connection = g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (monitor)); + g_assert (connection != NULL); + + error = NULL; + if (!g_dbus_connection_emit_signal (connection, + mount_op_owner, + "/org/gtk/Private/RemoteVolumeMonitor", + "org.gtk.Private.RemoteVolumeMonitor", + "MountOpShowProcesses", + g_variant_new ("(sssaias)", + the_dbus_name, + mount_op_id, + message_to_show, + pids, + choices_array), + &error)) + { + g_printerr ("Error emitting signal: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); + } - dbus_connection_send (connection, message, NULL); - dbus_message_unref (message); + g_variant_builder_unref (pids); + g_variant_builder_unref (choices_array); } static void -aborted_cb (GMountOperation *mount_operation, - gpointer user_data) +aborted_cb (GMountOperation *mount_operation, + GVfsRemoteVolumeMonitor *monitor) { - DBusMessage *message; - DBusMessageIter iter; const gchar *mount_op_id; const gchar *mount_op_owner; + GDBusConnection *connection; + GError *error; print_debug ("in aborted_cb"); mount_op_id = g_object_get_data (G_OBJECT (mount_operation), "mount_op_id"); mount_op_owner = g_object_get_data (G_OBJECT (mount_operation), "mount_op_owner"); - message = dbus_message_new_method_call (mount_op_owner, - "/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - "MountOpAborted"); - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &the_dbus_name); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &mount_op_id); - - dbus_connection_send (connection, message, NULL); - dbus_message_unref (message); + connection = g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (monitor)); + g_assert (connection != NULL); + + error = NULL; + if (!g_dbus_connection_emit_signal (connection, + mount_op_owner, + "/org/gtk/Private/RemoteVolumeMonitor", + "org.gtk.Private.RemoteVolumeMonitor", + "MountOpAborted", + g_variant_new ("(ss)", + the_dbus_name, + mount_op_id), + &error)) + { + g_printerr ("Error emitting signal: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); + } } static void @@ -304,20 +346,22 @@ mount_op_destroyed_cb (gpointer user_data, static GMountOperation * wrap_mount_op (const gchar *mount_op_id, - const gchar *mount_op_owner) + const gchar *mount_op_owner, + GVfsRemoteVolumeMonitor *monitor) { GMountOperation *op; op = g_proxy_mount_operation_new (); //op = g_mount_operation_new (); - g_signal_connect (op, "ask-password", G_CALLBACK (ask_password_cb), NULL); - g_signal_connect (op, "ask-question", G_CALLBACK (ask_question_cb), NULL); - g_signal_connect (op, "show-processes", G_CALLBACK (show_processes_cb), NULL); - g_signal_connect (op, "aborted", G_CALLBACK (aborted_cb), NULL); + g_signal_connect (op, "ask-password", G_CALLBACK (ask_password_cb), monitor); + g_signal_connect (op, "ask-question", G_CALLBACK (ask_question_cb), monitor); + g_signal_connect (op, "show-processes", G_CALLBACK (show_processes_cb), monitor); + g_signal_connect (op, "aborted", G_CALLBACK (aborted_cb), monitor); g_object_set_data_full (G_OBJECT (op), "mount_op_id", g_strdup (mount_op_id), g_free); g_object_set_data_full (G_OBJECT (op), "mount_op_owner", g_strdup (mount_op_owner), g_free); outstanding_mount_op_objects = g_list_prepend (outstanding_mount_op_objects, op); + g_object_weak_ref (G_OBJECT (op), mount_op_destroyed_cb, NULL); @@ -336,64 +380,79 @@ cancellable_destroyed_cb (gpointer user_data, } static void -remove_name_owned_changed_for_unique_name (const gchar *unique_name) +on_name_owner_vanished (GDBusConnection *connection, + const gchar *name, + gpointer user_data) { - const gchar *match_rule; - DBusError dbus_error; + GList *l; + guint name_watcher_id; + + print_debug ("Name owner '%s' vanished", name); - match_rule = g_hash_table_lookup (unique_names_being_watched, unique_name); - if (match_rule == NULL) + /* if @name has outstanding mount operation objects; abort them */ + for (l = outstanding_mount_op_objects; l != NULL; l = l->next) { - g_warning ("Was asked to remove match rule for unique_name %s but we don't have one", unique_name); - goto out; + GMountOperation *op = G_MOUNT_OPERATION (l->data); + const gchar *owner; + + owner = g_object_get_data (G_OBJECT (op), "mount_op_owner"); + if (g_strcmp0 (owner, name) == 0) + { + print_debug ("****** name `%s' has an outstanding mount operation object, aborting it", + name); + g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED); + } } - dbus_error_init (&dbus_error); - dbus_bus_remove_match (connection, - match_rule, - &dbus_error); - if (dbus_error_is_set (&dbus_error)) { - g_warning ("cannot remove match rule '%s': %s: %s", match_rule, dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - } + /* see if @name has outstanding ops; if so, cancel them */ + for (l = outstanding_ops; l != NULL; l = l->next) + { + GCancellable *cancellable = G_CANCELLABLE (l->data); + const gchar *owner; + + owner = g_object_get_data (G_OBJECT (cancellable), "owner"); + print_debug ("looking at op for %s", owner); + if (g_strcmp0 (owner, name) == 0) + { + print_debug ("****** name `%s' has an outstanding op, cancelling it", + name); + g_cancellable_cancel (cancellable); + } + } - g_hash_table_remove (unique_names_being_watched, unique_name); + /* unwatch the name */ + name_watcher_id = GPOINTER_TO_UINT (g_hash_table_lookup (unique_names_being_watched, name)); + if (name_watcher_id == 0) + { + g_warning ("Was asked to remove match rule for unique_name %s but we don't have one", name); + } + else + { + g_bus_unwatch_name (name_watcher_id); + } - out: - ; + g_hash_table_remove (unique_names_being_watched, name); } static void -ensure_name_owner_changed_for_unique_name (const gchar *unique_name) +ensure_name_owner_changed_for_unique_name (GDBusMethodInvocation *invocation) { - gchar *match_rule; - DBusError dbus_error; + guint name_watcher_id; + const gchar *unique_name; + + unique_name = g_dbus_method_invocation_get_sender (invocation); if (g_hash_table_lookup (unique_names_being_watched, unique_name) != NULL) - goto out; - - match_rule = g_strdup_printf ("type='signal'," - "interface='org.freedesktop.DBus'," - "member='NameOwnerChanged'," - "arg0='%s'", - unique_name); - - dbus_error_init (&dbus_error); - dbus_bus_add_match (connection, - match_rule, - &dbus_error); - if (dbus_error_is_set (&dbus_error)) - { - g_warning ("cannot add match rule '%s': %s: %s", match_rule, dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - g_free (match_rule); - goto out; - } - - g_hash_table_insert (unique_names_being_watched, g_strdup (unique_name), match_rule); - - out: - ; + return; + + name_watcher_id = g_bus_watch_name_on_connection (g_dbus_method_invocation_get_connection (invocation), + unique_name, + G_BUS_NAME_WATCHER_FLAGS_NONE, + NULL, /* name_appeared_handler */ + on_name_owner_vanished, + NULL, + NULL); + g_hash_table_insert (unique_names_being_watched, g_strdup (unique_name), GUINT_TO_POINTER (name_watcher_id)); } static void monitor_try_create (void); @@ -417,12 +476,9 @@ static void monitor_try_create (void); */ #define DRIVE_STRUCT_TYPE "(sssbbbbbbbbuasa{ss}sa{sv})" -static void -append_drive (GDrive *drive, DBusMessageIter *iter_array) +static GVariant * +drive_to_dbus (GDrive *drive) { - DBusMessageIter iter_struct; - DBusMessageIter iter_volume_array; - DBusMessageIter iter_identifiers; char *id; char *name; GIcon *icon; @@ -440,9 +496,11 @@ append_drive (GDrive *drive, DBusMessageIter *iter_array) char **identifiers; int n; const gchar *sort_key; - DBusMessageIter iter_expansion; + GVariant *result; + GVariantBuilder *volume_array_builder; + GVariantBuilder *identifiers_builder; + GVariantBuilder *expansion_builder; - dbus_message_iter_open_container (iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct); id = g_strdup_printf ("%p", drive); name = g_drive_get_name (drive); @@ -470,51 +528,63 @@ append_drive (GDrive *drive, DBusMessageIter *iter_array) if (sort_key == NULL) sort_key = ""; - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &id); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &icon_data); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &can_eject); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &can_poll_for_media); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &has_media); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &is_media_removable); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &is_media_check_automatic); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &can_start); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &can_start_degraded); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &can_stop); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &start_stop_type); - - dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "s", &iter_volume_array); + volume_array_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); for (l = volumes; l != NULL; l = l->next) { GVolume *volume = G_VOLUME (l->data); char *volume_id; volume_id = g_strdup_printf ("%p", volume); - dbus_message_iter_append_basic (&iter_volume_array, DBUS_TYPE_STRING, &volume_id); + g_variant_builder_add (volume_array_builder, "s", volume_id); g_free (volume_id); } - dbus_message_iter_close_container (&iter_struct, &iter_volume_array); - dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "{ss}", &iter_identifiers); + identifiers_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{ss}")); for (n = 0; identifiers != NULL && identifiers[n] != NULL; n++) { - DBusMessageIter iter_dict_entry; char *id_value; id_value = g_drive_get_identifier (drive, identifiers[n]); - dbus_message_iter_open_container (&iter_identifiers, - DBUS_TYPE_DICT_ENTRY, - NULL, - &iter_dict_entry); - dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING, &(identifiers[n])); - dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING, &id_value); - dbus_message_iter_close_container (&iter_identifiers, &iter_dict_entry); + + g_variant_builder_add (identifiers_builder, "{ss}", + identifiers[n], + id_value); g_free (id_value); } - dbus_message_iter_close_container (&iter_struct, &iter_identifiers); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &sort_key); - dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "{sv}", &iter_expansion); + expansion_builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); /* left for future expansion without ABI breaks */ - dbus_message_iter_close_container (&iter_struct, &iter_expansion); + + for (n = 0; identifiers != NULL && identifiers[n] != NULL; n++) + { + char *id_value; + id_value = g_drive_get_identifier (drive, identifiers[n]); + + g_variant_builder_add (identifiers_builder, "{ss}", + identifiers[n], + id_value); + g_free (id_value); + } + + result = g_variant_new (DRIVE_STRUCT_TYPE, + id, + name, + icon_data, + can_eject, + can_poll_for_media, + has_media, + is_media_removable, + is_media_check_automatic, + can_start, + can_start_degraded, + can_stop, + start_stop_type, + volume_array_builder, + identifiers_builder, + sort_key, + expansion_builder); + + g_variant_builder_unref (volume_array_builder); + g_variant_builder_unref (identifiers_builder); + g_variant_builder_unref (expansion_builder); g_strfreev (identifiers); g_list_foreach (volumes, (GFunc) g_object_unref, NULL); @@ -524,7 +594,7 @@ append_drive (GDrive *drive, DBusMessageIter *iter_array) g_free (name); g_free (id); - dbus_message_iter_close_container (iter_array, &iter_struct); + return result; } /* string id @@ -542,11 +612,9 @@ append_drive (GDrive *drive, DBusMessageIter *iter_array) */ #define VOLUME_STRUCT_TYPE "(sssssbbssa{ss}sa{sv})" -static void -append_volume (GVolume *volume, DBusMessageIter *iter_array) +static GVariant * +volume_to_dbus (GVolume *volume) { - DBusMessageIter iter_struct; - DBusMessageIter iter_identifiers; char *id; char *name; GIcon *icon; @@ -563,9 +631,10 @@ append_volume (GVolume *volume, DBusMessageIter *iter_array) char **identifiers; int n; const gchar *sort_key; - DBusMessageIter iter_expansion; + GVariant *result; + GVariantBuilder *identifiers_builder; + GVariantBuilder *expansion_builder; - dbus_message_iter_open_container (iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct); id = g_strdup_printf ("%p", volume); name = g_volume_get_name (volume); @@ -603,39 +672,39 @@ append_volume (GVolume *volume, DBusMessageIter *iter_array) if (sort_key == NULL) sort_key = ""; - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &id); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &icon_data); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &uuid); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &activation_uri); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &can_mount); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &should_automount); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &drive_id); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &mount_id); - - dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "{ss}", &iter_identifiers); + identifiers_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{ss}")); for (n = 0; identifiers != NULL && identifiers[n] != NULL; n++) { - DBusMessageIter iter_dict_entry; char *id_value; id_value = g_volume_get_identifier (volume, identifiers[n]); if (id_value == NULL) continue; - dbus_message_iter_open_container (&iter_identifiers, - DBUS_TYPE_DICT_ENTRY, - NULL, - &iter_dict_entry); - dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING, &(identifiers[n])); - dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING, &id_value); - dbus_message_iter_close_container (&iter_identifiers, &iter_dict_entry); + + g_variant_builder_add (identifiers_builder, "{ss}", + identifiers[n], + id_value); g_free (id_value); } - dbus_message_iter_close_container (&iter_struct, &iter_identifiers); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &sort_key); - dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "{sv}", &iter_expansion); + expansion_builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); /* left for future expansion without ABI breaks */ - dbus_message_iter_close_container (&iter_struct, &iter_expansion); + + result = g_variant_new (VOLUME_STRUCT_TYPE, + id, + name, + icon_data, + uuid, + activation_uri, + can_mount, + should_automount, + drive_id, + mount_id, + identifiers_builder, + sort_key, + expansion_builder); + + g_variant_builder_unref (identifiers_builder); + g_variant_builder_unref (expansion_builder); g_strfreev (identifiers); g_free (mount_id); @@ -653,7 +722,7 @@ append_volume (GVolume *volume, DBusMessageIter *iter_array) g_free (name); g_free (id); - dbus_message_iter_close_container (iter_array, &iter_struct); + return result; } /* string id @@ -669,11 +738,9 @@ append_volume (GVolume *volume, DBusMessageIter *iter_array) */ #define MOUNT_STRUCT_TYPE "(sssssbsassa{sv})" -static void -append_mount (GMount *mount, DBusMessageIter *iter_array) +static GVariant * +mount_to_dbus (GMount *mount) { - DBusMessageIter iter_struct; - DBusMessageIter iter_x_content_types_array; char *id; char *name; GIcon *icon; @@ -687,9 +754,9 @@ append_mount (GMount *mount, DBusMessageIter *iter_array) char **x_content_types; int n; const gchar *sort_key; - DBusMessageIter iter_expansion; - - dbus_message_iter_open_container (iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct); + GVariant *result; + GVariantBuilder *x_content_types_array_builder; + GVariantBuilder *expansion_builder; id = g_strdup_printf ("%p", mount); name = g_mount_get_name (mount); @@ -717,28 +784,31 @@ append_mount (GMount *mount, DBusMessageIter *iter_array) if (sort_key == NULL) sort_key = ""; - - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &id); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &icon_data); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &uuid); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &root_uri); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &can_unmount); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &volume_id); - - dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "s", &iter_x_content_types_array); + x_content_types_array_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); x_content_types = (char **) g_object_get_data (G_OBJECT (mount), "x-content-types"); if (x_content_types != NULL) { for (n = 0; x_content_types[n] != NULL; n++) - dbus_message_iter_append_basic (&iter_x_content_types_array, DBUS_TYPE_STRING, &(x_content_types[n])); + g_variant_builder_add (x_content_types_array_builder, "s", x_content_types[n]); } - dbus_message_iter_close_container (&iter_struct, &iter_x_content_types_array); - dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &sort_key); - dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "{sv}", &iter_expansion); + expansion_builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); /* left for future expansion without ABI breaks */ - dbus_message_iter_close_container (&iter_struct, &iter_expansion); + + result = g_variant_new (MOUNT_STRUCT_TYPE, + id, + name, + icon_data, + uuid, + root_uri, + can_unmount, + volume_id, + x_content_types_array_builder, + sort_key, + expansion_builder); + + g_variant_builder_unref (x_content_types_array_builder); + g_variant_builder_unref (expansion_builder); g_free (volume_id); if (volume != NULL) @@ -751,18 +821,21 @@ append_mount (GMount *mount, DBusMessageIter *iter_array) g_free (name); g_free (id); - dbus_message_iter_close_container (iter_array, &iter_struct); + return result; } -static DBusHandlerResult -handle_list (DBusConnection *connection, DBusMessage *message) +static gboolean +handle_list (GVfsRemoteVolumeMonitor *object, + GDBusMethodInvocation *invocation, + gpointer user_data) { GList *drives; GList *volumes; GList *mounts; - DBusMessageIter iter; - DBusMessageIter iter_array; - DBusMessage *reply; + GList *l; + GVariantBuilder *drives_array; + GVariantBuilder *volumes_array; + GVariantBuilder *mounts_array; print_debug ("in handle_list"); @@ -770,20 +843,15 @@ handle_list (DBusConnection *connection, DBusMessage *message) volumes = g_volume_monitor_get_volumes (monitor); mounts = g_volume_monitor_get_mounts (monitor); - reply = dbus_message_new_method_return (message); - dbus_message_iter_init_append (reply, &iter); - - dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DRIVE_STRUCT_TYPE, &iter_array); - g_list_foreach (drives, (GFunc) append_drive, &iter_array); - dbus_message_iter_close_container (&iter, &iter_array); - - dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, VOLUME_STRUCT_TYPE, &iter_array); - g_list_foreach (volumes, (GFunc) append_volume, &iter_array); - dbus_message_iter_close_container (&iter, &iter_array); - - dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, MOUNT_STRUCT_TYPE, &iter_array); - g_list_foreach (mounts, (GFunc) append_mount, &iter_array); - dbus_message_iter_close_container (&iter, &iter_array); + drives_array = g_variant_builder_new (G_VARIANT_TYPE ("a" DRIVE_STRUCT_TYPE)); + for (l = drives; l; l = l->next) + g_variant_builder_add_value (drives_array, drive_to_dbus (l->data)); + volumes_array = g_variant_builder_new (G_VARIANT_TYPE ("a" VOLUME_STRUCT_TYPE)); + for (l = volumes; l; l = l->next) + g_variant_builder_add_value (volumes_array, volume_to_dbus (l->data)); + mounts_array = g_variant_builder_new (G_VARIANT_TYPE ("a" MOUNT_STRUCT_TYPE)); + for (l = mounts; l; l = l->next) + g_variant_builder_add_value (mounts_array, mount_to_dbus (l->data)); g_list_foreach (drives, (GFunc) g_object_unref, NULL); g_list_free (drives); @@ -791,20 +859,25 @@ handle_list (DBusConnection *connection, DBusMessage *message) g_list_free (volumes); g_list_foreach (mounts, (GFunc) g_object_unref, NULL); g_list_free (mounts); - - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); - - return DBUS_HANDLER_RESULT_HANDLED; + + gvfs_remote_volume_monitor_complete_list (object, invocation, + g_variant_builder_end (drives_array), + g_variant_builder_end (volumes_array), + g_variant_builder_end (mounts_array)); + + g_variant_builder_unref (drives_array); + g_variant_builder_unref (volumes_array); + g_variant_builder_unref (mounts_array); + + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ static void -mount_unmount_cb (GMount *mount, GAsyncResult *result, DBusMessage *message) +mount_unmount_cb (GMount *mount, GAsyncResult *result, GDBusMethodInvocation *invocation) { GError *error; - DBusMessage *reply; print_debug ("in mount_unmount_cb"); @@ -815,59 +888,37 @@ mount_unmount_cb (GMount *mount, GAsyncResult *result, DBusMessage *message) if (!g_mount_unmount_with_operation_finish (mount, result, &error)) { print_debug (" error: %s", error->message); - reply = _dbus_message_new_from_gerror (message, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); } else { print_debug (" success"); - reply = dbus_message_new_method_return (message); + gvfs_remote_volume_monitor_complete_mount_unmount (NULL, invocation); } - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (message); - dbus_message_unref (reply); - g_object_unref (mount); + g_object_unref (invocation); } -static DBusHandlerResult -handle_mount_unmount (DBusConnection *connection, DBusMessage *message) +static gboolean +handle_mount_unmount (GVfsRemoteVolumeMonitor *object, + GDBusMethodInvocation *invocation, + const gchar *arg_id, + const gchar *arg_cancellation_id, + guint arg_unmount_flags, + const gchar *arg_mount_op_id, + gpointer user_data) { - const char *id; - const char *cancellation_id; const char *sender; - const char *mount_op_id; GCancellable *cancellable; GMountOperation *mount_operation; - dbus_uint32_t unmount_flags; - DBusError dbus_error; GList *mounts, *l; GMount *mount; - DBusHandlerResult ret; - - mounts = NULL; - unmount_flags = 0; - ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - dbus_error_init (&dbus_error); - if (!dbus_message_get_args (message, &dbus_error, - DBUS_TYPE_STRING, &id, - DBUS_TYPE_STRING, &cancellation_id, - DBUS_TYPE_UINT32, &unmount_flags, - DBUS_TYPE_STRING, &mount_op_id, - DBUS_TYPE_INVALID)) - { - g_warning ("Error parsing args for MountUnmount(): %s: %s", dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - goto out; - } print_debug ("in handle_mount_unmount"); - ret = DBUS_HANDLER_RESULT_HANDLED; - - sender = dbus_message_get_sender (message); + sender = g_dbus_method_invocation_get_sender (invocation); mount = NULL; mounts = g_volume_monitor_get_mounts (monitor); @@ -877,7 +928,7 @@ handle_mount_unmount (DBusConnection *connection, DBusMessage *message) mount = G_MOUNT (l->data); mount_id = g_strdup_printf ("%p", mount); - if (strcmp (mount_id, id) == 0) + if (strcmp (mount_id, arg_id) == 0) break; g_free (mount_id); @@ -887,49 +938,43 @@ handle_mount_unmount (DBusConnection *connection, DBusMessage *message) if (mount == NULL) { - DBusMessage *reply; - reply = dbus_message_new_error (message, - "org.gtk.Private.RemoteVolumeMonitor.NotFound", - "The given mount was not found"); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.Private.RemoteVolumeMonitor.NotFound", + "The given mount was not found"); goto out; } if (g_object_get_data (G_OBJECT (mount), "cancellable") != NULL) { - DBusMessage *reply; - reply = dbus_message_new_error (message, - "org.gtk.Private.RemoteVolumeMonitor.Failed", - "An operation is already pending"); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.Private.RemoteVolumeMonitor.Failed", + "An operation is already pending"); goto out; } cancellable = g_cancellable_new (); g_object_set_data_full (G_OBJECT (mount), "cancellable", cancellable, g_object_unref); g_object_set_data_full (G_OBJECT (cancellable), "owner", g_strdup (sender), g_free); - g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (cancellation_id), g_free); + g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (arg_cancellation_id), g_free); outstanding_ops = g_list_prepend (outstanding_ops, cancellable); g_object_weak_ref (G_OBJECT (cancellable), cancellable_destroyed_cb, NULL); mount_operation = NULL; - if (mount_op_id != NULL && strlen (mount_op_id) > 0) + if (arg_mount_op_id != NULL && strlen (arg_mount_op_id) > 0) { - mount_operation = wrap_mount_op (mount_op_id, sender); + mount_operation = wrap_mount_op (arg_mount_op_id, sender, object); g_object_set_data_full (G_OBJECT (mount), "mount_operation", mount_operation, g_object_unref); } g_object_ref (mount); g_mount_unmount_with_operation (mount, - unmount_flags, + arg_unmount_flags, mount_operation, cancellable, (GAsyncReadyCallback) mount_unmount_cb, - dbus_message_ref (message)); + g_object_ref (invocation)); out: if (mounts != NULL) @@ -937,57 +982,34 @@ handle_mount_unmount (DBusConnection *connection, DBusMessage *message) g_list_foreach (mounts, (GFunc) g_object_unref, NULL); g_list_free (mounts); } - return ret; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ -static DBusHandlerResult -handle_mount_op_reply (DBusConnection *connection, DBusMessage *message) +static gboolean +handle_mount_op_reply (GVfsRemoteVolumeMonitor *object, + GDBusMethodInvocation *invocation, + const gchar *arg_mount_op_id, + gint arg_result, + const gchar *arg_user_name, + const gchar *arg_domain, + const gchar *arg_encoded_password, + gint arg_password_save, + gint arg_choice, + gboolean arg_anonymous, + gpointer user_data) { - const char *mount_op_id; - dbus_int32_t result; - const char *user_name; - const char *domain; - const char *encoded_password; char *decoded_password; gsize decoded_password_len; - dbus_int32_t password_save; - dbus_int32_t choice; - dbus_bool_t anonymous; - DBusError dbus_error; - DBusHandlerResult ret; GList *l; - DBusMessage *reply; GMountOperation *mount_operation; const gchar *sender; - decoded_password = NULL; - ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - dbus_error_init (&dbus_error); - if (!dbus_message_get_args (message, - &dbus_error, - DBUS_TYPE_STRING, &mount_op_id, - DBUS_TYPE_INT32, &result, - DBUS_TYPE_STRING, &user_name, - DBUS_TYPE_STRING, &domain, - DBUS_TYPE_STRING, &encoded_password, - DBUS_TYPE_INT32, &password_save, - DBUS_TYPE_INT32, &choice, - DBUS_TYPE_BOOLEAN, &anonymous, - DBUS_TYPE_INVALID)) - { - g_warning ("Error parsing args for MountOpReply(): %s: %s", dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - goto out; - } - print_debug ("in handle_mount_op_reply"); - ret = DBUS_HANDLER_RESULT_HANDLED; - - sender = dbus_message_get_sender (message); + decoded_password = NULL; + sender = g_dbus_method_invocation_get_sender (invocation); /* Find the op */ mount_operation = NULL; @@ -1000,7 +1022,7 @@ handle_mount_op_reply (DBusConnection *connection, DBusMessage *message) owner = g_object_get_data (G_OBJECT (op), "mount_op_owner"); id = g_object_get_data (G_OBJECT (op), "mount_op_id"); - if (g_strcmp0 (owner, sender) == 0 && g_strcmp0 (id, mount_op_id) == 0) + if (g_strcmp0 (owner, sender) == 0 && g_strcmp0 (id, arg_mount_op_id) == 0) { print_debug ("found mount_op"); mount_operation = op; @@ -1010,42 +1032,36 @@ handle_mount_op_reply (DBusConnection *connection, DBusMessage *message) if (mount_operation == NULL) { - DBusMessage *reply; - reply = dbus_message_new_error (message, - "org.gtk.Private.RemoteVolumeMonitor.NotFound", - "No outstanding mount operation"); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.Private.RemoteVolumeMonitor.NotFound", + "No outstanding mount operation"); goto out; } - decoded_password = (gchar *) g_base64_decode (encoded_password, &decoded_password_len); + decoded_password = (gchar *) g_base64_decode (arg_encoded_password, &decoded_password_len); - g_mount_operation_set_username (mount_operation, user_name); - g_mount_operation_set_domain (mount_operation, domain); + g_mount_operation_set_username (mount_operation, arg_user_name); + g_mount_operation_set_domain (mount_operation, arg_domain); g_mount_operation_set_password (mount_operation, decoded_password); - g_mount_operation_set_password_save (mount_operation, password_save); - g_mount_operation_set_choice (mount_operation, choice); - g_mount_operation_set_anonymous (mount_operation, anonymous); + g_mount_operation_set_password_save (mount_operation, arg_password_save); + g_mount_operation_set_choice (mount_operation, arg_choice); + g_mount_operation_set_anonymous (mount_operation, arg_anonymous); - g_mount_operation_reply (mount_operation, result); + g_mount_operation_reply (mount_operation, arg_result); - reply = dbus_message_new_method_return (message); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); + gvfs_remote_volume_monitor_complete_mount_op_reply (object, invocation); out: g_free (decoded_password); - return ret; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ static void -volume_mount_cb (GVolume *volume, GAsyncResult *result, DBusMessage *message) +volume_mount_cb (GVolume *volume, GAsyncResult *result, GDBusMethodInvocation *invocation) { GError *error; - DBusMessage *reply; print_debug ("in volume_mount_cb"); @@ -1056,56 +1072,35 @@ volume_mount_cb (GVolume *volume, GAsyncResult *result, DBusMessage *message) if (!g_volume_mount_finish (volume, result, &error)) { print_debug (" error: %s", error->message); - reply = _dbus_message_new_from_gerror (message, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); } else { print_debug (" success"); - reply = dbus_message_new_method_return (message); + gvfs_remote_volume_monitor_complete_volume_mount (NULL, invocation); } - - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (message); - dbus_message_unref (reply); + g_object_unref (invocation); } -static DBusHandlerResult -handle_volume_mount (DBusConnection *connection, DBusMessage *message) +static gboolean +handle_volume_mount (GVfsRemoteVolumeMonitor *object, + GDBusMethodInvocation *invocation, + const gchar *arg_id, + const gchar *arg_cancellation_id, + guint arg_mount_flags, + const gchar *arg_mount_op_id, + gpointer user_data) { - const char *id; - const char *cancellation_id; const char *sender; - dbus_uint32_t mount_flags; - const char *mount_op_id; - DBusError dbus_error; GList *volumes, *l; GVolume *volume; - DBusHandlerResult ret; GMountOperation *mount_operation; GCancellable *cancellable; - volumes = NULL; - ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - dbus_error_init (&dbus_error); - if (!dbus_message_get_args (message, &dbus_error, - DBUS_TYPE_STRING, &id, - DBUS_TYPE_STRING, &cancellation_id, - DBUS_TYPE_UINT32, &mount_flags, - DBUS_TYPE_STRING, &mount_op_id, - DBUS_TYPE_INVALID)) - { - g_warning ("Error parsing args for VolumeMount(): %s: %s", dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - goto out; - } - print_debug ("in handle_volume_mount"); - ret = DBUS_HANDLER_RESULT_HANDLED; - - sender = dbus_message_get_sender (message); + sender = g_dbus_method_invocation_get_sender (invocation); volume = NULL; volumes = g_volume_monitor_get_volumes (monitor); @@ -1115,7 +1110,7 @@ handle_volume_mount (DBusConnection *connection, DBusMessage *message) volume = G_VOLUME (l->data); volume_id = g_strdup_printf ("%p", volume); - if (strcmp (volume_id, id) == 0) + if (strcmp (volume_id, arg_id) == 0) break; g_free (volume_id); @@ -1125,48 +1120,42 @@ handle_volume_mount (DBusConnection *connection, DBusMessage *message) if (volume == NULL) { - DBusMessage *reply; - reply = dbus_message_new_error (message, - "org.gtk.Private.RemoteVolumeMonitor.NotFound", - "The given volume was not found"); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.Private.RemoteVolumeMonitor.NotFound", + "The given volume was not found"); goto out; } if (g_object_get_data (G_OBJECT (volume), "cancellable") != NULL) { - DBusMessage *reply; - reply = dbus_message_new_error (message, - "org.gtk.Private.RemoteVolumeMonitor.Failed", - "An operation is already pending"); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.Private.RemoteVolumeMonitor.Failed", + "An operation is already pending"); goto out; } mount_operation = NULL; - if (mount_op_id != NULL && strlen (mount_op_id) > 0) + if (arg_mount_op_id != NULL && strlen (arg_mount_op_id) > 0) { - mount_operation = wrap_mount_op (mount_op_id, sender); + mount_operation = wrap_mount_op (arg_mount_op_id, sender, object); g_object_set_data_full (G_OBJECT (volume), "mount_operation", mount_operation, g_object_unref); } cancellable = g_cancellable_new (); g_object_set_data_full (G_OBJECT (volume), "cancellable", cancellable, g_object_unref); g_object_set_data_full (G_OBJECT (cancellable), "owner", g_strdup (sender), g_free); - g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (cancellation_id), g_free); + g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (arg_cancellation_id), g_free); outstanding_ops = g_list_prepend (outstanding_ops, cancellable); g_object_weak_ref (G_OBJECT (cancellable), cancellable_destroyed_cb, NULL); g_volume_mount (volume, - mount_flags, + arg_mount_flags, mount_operation, cancellable, (GAsyncReadyCallback) volume_mount_cb, - dbus_message_ref (message)); + g_object_ref (invocation)); out: if (volumes != NULL) @@ -1174,16 +1163,15 @@ handle_volume_mount (DBusConnection *connection, DBusMessage *message) g_list_foreach (volumes, (GFunc) g_object_unref, NULL); g_list_free (volumes); } - return ret; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ static void -drive_eject_cb (GDrive *drive, GAsyncResult *result, DBusMessage *message) +drive_eject_cb (GDrive *drive, GAsyncResult *result, GDBusMethodInvocation *invocation) { GError *error; - DBusMessage *reply; print_debug ("in drive_eject_cb"); @@ -1194,58 +1182,35 @@ drive_eject_cb (GDrive *drive, GAsyncResult *result, DBusMessage *message) if (!g_drive_eject_with_operation_finish (drive, result, &error)) { print_debug (" error: %s", error->message); - reply = _dbus_message_new_from_gerror (message, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); } else { print_debug (" success"); - reply = dbus_message_new_method_return (message); + gvfs_remote_volume_monitor_complete_drive_eject (NULL, invocation); } - - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (message); - dbus_message_unref (reply); + g_object_unref (invocation); } -static DBusHandlerResult -handle_drive_eject (DBusConnection *connection, DBusMessage *message) +static gboolean +handle_drive_eject (GVfsRemoteVolumeMonitor *object, + GDBusMethodInvocation *invocation, + const gchar *arg_id, + const gchar *arg_cancellation_id, + guint arg_unmount_flags, + const gchar *arg_mount_op_id, + gpointer user_data) { - const char *id; - const char *cancellation_id; const char *sender; - const char *mount_op_id; GMountOperation *mount_operation; GCancellable *cancellable; - dbus_uint32_t unmount_flags; - DBusError dbus_error; GList *drives, *l; GDrive *drive; - DBusHandlerResult ret; - - drive = NULL; - drives = NULL; - unmount_flags = 0; - ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - dbus_error_init (&dbus_error); - if (!dbus_message_get_args (message, &dbus_error, - DBUS_TYPE_STRING, &id, - DBUS_TYPE_STRING, &cancellation_id, - DBUS_TYPE_UINT32, &unmount_flags, - DBUS_TYPE_STRING, &mount_op_id, - DBUS_TYPE_INVALID)) - { - g_warning ("Error parsing args for DriveEject(): %s: %s", dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - goto out; - } print_debug ("in handle_drive_eject"); - ret = DBUS_HANDLER_RESULT_HANDLED; - - sender = dbus_message_get_sender (message); + sender = g_dbus_method_invocation_get_sender (invocation); drive = NULL; drives = g_volume_monitor_get_connected_drives (monitor); @@ -1255,7 +1220,7 @@ handle_drive_eject (DBusConnection *connection, DBusMessage *message) drive = G_DRIVE (l->data); drive_id = g_strdup_printf ("%p", drive); - if (strcmp (drive_id, id) == 0) + if (strcmp (drive_id, arg_id) == 0) break; g_free (drive_id); @@ -1265,48 +1230,42 @@ handle_drive_eject (DBusConnection *connection, DBusMessage *message) if (drive == NULL) { - DBusMessage *reply; - reply = dbus_message_new_error (message, - "org.gtk.Private.RemoteVolumeMonitor.NotFound", - "The given drive was not found"); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.Private.RemoteVolumeMonitor.NotFound", + "The given drive was not found"); goto out; } if (g_object_get_data (G_OBJECT (drive), "cancellable") != NULL) { - DBusMessage *reply; - reply = dbus_message_new_error (message, - "org.gtk.Private.RemoteVolumeMonitor.Failed", - "An operation is already pending"); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.Private.RemoteVolumeMonitor.Failed", + "An operation is already pending"); goto out; } cancellable = g_cancellable_new (); g_object_set_data_full (G_OBJECT (drive), "cancellable", cancellable, g_object_unref); g_object_set_data_full (G_OBJECT (cancellable), "owner", g_strdup (sender), g_free); - g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (cancellation_id), g_free); + g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (arg_cancellation_id), g_free); outstanding_ops = g_list_prepend (outstanding_ops, cancellable); g_object_weak_ref (G_OBJECT (cancellable), cancellable_destroyed_cb, NULL); mount_operation = NULL; - if (mount_op_id != NULL && strlen (mount_op_id) > 0) + if (arg_mount_op_id != NULL && strlen (arg_mount_op_id) > 0) { - mount_operation = wrap_mount_op (mount_op_id, sender); + mount_operation = wrap_mount_op (arg_mount_op_id, sender, object); g_object_set_data_full (G_OBJECT (drive), "mount_operation", mount_operation, g_object_unref); } g_drive_eject_with_operation (drive, - unmount_flags, + arg_unmount_flags, mount_operation, cancellable, (GAsyncReadyCallback) drive_eject_cb, - dbus_message_ref (message)); + g_object_ref (invocation)); out: if (drives != NULL) @@ -1314,16 +1273,15 @@ handle_drive_eject (DBusConnection *connection, DBusMessage *message) g_list_foreach (drives, (GFunc) g_object_unref, NULL); g_list_free (drives); } - return ret; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ static void -drive_stop_cb (GDrive *drive, GAsyncResult *result, DBusMessage *message) +drive_stop_cb (GDrive *drive, GAsyncResult *result, GDBusMethodInvocation *invocation) { GError *error; - DBusMessage *reply; print_debug ("in drive_stop_cb"); @@ -1334,58 +1292,35 @@ drive_stop_cb (GDrive *drive, GAsyncResult *result, DBusMessage *message) if (!g_drive_stop_finish (drive, result, &error)) { print_debug (" error: %s", error->message); - reply = _dbus_message_new_from_gerror (message, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); } else { print_debug (" success"); - reply = dbus_message_new_method_return (message); + gvfs_remote_volume_monitor_complete_drive_stop (NULL, invocation); } - - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (message); - dbus_message_unref (reply); + g_object_unref (invocation); } -static DBusHandlerResult -handle_drive_stop (DBusConnection *connection, DBusMessage *message) +static gboolean +handle_drive_stop (GVfsRemoteVolumeMonitor *object, + GDBusMethodInvocation *invocation, + const gchar *arg_id, + const gchar *arg_cancellation_id, + guint arg_unmount_flags, + const gchar *arg_mount_op_id, + gpointer user_data) { - const char *id; - const char *cancellation_id; const char *sender; - const char *mount_op_id; GMountOperation *mount_operation; GCancellable *cancellable; - dbus_uint32_t unmount_flags; - DBusError dbus_error; GList *drives, *l; GDrive *drive; - DBusHandlerResult ret; - - drive = NULL; - drives = NULL; - unmount_flags = 0; - ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - dbus_error_init (&dbus_error); - if (!dbus_message_get_args (message, &dbus_error, - DBUS_TYPE_STRING, &id, - DBUS_TYPE_STRING, &cancellation_id, - DBUS_TYPE_UINT32, &unmount_flags, - DBUS_TYPE_STRING, &mount_op_id, - DBUS_TYPE_INVALID)) - { - g_warning ("Error parsing args for DriveStop(): %s: %s", dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - goto out; - } print_debug ("in handle_drive_stop"); - ret = DBUS_HANDLER_RESULT_HANDLED; - - sender = dbus_message_get_sender (message); + sender = g_dbus_method_invocation_get_sender (invocation); drive = NULL; drives = g_volume_monitor_get_connected_drives (monitor); @@ -1395,7 +1330,7 @@ handle_drive_stop (DBusConnection *connection, DBusMessage *message) drive = G_DRIVE (l->data); drive_id = g_strdup_printf ("%p", drive); - if (strcmp (drive_id, id) == 0) + if (strcmp (drive_id, arg_id) == 0) break; g_free (drive_id); @@ -1405,48 +1340,42 @@ handle_drive_stop (DBusConnection *connection, DBusMessage *message) if (drive == NULL) { - DBusMessage *reply; - reply = dbus_message_new_error (message, - "org.gtk.Private.RemoteVolumeMonitor.NotFound", - "The given drive was not found"); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.Private.RemoteVolumeMonitor.NotFound", + "The given drive was not found"); goto out; } if (g_object_get_data (G_OBJECT (drive), "cancellable") != NULL) { - DBusMessage *reply; - reply = dbus_message_new_error (message, - "org.gtk.Private.RemoteVolumeMonitor.Failed", - "An operation is already pending"); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.Private.RemoteVolumeMonitor.Failed", + "An operation is already pending"); goto out; } cancellable = g_cancellable_new (); g_object_set_data_full (G_OBJECT (drive), "cancellable", cancellable, g_object_unref); g_object_set_data_full (G_OBJECT (cancellable), "owner", g_strdup (sender), g_free); - g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (cancellation_id), g_free); + g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (arg_cancellation_id), g_free); outstanding_ops = g_list_prepend (outstanding_ops, cancellable); g_object_weak_ref (G_OBJECT (cancellable), cancellable_destroyed_cb, NULL); mount_operation = NULL; - if (mount_op_id != NULL && strlen (mount_op_id) > 0) + if (arg_mount_op_id != NULL && strlen (arg_mount_op_id) > 0) { - mount_operation = wrap_mount_op (mount_op_id, sender); + mount_operation = wrap_mount_op (arg_mount_op_id, sender, object); g_object_set_data_full (G_OBJECT (drive), "mount_operation", mount_operation, g_object_unref); } g_drive_stop (drive, - unmount_flags, + arg_unmount_flags, mount_operation, cancellable, (GAsyncReadyCallback) drive_stop_cb, - dbus_message_ref (message)); + g_object_ref (invocation)); out: if (drives != NULL) @@ -1454,16 +1383,15 @@ handle_drive_stop (DBusConnection *connection, DBusMessage *message) g_list_foreach (drives, (GFunc) g_object_unref, NULL); g_list_free (drives); } - return ret; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ static void -drive_start_cb (GDrive *drive, GAsyncResult *result, DBusMessage *message) +drive_start_cb (GDrive *drive, GAsyncResult *result, GDBusMethodInvocation *invocation) { GError *error; - DBusMessage *reply; print_debug ("in drive_start_cb"); @@ -1474,56 +1402,35 @@ drive_start_cb (GDrive *drive, GAsyncResult *result, DBusMessage *message) if (!g_drive_start_finish (drive, result, &error)) { print_debug (" error: %s", error->message); - reply = _dbus_message_new_from_gerror (message, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); } else { print_debug (" success"); - reply = dbus_message_new_method_return (message); + gvfs_remote_volume_monitor_complete_drive_start (NULL, invocation); } - - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (message); - dbus_message_unref (reply); + g_object_unref (invocation); } -static DBusHandlerResult -handle_drive_start (DBusConnection *connection, DBusMessage *message) +static gboolean +handle_drive_start (GVfsRemoteVolumeMonitor *object, + GDBusMethodInvocation *invocation, + const gchar *arg_id, + const gchar *arg_cancellation_id, + guint arg_flags, + const gchar *arg_mount_op_id, + gpointer user_data) { - const char *id; - const char *cancellation_id; const char *sender; - const char *mount_op_id; - GDriveStartFlags flags; - DBusError dbus_error; GList *drives, *l; GDrive *drive; - DBusHandlerResult ret; GMountOperation *mount_operation; GCancellable *cancellable; - drives = NULL; - ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - dbus_error_init (&dbus_error); - if (!dbus_message_get_args (message, &dbus_error, - DBUS_TYPE_STRING, &id, - DBUS_TYPE_STRING, &cancellation_id, - DBUS_TYPE_UINT32, &flags, - DBUS_TYPE_STRING, &mount_op_id, - DBUS_TYPE_INVALID)) - { - g_warning ("Error parsing args for DriveStart(): %s: %s", dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - goto out; - } - print_debug ("in handle_drive_start"); - ret = DBUS_HANDLER_RESULT_HANDLED; - - sender = dbus_message_get_sender (message); + sender = g_dbus_method_invocation_get_sender (invocation); drive = NULL; drives = g_volume_monitor_get_connected_drives (monitor); @@ -1533,7 +1440,7 @@ handle_drive_start (DBusConnection *connection, DBusMessage *message) drive = G_DRIVE (l->data); drive_id = g_strdup_printf ("%p", drive); - if (strcmp (drive_id, id) == 0) + if (strcmp (drive_id, arg_id) == 0) break; g_free (drive_id); @@ -1543,48 +1450,42 @@ handle_drive_start (DBusConnection *connection, DBusMessage *message) if (drive == NULL) { - DBusMessage *reply; - reply = dbus_message_new_error (message, - "org.gtk.Private.RemoteVolumeMonitor.NotFound", - "The given drive was not found"); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.Private.RemoteVolumeMonitor.NotFound", + "The given drive was not found"); goto out; } if (g_object_get_data (G_OBJECT (drive), "cancellable") != NULL) { - DBusMessage *reply; - reply = dbus_message_new_error (message, - "org.gtk.Private.RemoteVolumeMonitor.Failed", - "An operation is already pending"); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.Private.RemoteVolumeMonitor.Failed", + "An operation is already pending"); goto out; } mount_operation = NULL; - if (mount_op_id != NULL && strlen (mount_op_id) > 0) + if (arg_mount_op_id != NULL && strlen (arg_mount_op_id) > 0) { - mount_operation = wrap_mount_op (mount_op_id, sender); + mount_operation = wrap_mount_op (arg_mount_op_id, sender, object); g_object_set_data_full (G_OBJECT (drive), "mount_operation", mount_operation, g_object_unref); } cancellable = g_cancellable_new (); g_object_set_data_full (G_OBJECT (drive), "cancellable", cancellable, g_object_unref); g_object_set_data_full (G_OBJECT (cancellable), "owner", g_strdup (sender), g_free); - g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (cancellation_id), g_free); + g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (arg_cancellation_id), g_free); outstanding_ops = g_list_prepend (outstanding_ops, cancellable); g_object_weak_ref (G_OBJECT (cancellable), cancellable_destroyed_cb, NULL); g_drive_start (drive, - flags, + arg_flags, mount_operation, cancellable, (GAsyncReadyCallback) drive_start_cb, - dbus_message_ref (message)); + g_object_ref (invocation)); out: if (drives != NULL) @@ -1592,16 +1493,15 @@ handle_drive_start (DBusConnection *connection, DBusMessage *message) g_list_foreach (drives, (GFunc) g_object_unref, NULL); g_list_free (drives); } - return ret; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ static void -drive_poll_for_media_cb (GDrive *drive, GAsyncResult *result, DBusMessage *message) +drive_poll_for_media_cb (GDrive *drive, GAsyncResult *result, GDBusMethodInvocation *invocation) { GError *error; - DBusMessage *reply; print_debug ("in drive_poll_for_media_cb"); @@ -1611,52 +1511,32 @@ drive_poll_for_media_cb (GDrive *drive, GAsyncResult *result, DBusMessage *messa if (!g_drive_poll_for_media_finish (drive, result, &error)) { print_debug (" error: %s", error->message); - reply = _dbus_message_new_from_gerror (message, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); } else { print_debug (" success"); - reply = dbus_message_new_method_return (message); + gvfs_remote_volume_monitor_complete_drive_poll_for_media (NULL, invocation); } - - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (message); - dbus_message_unref (reply); + g_object_unref (invocation); } -static DBusHandlerResult -handle_drive_poll_for_media (DBusConnection *connection, DBusMessage *message) +static gboolean +handle_drive_poll_for_media (GVfsRemoteVolumeMonitor *object, + GDBusMethodInvocation *invocation, + const gchar *arg_id, + const gchar *arg_cancellation_id, + gpointer user_data) { - const char *id; - const char *cancellation_id; const char *sender; GCancellable *cancellable; - DBusError dbus_error; GList *drives, *l; GDrive *drive; - DBusHandlerResult ret; - - drive = NULL; - drives = NULL; - ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - dbus_error_init (&dbus_error); - if (!dbus_message_get_args (message, &dbus_error, - DBUS_TYPE_STRING, &id, - DBUS_TYPE_STRING, &cancellation_id, - DBUS_TYPE_INVALID)) - { - g_warning ("Error parsing args for DrivePollForMedia(): %s: %s", dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - goto out; - } print_debug ("in handle_drive_poll_for_media"); - ret = DBUS_HANDLER_RESULT_HANDLED; - - sender = dbus_message_get_sender (message); + sender = g_dbus_method_invocation_get_sender (invocation); drive = NULL; drives = g_volume_monitor_get_connected_drives (monitor); @@ -1666,7 +1546,7 @@ handle_drive_poll_for_media (DBusConnection *connection, DBusMessage *message) drive = G_DRIVE (l->data); drive_id = g_strdup_printf ("%p", drive); - if (strcmp (drive_id, id) == 0) + if (strcmp (drive_id, arg_id) == 0) break; g_free (drive_id); @@ -1676,30 +1556,24 @@ handle_drive_poll_for_media (DBusConnection *connection, DBusMessage *message) if (drive == NULL) { - DBusMessage *reply; - reply = dbus_message_new_error (message, - "org.gtk.Private.RemoteVolumeMonitor.NotFound", - "The given drive was not found"); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.Private.RemoteVolumeMonitor.NotFound", + "The given drive was not found"); goto out; } if (g_object_get_data (G_OBJECT (drive), "cancellable") != NULL) { - DBusMessage *reply; - reply = dbus_message_new_error (message, - "org.gtk.Private.RemoteVolumeMonitor.Failed", - "An operation is already pending"); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.Private.RemoteVolumeMonitor.Failed", + "An operation is already pending"); goto out; } cancellable = g_cancellable_new (); g_object_set_data_full (G_OBJECT (drive), "cancellable", cancellable, g_object_unref); g_object_set_data_full (G_OBJECT (cancellable), "owner", g_strdup (sender), g_free); - g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (cancellation_id), g_free); + g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (arg_cancellation_id), g_free); outstanding_ops = g_list_prepend (outstanding_ops, cancellable); g_object_weak_ref (G_OBJECT (cancellable), cancellable_destroyed_cb, @@ -1708,69 +1582,59 @@ handle_drive_poll_for_media (DBusConnection *connection, DBusMessage *message) g_drive_poll_for_media (drive, cancellable, (GAsyncReadyCallback) drive_poll_for_media_cb, - dbus_message_ref (message)); - + g_object_ref (invocation)); + out: if (drives != NULL) { g_list_foreach (drives, (GFunc) g_object_unref, NULL); g_list_free (drives); } - return ret; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ -static DBusHandlerResult -handle_is_supported (DBusConnection *connection, DBusMessage *message) +static gboolean +handle_is_supported (GVfsRemoteVolumeMonitor *object, + GDBusMethodInvocation *invocation, + gpointer user_data) { - dbus_bool_t is_supported; - DBusMessage *reply; - DBusMessageIter iter; - print_debug ("in handle_supported"); /* if monitor wasn't created on startup; try again */ if (monitor == NULL) monitor_try_create (); - is_supported = (monitor != NULL); - - reply = dbus_message_new_method_return (message); - dbus_message_iter_init_append (reply, &iter); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &is_supported); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); - - return DBUS_HANDLER_RESULT_HANDLED; + if (monitor != NULL) + { + /* If someone is calling into this object and interface, start watching their name so + * we can cancel operations initiated by them when they disconnect + */ + ensure_name_owner_changed_for_unique_name (invocation); + } + + gvfs_remote_volume_monitor_complete_is_supported (object, invocation, + monitor != NULL); + + return TRUE; /* invocation was handled */ } /* ---------------------------------------------------------------------------------------------------- */ -static DBusHandlerResult -handle_cancel_operation (DBusConnection *connection, DBusMessage *message) +static gboolean +handle_cancel_operation (GVfsRemoteVolumeMonitor *object, + GDBusMethodInvocation *invocation, + const gchar *arg_cancellation_id, + gpointer user_data) { - DBusMessage *reply; - DBusMessageIter iter; - DBusError dbus_error; - dbus_bool_t was_cancelled; + gboolean was_cancelled; const char *sender; - const char *cancellation_id; GList *l; was_cancelled = FALSE; - sender = dbus_message_get_sender (message); - - dbus_error_init (&dbus_error); - if (!dbus_message_get_args (message, &dbus_error, - DBUS_TYPE_STRING, &cancellation_id, - DBUS_TYPE_INVALID)) - { - g_warning ("Error parsing args for CancelOperation(): %s: %s", dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - goto out; - } + sender = g_dbus_method_invocation_get_sender (invocation); print_debug ("in handle_cancel_operation"); @@ -1783,7 +1647,7 @@ handle_cancel_operation (DBusConnection *connection, DBusMessage *message) owner = g_object_get_data (G_OBJECT (cancellable), "owner"); id = g_object_get_data (G_OBJECT (cancellable), "cancellation_id"); - if (g_strcmp0 (owner, sender) == 0 && g_strcmp0 (id, cancellation_id) == 0) + if (g_strcmp0 (owner, sender) == 0 && g_strcmp0 (id, arg_cancellation_id) == 0) { print_debug ("found op to cancel"); g_cancellable_cancel (cancellable); @@ -1796,215 +1660,87 @@ handle_cancel_operation (DBusConnection *connection, DBusMessage *message) if (!was_cancelled) g_warning ("didn't find op to cancel"); - out: - reply = dbus_message_new_method_return (message); - dbus_message_iter_init_append (reply, &iter); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &was_cancelled); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); + gvfs_remote_volume_monitor_complete_cancel_operation (object, invocation, was_cancelled); - return DBUS_HANDLER_RESULT_HANDLED; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ -static DBusHandlerResult -filter_function (DBusConnection *connection, DBusMessage *message, void *user_data) -{ - DBusHandlerResult ret; - - ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - if (dbus_message_is_signal (message, "org.freedesktop.DBus", "NameLost")) - { - /* means that someone has claimed our name (we allow replacement) */ - g_warning ("Got NameLost, some other instance replaced us"); - exit (0); - } - else if (dbus_message_is_signal (message, "org.freedesktop.DBus", "NameOwnerChanged")) - { - DBusMessageIter iter; - const gchar *name; - const gchar *old_owner; - const gchar *new_owner; - - dbus_message_iter_init (message, &iter); - dbus_message_iter_get_basic (&iter, &name); - dbus_message_iter_next (&iter); - dbus_message_iter_get_basic (&iter, &old_owner); - dbus_message_iter_next (&iter); - dbus_message_iter_get_basic (&iter, &new_owner); - dbus_message_iter_next (&iter); - - print_debug ("NameOwnerChanged: '%s' '%s' '%s'", name, old_owner, new_owner); - - if (strlen (new_owner) == 0) - { - GList *l; - - /* if @name has outstanding mount operation objects; abort them */ - for (l = outstanding_mount_op_objects; l != NULL; l = l->next) - { - GMountOperation *op = G_MOUNT_OPERATION (l->data); - const gchar *owner; - - owner = g_object_get_data (G_OBJECT (op), "mount_op_owner"); - if (g_strcmp0 (owner, name) == 0) - { - print_debug ("****** name `%s' has an outstanding mount operation object, aborting it", - name); - g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED); - } - } - - /* see if @name has outstanding ops; if so, cancel them */ - for (l = outstanding_ops; l != NULL; l = l->next) - { - GCancellable *cancellable = G_CANCELLABLE (l->data); - const gchar *owner; - - owner = g_object_get_data (G_OBJECT (cancellable), "owner"); - print_debug ("looking at op for %s", owner); - if (g_strcmp0 (owner, name) == 0) - { - print_debug ("****** name `%s' has an outstanding op, cancelling it", - name); - g_cancellable_cancel (cancellable); - } - } - - remove_name_owned_changed_for_unique_name (name); - } - - } - else if (g_strcmp0 (dbus_message_get_interface (message), "org.gtk.Private.RemoteVolumeMonitor") == 0 && - g_strcmp0 (dbus_message_get_path (message), "/org/gtk/Private/RemoteVolumeMonitor") == 0) - { - /* If someone is calling into this object and interface, start watching their name so - * we can cancel operations initiated by them when they disconnect - */ - ensure_name_owner_changed_for_unique_name (dbus_message_get_sender (message)); - - if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "IsSupported")) - { - ret = handle_is_supported (connection, message); - } - else - { - if (monitor != NULL) - { - if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "List")) - ret = handle_list (connection, message); - - else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "CancelOperation")) - ret = handle_cancel_operation (connection, message); - - else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "MountUnmount")) - ret = handle_mount_unmount (connection, message); - - else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "VolumeMount")) - ret = handle_volume_mount (connection, message); - - else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveEject")) - ret = handle_drive_eject (connection, message); - - else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "DrivePollForMedia")) - ret = handle_drive_poll_for_media (connection, message); - - else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveStart")) - ret = handle_drive_start (connection, message); - - else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveStop")) - ret = handle_drive_stop (connection, message); - - else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "MountOpReply")) - ret = handle_mount_op_reply (connection, message); - } - } - } - - return ret; -} - -typedef void (*AppendFunc) (void *object, DBusMessageIter *iter); +typedef GVariant * (*MonitorDBusFunc) (void *object); +typedef void (*MonitorSignalFunc) (GVfsRemoteVolumeMonitor *object, + const gchar *arg_dbus_name, + const gchar *arg_id, + GVariant *val); static void -emit_signal (DBusConnection *connection, const char *signal_name, void *object, AppendFunc func) +emit_signal (GVfsRemoteVolumeMonitor *instance, MonitorSignalFunc signal_func, void *object, MonitorDBusFunc func) { char *id; - DBusMessage *message; - DBusMessageIter iter; - + GVariant *val; + + print_debug ("emit_signal: %p", object); + id = g_strdup_printf ("%p", object); + val = func (object); - message = dbus_message_new_signal ("/org/gtk/Private/RemoteVolumeMonitor", - "org.gtk.Private.RemoteVolumeMonitor", - signal_name); - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &the_dbus_name); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &id); - - func (object, &iter); - - dbus_connection_send (connection, message, NULL); - dbus_message_unref (message); - + signal_func (instance, the_dbus_name, id, val); g_free (id); } static void -drive_changed (GVolumeMonitor *monitor, GDrive *drive, DBusConnection *connection) +drive_changed (GVolumeMonitor *monitor, GDrive *drive, GVfsRemoteVolumeMonitor *instance) { - emit_signal (connection, "DriveChanged", drive, (AppendFunc) append_drive); + emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_drive_changed, drive, (MonitorDBusFunc) drive_to_dbus); } static void -drive_connected (GVolumeMonitor *monitor, GDrive *drive, DBusConnection *connection) +drive_connected (GVolumeMonitor *monitor, GDrive *drive, GVfsRemoteVolumeMonitor *instance) { - emit_signal (connection, "DriveConnected", drive, (AppendFunc) append_drive); + emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_drive_connected, drive, (MonitorDBusFunc) drive_to_dbus); } static void -drive_disconnected (GVolumeMonitor *monitor, GDrive *drive, DBusConnection *connection) +drive_disconnected (GVolumeMonitor *monitor, GDrive *drive, GVfsRemoteVolumeMonitor *instance) { - emit_signal (connection, "DriveDisconnected", drive, (AppendFunc) append_drive); + emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_drive_disconnected, drive, (MonitorDBusFunc) drive_to_dbus); } static void -drive_eject_button (GVolumeMonitor *monitor, GDrive *drive, DBusConnection *connection) +drive_eject_button (GVolumeMonitor *monitor, GDrive *drive, GVfsRemoteVolumeMonitor *instance) { - emit_signal (connection, "DriveEjectButton", drive, (AppendFunc) append_drive); + emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_drive_eject_button, drive, (MonitorDBusFunc) drive_to_dbus); } static void -drive_stop_button (GVolumeMonitor *monitor, GDrive *drive, DBusConnection *connection) +drive_stop_button (GVolumeMonitor *monitor, GDrive *drive, GVfsRemoteVolumeMonitor *instance) { - emit_signal (connection, "DriveStopButton", drive, (AppendFunc) append_drive); + emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_drive_stop_button, drive, (MonitorDBusFunc) drive_to_dbus); } static void -volume_changed (GVolumeMonitor *monitor, GVolume *volume, DBusConnection *connection) +volume_changed (GVolumeMonitor *monitor, GVolume *volume, GVfsRemoteVolumeMonitor *instance) { - emit_signal (connection, "VolumeChanged", volume, (AppendFunc) append_volume); + emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_volume_changed, volume, (MonitorDBusFunc) volume_to_dbus); } static void -volume_added (GVolumeMonitor *monitor, GVolume *volume, DBusConnection *connection) +volume_added (GVolumeMonitor *monitor, GVolume *volume, GVfsRemoteVolumeMonitor *instance) { - emit_signal (connection, "VolumeAdded", volume, (AppendFunc) append_volume); + emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_volume_added, volume, (MonitorDBusFunc) volume_to_dbus); } static void -volume_removed (GVolumeMonitor *monitor, GVolume *volume, DBusConnection *connection) +volume_removed (GVolumeMonitor *monitor, GVolume *volume, GVfsRemoteVolumeMonitor *instance) { - emit_signal (connection, "VolumeRemoved", volume, (AppendFunc) append_volume); + emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_volume_removed, volume, (MonitorDBusFunc) volume_to_dbus); } static void -mount_changed (GVolumeMonitor *monitor, GMount *mount, DBusConnection *connection) +mount_changed (GVolumeMonitor *monitor, GMount *mount, GVfsRemoteVolumeMonitor *instance) { - emit_signal (connection, "MountChanged", mount, (AppendFunc) append_mount); + emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_mount_changed, mount, (MonitorDBusFunc) mount_to_dbus); } static void @@ -2016,22 +1752,22 @@ mount_sniff_x_content_type (GMount *mount) } static void -mount_added (GVolumeMonitor *monitor, GMount *mount, DBusConnection *connection) +mount_added (GVolumeMonitor *monitor, GMount *mount, GVfsRemoteVolumeMonitor *instance) { mount_sniff_x_content_type (mount); - emit_signal (connection, "MountAdded", mount, (AppendFunc) append_mount); + emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_mount_added, mount, (MonitorDBusFunc) mount_to_dbus); } static void -mount_pre_unmount (GVolumeMonitor *monitor, GMount *mount, DBusConnection *connection) +mount_pre_unmount (GVolumeMonitor *monitor, GMount *mount, GVfsRemoteVolumeMonitor *instance) { - emit_signal (connection, "MountPreUnmount", mount, (AppendFunc) append_mount); + emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_mount_pre_unmount, mount, (MonitorDBusFunc) mount_to_dbus); } static void -mount_removed (GVolumeMonitor *monitor, GMount *mount, DBusConnection *connection) +mount_removed (GVolumeMonitor *monitor, GMount *mount, GVfsRemoteVolumeMonitor *instance) { - emit_signal (connection, "MountRemoved", mount, (AppendFunc) append_mount); + emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_mount_removed, mount, (MonitorDBusFunc) mount_to_dbus); } void @@ -2049,7 +1785,6 @@ g_vfs_proxy_volume_monitor_daemon_init (void) bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); - dbus_threads_init_default (); g_type_init (); } @@ -2096,17 +1831,89 @@ monitor_try_create (void) g_type_class_unref (klass); } +static void +bus_acquired_handler_cb (GDBusConnection *conn, + const gchar *name, + gpointer user_data) +{ + GError *error; + + if (! conn) + return; + + monitor_daemon = gvfs_remote_volume_monitor_skeleton_new (); + + g_signal_connect (monitor_daemon, "handle-is-supported", G_CALLBACK (handle_is_supported), NULL); + if (monitor != NULL) + { + g_signal_connect (monitor_daemon, "handle-list", G_CALLBACK (handle_list), NULL); + g_signal_connect (monitor_daemon, "handle-cancel-operation", G_CALLBACK (handle_cancel_operation), NULL); + g_signal_connect (monitor_daemon, "handle-drive-eject", G_CALLBACK (handle_drive_eject), NULL); + g_signal_connect (monitor_daemon, "handle-drive-poll-for-media", G_CALLBACK (handle_drive_poll_for_media), NULL); + g_signal_connect (monitor_daemon, "handle-drive-start", G_CALLBACK (handle_drive_start), NULL); + g_signal_connect (monitor_daemon, "handle-drive-stop", G_CALLBACK (handle_drive_stop), NULL); + g_signal_connect (monitor_daemon, "handle-mount-op-reply", G_CALLBACK (handle_mount_op_reply), NULL); + g_signal_connect (monitor_daemon, "handle-mount-unmount", G_CALLBACK (handle_mount_unmount), NULL); + g_signal_connect (monitor_daemon, "handle-volume-mount", G_CALLBACK (handle_volume_mount), NULL); + } + + /* This way we open our d-bus API to public, though there's the "Private" path element */ + error = NULL; + if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (monitor_daemon), conn, + "/org/gtk/Private/RemoteVolumeMonitor", &error)) + { + g_printerr ("Error exporting volume monitor: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); + } + + + if (monitor != NULL) + { + g_signal_connect (monitor, "drive-changed", (GCallback) drive_changed, monitor_daemon); + g_signal_connect (monitor, "drive-connected", (GCallback) drive_connected, monitor_daemon); + g_signal_connect (monitor, "drive-disconnected", (GCallback) drive_disconnected, monitor_daemon); + g_signal_connect (monitor, "drive-eject-button", (GCallback) drive_eject_button, monitor_daemon); + g_signal_connect (monitor, "drive-stop-button", (GCallback) drive_stop_button, monitor_daemon); + + g_signal_connect (monitor, "volume-changed", (GCallback) volume_changed, monitor_daemon); + g_signal_connect (monitor, "volume-added", (GCallback) volume_added, monitor_daemon); + g_signal_connect (monitor, "volume-removed", (GCallback) volume_removed, monitor_daemon); + + g_signal_connect (monitor, "mount-changed", (GCallback) mount_changed, monitor_daemon); + g_signal_connect (monitor, "mount-added", (GCallback) mount_added, monitor_daemon); + g_signal_connect (monitor, "mount-pre-unmount", (GCallback) mount_pre_unmount, monitor_daemon); + g_signal_connect (monitor, "mount-removed", (GCallback) mount_removed, monitor_daemon); + } +} + +static void +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + /* means that someone has claimed our name (we allow replacement) */ + g_main_loop_quit (loop); +} + +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + /* acquired the name %s on the session message bus */ +} + int g_vfs_proxy_volume_monitor_daemon_main (int argc, char *argv[], const char *dbus_name, GType volume_monitor_type) { - int rc G_GNUC_UNUSED; int ret; - GMainLoop *loop; - DBusError dbus_error; + guint name_owner_id; + name_owner_id = 0; ret = 1; loop = g_main_loop_new (NULL, FALSE); @@ -2118,69 +1925,31 @@ g_vfs_proxy_volume_monitor_daemon_main (int argc, the_volume_monitor_type = volume_monitor_type; the_dbus_name = dbus_name; - unique_names_being_watched = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + unique_names_being_watched = g_hash_table_new_full (g_str_hash, g_int_equal, g_free, NULL); /* try and create the monitor */ monitor_try_create (); - dbus_error_init (&dbus_error); - connection = dbus_bus_get (DBUS_BUS_SESSION, &dbus_error); - if (dbus_error_is_set (&dbus_error)) - { - g_warning ("Cannot connect to session bus: %s: %s", dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - goto out; - } - - _g_dbus_connection_integrate_with_main (connection); - - rc = dbus_bus_request_name (connection, - dbus_name, - DBUS_NAME_FLAG_ALLOW_REPLACEMENT | - DBUS_NAME_FLAG_DO_NOT_QUEUE | - DBUS_NAME_FLAG_REPLACE_EXISTING, - &dbus_error); - if (dbus_error_is_set (&dbus_error)) - { - g_warning ("dbus_bus_request_name failed: %s: %s", dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - goto out; - } - if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) - { - g_warning ("Cannot become primary owner"); - goto out; - } - - if (!dbus_connection_add_filter (connection, filter_function, NULL, NULL)) - { - g_warning ("Cannot add filter function"); - goto out; - } - - if (monitor != NULL) - { - g_signal_connect (monitor, "drive-changed", (GCallback) drive_changed, connection); - g_signal_connect (monitor, "drive-connected", (GCallback) drive_connected, connection); - g_signal_connect (monitor, "drive-disconnected", (GCallback) drive_disconnected, connection); - g_signal_connect (monitor, "drive-eject-button", (GCallback) drive_eject_button, connection); - g_signal_connect (monitor, "drive-stop-button", (GCallback) drive_stop_button, connection); - - g_signal_connect (monitor, "volume-changed", (GCallback) volume_changed, connection); - g_signal_connect (monitor, "volume-added", (GCallback) volume_added, connection); - g_signal_connect (monitor, "volume-removed", (GCallback) volume_removed, connection); - - g_signal_connect (monitor, "mount-changed", (GCallback) mount_changed, connection); - g_signal_connect (monitor, "mount-added", (GCallback) mount_added, connection); - g_signal_connect (monitor, "mount-pre-unmount", (GCallback) mount_pre_unmount, connection); - g_signal_connect (monitor, "mount-removed", (GCallback) mount_removed, connection); - } - + name_owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, + dbus_name, + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | + G_BUS_NAME_OWNER_FLAGS_REPLACE, + bus_acquired_handler_cb, + on_name_acquired, + on_name_lost, + NULL, + NULL); g_main_loop_run (loop); - g_main_loop_unref (loop); ret = 0; out: + if (name_owner_id != 0) + g_bus_unown_name (name_owner_id); + if (loop != NULL) + g_main_loop_unref (loop); + if (unique_names_being_watched) + g_hash_table_unref (unique_names_being_watched); + return ret; } |