[gvfs/wip/goa: 4/4] Add GVfsGoaVolumeMonitor
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs/wip/goa: 4/4] Add GVfsGoaVolumeMonitor
- Date: Tue, 23 Oct 2012 20:16:55 +0000 (UTC)
commit 2c09145f1fdcff5cbe52d3ebdb2b1d8d7ef7c53f
Author: Debarshi Ray <debarshir gnome org>
Date: Tue Oct 23 21:46:33 2012 +0200
Add GVfsGoaVolumeMonitor
https://bugzilla.gnome.org/show_bug.cgi?id=686526
configure.ac | 24 +
monitor/Makefile.am | 6 +-
monitor/goa/Makefile.am | 46 ++
monitor/goa/goa.monitor | 4 +
monitor/goa/goavolume.c | 480 ++++++++++++++++++++
monitor/goa/goavolume.h | 68 +++
monitor/goa/goavolumemonitor.c | 222 +++++++++
monitor/goa/goavolumemonitor.h | 63 +++
monitor/goa/goavolumemonitordaemon.c | 49 ++
.../org.gtk.Private.GoaVolumeMonitor.service.in | 3 +
10 files changed, 964 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index e3dde83..92abff6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -374,6 +374,28 @@ AC_SUBST(AFC_CFLAGS)
AM_CONDITIONAL(USE_AFC, [test "$msg_afc" = "yes"])
+dnl *************************************************
+dnl *** Check if we should build with GOA backend ***
+dnl *************************************************
+AC_ARG_ENABLE(goa, AS_HELP_STRING([--disable-goa],[build without GOA backend]))
+msg_goa=no
+GOA_LIBS=
+GOA_CFLAGS=
+
+if test "x$enable_goa" != "xno" ; then
+ PKG_CHECK_EXISTS(goa-1.0 >= 3.7.1, msg_goa=yes)
+
+ if test "x$msg_goa" = "xyes"; then
+ PKG_CHECK_MODULES(GOA, goa-1.0)
+ AC_DEFINE(HAVE_GOA, 1, [Define to 1 if GOA is going to be built])
+ fi
+fi
+
+AC_SUBST(GOA_LIBS)
+AC_SUBST(GOA_CFLAGS)
+
+AM_CONDITIONAL(USE_GOA, [test "$msg_goa" = "yes"])
+
dnl *****************************************************
dnl *** Check if we should build with obexftp backend ***
dnl *****************************************************
@@ -830,6 +852,7 @@ monitor/gdu/Makefile
monitor/udisks2/Makefile
monitor/gphoto2/Makefile
monitor/afc/Makefile
+monitor/goa/Makefile
programs/Makefile
man/Makefile
test/Makefile
@@ -857,6 +880,7 @@ echo "
Build HAL volume monitor: $msg_hal (with fast init path: $have_hal_fast_init)
Build GDU volume monitor: $msg_gdu
Build udisks2 volume monitor: $msg_udisks2
+ Build GOA volume monitor: $msg_goa
Use libsystemd-login: $msg_libsystemd_login
GNOME Keyring support: $msg_keyring
GTK+ support: $msg_gtk
diff --git a/monitor/Makefile.am b/monitor/Makefile.am
index d903df1..080e624 100644
--- a/monitor/Makefile.am
+++ b/monitor/Makefile.am
@@ -1,4 +1,4 @@
-DIST_SUBDIRS = proxy hal gdu gphoto2 afc udisks2
+DIST_SUBDIRS = proxy hal gdu gphoto2 afc udisks2 goa
SUBDIRS = proxy
if USE_HAL
@@ -20,3 +20,7 @@ endif
if USE_AFC
SUBDIRS += afc
endif
+
+if USE_GOA
+SUBDIRS += goa
+endif
diff --git a/monitor/goa/Makefile.am b/monitor/goa/Makefile.am
new file mode 100644
index 0000000..e8ef564
--- /dev/null
+++ b/monitor/goa/Makefile.am
@@ -0,0 +1,46 @@
+NULL =
+
+gvfs_src_dir = $(top_srcdir)/@with_gvfs_source@
+
+libexec_PROGRAMS = gvfs-goa-volume-monitor
+
+gvfs_goa_volume_monitor_SOURCES = \
+ goavolume.c goavolume.h \
+ goavolumemonitor.c goavolumemonitor.h \
+ goavolumemonitordaemon.c \
+ $(NULL)
+
+gvfs_goa_volume_monitor_CFLAGS = \
+ -DG_LOG_DOMAIN=\"GVFS-GOA\" \
+ -I$(top_srcdir)/common \
+ -I$(top_srcdir)/monitor/proxy \
+ $(GLIB_CFLAGS) \
+ $(GOA_CFLAGS) \
+ $(WARN_CFLAGS) \
+ -DGIO_MODULE_DIR=\"$(GIO_MODULE_DIR)\" \
+ -DGVFS_LOCALEDIR=\"$(localedir)\" \
+ $(NULL)
+
+gvfs_goa_volume_monitor_LDADD = \
+ $(GLIB_LIBS) \
+ $(GOA_LIBS) \
+ $(top_builddir)/common/libgvfscommon.la \
+ $(top_builddir)/monitor/proxy/libgvfsproxyvolumemonitordaemon-noin.la \
+ $(NULL)
+
+remote_volume_monitorsdir = $(datadir)/gvfs/remote-volume-monitors
+remote_volume_monitors_DATA = goa.monitor
+
+servicedir = $(datadir)/dbus-1/services
+service_in_files = org.gtk.Private.GoaVolumeMonitor.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) $(SED) -e "s|\ libexecdir\@|$(libexecdir)|" $< > $@
+
+clean-local:
+ rm -f *~ *.loT $(BUILT_SOURCES) $(service_DATA)
+
+DISTCLEANFILES = $(service_DATA)
+
+EXTRA_DIST = $(service_in_files) goa.monitor
diff --git a/monitor/goa/goa.monitor b/monitor/goa/goa.monitor
new file mode 100644
index 0000000..a763c6b
--- /dev/null
+++ b/monitor/goa/goa.monitor
@@ -0,0 +1,4 @@
+[RemoteVolumeMonitor]
+Name=GProxyVolumeMonitorGoa
+DBusName=org.gtk.Private.GoaVolumeMonitor
+IsNative=false
diff --git a/monitor/goa/goavolume.c b/monitor/goa/goavolume.c
new file mode 100644
index 0000000..8873585
--- /dev/null
+++ b/monitor/goa/goavolume.c
@@ -0,0 +1,480 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* gvfs - extensions for gio
+ *
+ * Copyright (C) 2012 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Debarshi Ray <debarshir gnome org>
+ */
+
+#include <config.h>
+#include <string.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <glib/gi18n.h>
+
+#include "goavolume.h"
+
+struct _GVfsGoaVolume
+{
+ GObject parent;
+ GFile *root;
+ GMount *mount;
+ GoaObject *object;
+ gchar *uuid;
+ gchar *icon;
+ gchar *symbolic_icon;
+};
+
+struct _GVfsGoaVolumeClass
+{
+ GObjectClass parent_class;
+};
+
+enum
+{
+ PROP_0,
+ PROP_ACCOUNT,
+ PROP_UUID
+};
+
+static void g_vfs_goa_volume_iface_init (GVolumeIface *iface);
+
+G_DEFINE_TYPE_EXTENDED (GVfsGoaVolume, g_vfs_goa_volume, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (G_TYPE_VOLUME,
+ g_vfs_goa_volume_iface_init))
+
+typedef struct
+{
+ GAsyncReadyCallback callback;
+ GCancellable *cancellable;
+ GMountOperation *mount_operation;
+ GSimpleAsyncResult *simple;
+ gpointer user_data;
+} MountOp;
+
+static void
+mount_op_free (MountOp *data)
+{
+ g_clear_object (&data->cancellable);
+ g_clear_object (&data->mount_operation);
+ g_object_unref (data->simple);
+ g_slice_free (MountOp, data);
+}
+
+static void
+mount_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ MountOp *data = user_data;
+
+ if (data->callback != NULL)
+ data->callback (source_object, res, data->user_data);
+
+ mount_op_free (data);
+}
+
+static void
+find_enclosing_mount_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ GFile *root = G_FILE (source_object);
+ GSimpleAsyncResult *simple = user_data;
+ GVfsGoaVolume *self;
+ GError *error;
+ MountOp *data;
+
+ self = G_VFS_GOA_VOLUME (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
+ data = g_async_result_get_user_data (G_ASYNC_RESULT (simple));
+
+ error = NULL;
+ g_clear_object (&self->mount);
+ self->mount = g_file_find_enclosing_mount_finish (root, res, &error);
+ if (error != NULL)
+ g_simple_async_result_take_error (simple, error);
+
+ g_simple_async_result_complete (simple);
+}
+
+static void
+mount_enclosing_volume_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ GFile *root = G_FILE (source_object);
+ GSimpleAsyncResult *simple = user_data;
+ GVfsGoaVolume *self;
+ GError *error;
+ MountOp *data;
+
+ self = G_VFS_GOA_VOLUME (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
+ data = g_async_result_get_user_data (G_ASYNC_RESULT (simple));
+
+ error = NULL;
+ if (!g_file_mount_enclosing_volume_finish (root, res, &error))
+ {
+ if (error->code == G_IO_ERROR_CANCELLED)
+ {
+ g_simple_async_result_take_error (simple, error);
+ g_simple_async_result_complete (simple);
+ return;
+ }
+ else
+ {
+ g_warning ("Failed to mount %s: %s", g_file_get_uri (root), error->message);
+ g_error_free (error);
+ /* We carry on because the failure could have been caused
+ * by a volume that was already mounted.
+ */
+ }
+ }
+
+ g_file_find_enclosing_mount_async (root, G_PRIORITY_DEFAULT, NULL, find_enclosing_mount_cb, simple);
+}
+
+static void
+get_password_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ GoaPasswordBased *passwd_based = GOA_PASSWORD_BASED (source_object);
+ GSimpleAsyncResult *simple = user_data;
+ GVfsGoaVolume *self;
+ GError *error;
+ GoaAccount *account;
+ GoaFiles *files;
+ MountOp *data;
+ gchar *passwd;
+
+ self = G_VFS_GOA_VOLUME (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
+ data = g_async_result_get_user_data (G_ASYNC_RESULT (simple));
+ passwd = NULL;
+
+ error = NULL;
+ if (!goa_password_based_call_get_password_finish (passwd_based, &passwd, res, &error))
+ {
+ g_simple_async_result_take_error (simple, error);
+ g_simple_async_result_complete (simple);
+ goto out;
+ }
+
+ account = goa_object_peek_account (self->object);
+ files = goa_object_peek_files (self->object);
+ if (files == NULL)
+ {
+ g_simple_async_result_set_error (simple,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "Failed to get org.gnome.OnlineAccounts.Files for %s",
+ goa_account_get_id (account));
+ g_simple_async_result_complete (simple);
+ goto out;
+ }
+
+ g_mount_operation_set_username (data->mount_operation, goa_account_get_identity (account));
+ g_mount_operation_set_password (data->mount_operation, passwd);
+ g_file_mount_enclosing_volume (self->root,
+ G_MOUNT_MOUNT_NONE,
+ data->mount_operation,
+ data->cancellable,
+ mount_enclosing_volume_cb,
+ simple);
+ out:
+ g_free (passwd);
+}
+
+static void
+ensure_credentials_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ GoaAccount *account = GOA_ACCOUNT (source_object);
+ GSimpleAsyncResult *simple = user_data;
+ GVfsGoaVolume *self;
+ GError *error;
+ GoaPasswordBased *passwd_based;
+ MountOp *data;
+
+ self = G_VFS_GOA_VOLUME (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
+ data = g_async_result_get_user_data (G_ASYNC_RESULT (simple));
+
+ error = NULL;
+ if (!goa_account_call_ensure_credentials_finish (account, NULL, res, &error))
+ {
+ g_simple_async_result_take_error (simple, error);
+ g_simple_async_result_complete (simple);
+ return;
+ }
+
+ passwd_based = goa_object_peek_password_based (self->object);
+ if (passwd_based != NULL)
+ {
+ const gchar *id;
+
+ id = goa_account_get_id (account);
+ goa_password_based_call_get_password (passwd_based, id, data->cancellable, get_password_cb, simple);
+ }
+}
+
+static gboolean
+g_vfs_goa_volume_can_mount (GVolume *_self)
+{
+ return TRUE;
+}
+
+static char **
+g_vfs_goa_volume_enumerate_identifiers (GVolume *_self)
+{
+ GVfsGoaVolume *self = G_VFS_GOA_VOLUME (_self);
+ GPtrArray *res;
+
+ res = g_ptr_array_new ();
+ g_ptr_array_add (res, g_strdup (G_VOLUME_IDENTIFIER_KIND_CLASS));
+ g_ptr_array_add (res, g_strdup (G_VOLUME_IDENTIFIER_KIND_UUID));
+ g_ptr_array_add (res, NULL);
+
+ return (gchar **) g_ptr_array_free (res, FALSE);
+}
+
+static GFile *
+g_vfs_goa_volume_get_activation_root (GVolume *_self)
+{
+ GVfsGoaVolume *self = G_VFS_GOA_VOLUME (_self);
+ return g_object_ref (self->root);
+}
+
+static GDrive *
+g_vfs_goa_volume_get_drive (GVolume *volume)
+{
+ return NULL;
+}
+
+static GIcon *
+g_vfs_goa_volume_get_icon (GVolume *_self)
+{
+ GVfsGoaVolume *self = G_VFS_GOA_VOLUME (_self);
+ return g_themed_icon_new_with_default_fallbacks (self->icon);
+}
+
+static char *
+g_vfs_goa_volume_get_identifier (GVolume *_self, const gchar *kind)
+{
+ GVfsGoaVolume *self = G_VFS_GOA_VOLUME (_self);
+
+ if (g_strcmp0 (kind, G_VOLUME_IDENTIFIER_KIND_CLASS) == 0)
+ return g_strdup ("network");
+ else if (g_strcmp0 (kind, G_VOLUME_IDENTIFIER_KIND_UUID) == 0)
+ return g_strdup (self->uuid);
+
+ return NULL;
+}
+
+static GMount *
+g_vfs_goa_volume_get_mount (GVolume *_self)
+{
+ GVfsGoaVolume *self = G_VFS_GOA_VOLUME (_self);
+ return self->mount;
+}
+
+static char *
+g_vfs_goa_volume_get_name (GVolume *_self)
+{
+ GVfsGoaVolume *self = G_VFS_GOA_VOLUME (_self);
+ GoaAccount *account;
+
+ account = goa_object_peek_account (self->object);
+ return goa_account_dup_presentation_identity (account);
+}
+
+static GIcon *
+g_vfs_goa_volume_get_symbolic_icon (GVolume *_self)
+{
+ GVfsGoaVolume *self = G_VFS_GOA_VOLUME (_self);
+ return g_themed_icon_new_with_default_fallbacks (self->symbolic_icon);
+}
+
+static char *
+g_vfs_goa_volume_get_uuid (GVolume *_self)
+{
+ GVfsGoaVolume *self = G_VFS_GOA_VOLUME (_self);
+ return g_strdup (self->uuid);
+}
+
+static void
+g_vfs_goa_volume_mount (GVolume *_self,
+ GMountMountFlags flags,
+ GMountOperation *mount_operation,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GVfsGoaVolume *self = G_VFS_GOA_VOLUME (_self);
+ MountOp *data;
+ GSimpleAsyncResult *simple;
+ GoaAccount *account;
+
+ data = g_slice_new0 (MountOp);
+ simple = g_simple_async_result_new (G_OBJECT (self), mount_cb, data, g_vfs_goa_volume_mount);
+
+ data->simple = simple;
+ data->callback = callback;
+ data->user_data = user_data;
+
+ if (cancellable != NULL)
+ {
+ data->cancellable = g_object_ref (cancellable);
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
+ }
+
+ if (mount_operation == NULL)
+ data->mount_operation = g_mount_operation_new ();
+ else
+ data->mount_operation = g_object_ref (mount_operation);
+
+ account = goa_object_peek_account (self->object);
+ goa_account_call_ensure_credentials (account, data->cancellable, ensure_credentials_cb, simple);
+}
+
+static gboolean
+g_vfs_goa_volume_mount_finish (GVolume *_self, GAsyncResult *res, GError **error)
+{
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);;
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (_self), g_vfs_goa_volume_mount), FALSE);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+g_vfs_goa_volume_should_automount (GVolume *volume)
+{
+ return FALSE;
+}
+
+static void
+g_vfs_goa_volume_constructed (GObject *_self)
+{
+ GVfsGoaVolume *self = G_VFS_GOA_VOLUME (_self);
+
+ G_OBJECT_CLASS (g_vfs_goa_volume_parent_class)->constructed (_self);
+ self->root = g_file_new_for_uri (self->uuid);
+}
+
+static void
+g_vfs_goa_volume_dispose (GObject *_self)
+{
+ GVfsGoaVolume *self = G_VFS_GOA_VOLUME (_self);
+
+ g_clear_object (&self->root);
+ g_clear_object (&self->mount);
+ g_clear_object (&self->object);
+
+ G_OBJECT_CLASS (g_vfs_goa_volume_parent_class)->dispose (_self);
+}
+
+static void
+g_vfs_goa_volume_finalize (GObject *_self)
+{
+ GVfsGoaVolume *self = G_VFS_GOA_VOLUME (_self);
+
+ g_free (self->uuid);
+ g_free (self->icon);
+ g_free (self->symbolic_icon);
+
+ G_OBJECT_CLASS (g_vfs_goa_volume_parent_class)->finalize (_self);
+}
+
+static void
+g_vfs_goa_volume_set_property (GObject *_self, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GVfsGoaVolume *self = G_VFS_GOA_VOLUME (_self);
+
+ switch (prop_id)
+ {
+ case PROP_ACCOUNT:
+ self->object = g_value_dup_object (value);
+ break;
+
+ case PROP_UUID:
+ self->uuid = g_value_dup_string (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (_self, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+g_vfs_goa_volume_class_init (GVfsGoaVolumeClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->constructed = g_vfs_goa_volume_constructed;
+ gobject_class->dispose = g_vfs_goa_volume_dispose;
+ gobject_class->finalize = g_vfs_goa_volume_finalize;
+ gobject_class->set_property = g_vfs_goa_volume_set_property;
+
+ g_object_class_install_property (gobject_class,
+ PROP_ACCOUNT,
+ g_param_spec_object ("account",
+ "GoaObject object",
+ "The GOA account represented by the volume",
+ GOA_TYPE_OBJECT,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_WRITABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_UUID,
+ g_param_spec_string ("uuid",
+ "UUID",
+ "The UUID of the volume",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_WRITABLE));
+}
+
+static void
+g_vfs_goa_volume_init (GVfsGoaVolume *self)
+{
+ self->icon = g_strdup ("network-server");
+ self->symbolic_icon = g_strdup ("network-server-symbolic");
+}
+
+static void
+g_vfs_goa_volume_iface_init (GVolumeIface *iface)
+{
+ iface->can_mount = g_vfs_goa_volume_can_mount;
+ iface->enumerate_identifiers = g_vfs_goa_volume_enumerate_identifiers;
+ iface->get_activation_root = g_vfs_goa_volume_get_activation_root;
+ iface->get_drive = g_vfs_goa_volume_get_drive;
+ iface->get_icon = g_vfs_goa_volume_get_icon;
+ iface->get_identifier = g_vfs_goa_volume_get_identifier;
+ iface->get_mount = g_vfs_goa_volume_get_mount;
+ iface->get_name = g_vfs_goa_volume_get_name;
+ iface->get_symbolic_icon = g_vfs_goa_volume_get_symbolic_icon;
+ iface->get_uuid = g_vfs_goa_volume_get_uuid;
+ iface->mount_fn = g_vfs_goa_volume_mount;
+ iface->mount_finish = g_vfs_goa_volume_mount_finish;
+ iface->should_automount = g_vfs_goa_volume_should_automount;
+}
+
+GVfsGoaVolume *
+g_vfs_goa_volume_new (GoaObject *object, const gchar *uuid)
+{
+ return g_object_new (G_VFS_TYPE_GOA_VOLUME,
+ "account", object,
+ "uuid", uuid,
+ NULL);
+}
diff --git a/monitor/goa/goavolume.h b/monitor/goa/goavolume.h
new file mode 100644
index 0000000..5760372
--- /dev/null
+++ b/monitor/goa/goavolume.h
@@ -0,0 +1,68 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* gvfs - extensions for gio
+ *
+ * Copyright (C) 2012 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Debarshi Ray <debarshir gnome org>
+ */
+
+#ifndef __GOA_VOLUME_H__
+#define __GOA_VOLUME_H__
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#define GOA_API_IS_SUBJECT_TO_CHANGE
+#include <goa/goa.h>
+
+#include "goavolumemonitor.h"
+
+G_BEGIN_DECLS
+
+#define G_VFS_TYPE_GOA_VOLUME (g_vfs_goa_volume_get_type())
+
+#define G_VFS_GOA_VOLUME(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST((o), \
+ G_VFS_TYPE_GOA_VOLUME, GVfsGoaVolume))
+
+#define G_VFS_GOA_VOLUME_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_CAST((k), \
+ G_VFS_TYPE_GOA_VOLUME, GVfsGoaVolumeClass))
+
+#define G_VFS_IS_GOA_VOLUME(o) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((o), \
+ G_VFS_TYPE_GOA_VOLUME))
+
+#define G_VFS_IS_GOA_VOLUME_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_TYPE((k), \
+ G_VFS_TYPE_GOA_VOLUME))
+
+#define G_VFS_GOA_VOLUME_GET_CLASS(o) \
+ (G_TYPE_INSTANCE_GET_CLASS((o), \
+ G_VFS_TYPE_GOA_VOLUME, GVfsGoaVolumeClass))
+
+typedef struct _GVfsGoaVolume GVfsGoaVolume;
+typedef struct _GVfsGoaVolumeClass GVfsGoaVolumeClass;
+
+GType g_vfs_goa_volume_get_type (void) G_GNUC_CONST;
+
+GVfsGoaVolume *g_vfs_goa_volume_new (GoaObject *object, const gchar *uuid);
+
+G_END_DECLS
+
+#endif /* __GOA_VOLUME_H__ */
diff --git a/monitor/goa/goavolumemonitor.c b/monitor/goa/goavolumemonitor.c
new file mode 100644
index 0000000..fec383a
--- /dev/null
+++ b/monitor/goa/goavolumemonitor.c
@@ -0,0 +1,222 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* gvfs - extensions for gio
+ *
+ * Copyright (C) 2012 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Debarshi Ray <debarshir gnome org>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#define GOA_API_IS_SUBJECT_TO_CHANGE
+#include <goa/goa.h>
+
+#include <gvfsproxyvolumemonitordaemon.h>
+#include "goavolume.h"
+#include "goavolumemonitor.h"
+
+struct _GVfsGoaVolumeMonitor
+{
+ GNativeVolumeMonitor parent;
+ GHashTable *accounts;
+ GoaClient *client;
+};
+
+struct _GVfsGoaVolumeMonitorClass
+{
+ GVolumeMonitorClass parent_class;
+};
+
+G_DEFINE_TYPE(GVfsGoaVolumeMonitor, g_vfs_goa_volume_monitor, G_TYPE_VOLUME_MONITOR)
+
+static void
+toggle_account (GVfsGoaVolumeMonitor *self, GoaObject *object, gboolean enabled)
+{
+ GVfsGoaVolume *volume;
+
+ if (enabled)
+ {
+ GoaFiles *files;
+
+ files = goa_object_peek_files (object);
+ volume = g_vfs_goa_volume_new (object, goa_files_get_uri (files));
+ g_object_set_data_full (G_OBJECT (object), "volume", volume, g_object_unref);
+ g_signal_emit_by_name (self, "volume-added", volume);
+ }
+ else
+ {
+ volume = g_object_get_data (G_OBJECT (object), "volume");
+ g_signal_emit_by_name (self, "volume-removed", volume);
+ g_object_set_data (G_OBJECT (object), "volume", NULL);
+ }
+}
+
+static void
+account_files_changed (GObject *_object, GParamSpec *pspec, gpointer user_data)
+{
+ GoaObject *object = GOA_OBJECT (_object);
+ GVfsGoaVolumeMonitor *self = user_data;
+ gboolean enabled;
+
+ enabled = (goa_object_peek_files (object) != NULL);
+ toggle_account (self, object, enabled);
+}
+
+static void
+add_account (GVfsGoaVolumeMonitor *self, GoaObject *object)
+{
+ GoaAccount *account;
+ gchar *id;
+
+ account = goa_object_peek_account (object);
+ id = goa_account_dup_id (account);
+ g_hash_table_insert (self->accounts, id, g_object_ref (object));
+
+ g_signal_connect (object, "notify::files", G_CALLBACK (account_files_changed), self);
+ account_files_changed (G_OBJECT (object), NULL, self);
+}
+
+static void
+account_added_cb (GoaClient *client, GoaObject *object, gpointer user_data)
+{
+ GVfsGoaVolumeMonitor *self = user_data;
+ add_account (self, object);
+}
+
+static void
+account_removed_cb (GoaClient *client, GoaObject *object, gpointer user_data)
+{
+ GVfsGoaVolumeMonitor *self = user_data;
+ GoaAccount *account;
+ const gchar *id;
+
+ toggle_account (self, object, FALSE);
+
+ account = goa_object_peek_account (object);
+ id = goa_account_get_id (account);
+ g_hash_table_remove (self->accounts, id);
+}
+
+static GList *
+g_vfs_goa_volume_monitor_get_connected_drives (GVolumeMonitor *_self)
+{
+ return NULL;
+}
+
+static GList *
+g_vfs_goa_volume_monitor_get_mounts (GVolumeMonitor *_self)
+{
+ return NULL;
+}
+
+static GList *
+g_vfs_goa_volume_monitor_get_volumes (GVolumeMonitor *_self)
+{
+ GVfsGoaVolumeMonitor *self = G_VFS_GOA_VOLUME_MONITOR (_self);
+ GHashTableIter iter;
+ GList *volumes;
+ GoaObject *object;
+
+ volumes = NULL;
+
+ if (self->accounts == NULL)
+ goto out;
+
+ g_hash_table_iter_init (&iter, self->accounts);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &object))
+ {
+ GVfsGoaVolume *volume;
+
+ volume = g_object_get_data (G_OBJECT (object), "volume");
+ if (volume != NULL)
+ volumes = g_list_append (volumes, g_object_ref (volume));
+ }
+
+ out:
+ return volumes;
+}
+
+static gboolean
+g_vfs_goa_volume_monitor_is_supported (void)
+{
+ return TRUE;
+}
+
+static void
+g_vfs_goa_volume_monitor_dispose (GObject *_self)
+{
+ GVfsGoaVolumeMonitor *self = G_VFS_GOA_VOLUME_MONITOR (_self);
+
+ g_clear_pointer (&self->accounts, g_hash_table_unref);
+ g_clear_object (&self->client);
+
+ G_OBJECT_CLASS (g_vfs_goa_volume_monitor_parent_class)->dispose (_self);
+}
+
+static void
+g_vfs_goa_volume_monitor_class_init (GVfsGoaVolumeMonitorClass * klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GVolumeMonitorClass *monitor_class = G_VOLUME_MONITOR_CLASS (klass);
+
+ gobject_class->dispose = g_vfs_goa_volume_monitor_dispose;
+
+ monitor_class->get_connected_drives = g_vfs_goa_volume_monitor_get_connected_drives;
+ monitor_class->get_mounts = g_vfs_goa_volume_monitor_get_mounts;
+ monitor_class->get_volumes = g_vfs_goa_volume_monitor_get_volumes;
+ monitor_class->is_supported = g_vfs_goa_volume_monitor_is_supported;
+}
+
+static void
+g_vfs_goa_volume_monitor_init (GVfsGoaVolumeMonitor *self)
+{
+ GError *error;
+ GList *accounts;
+ GList *l;
+
+ error = NULL;
+ self->client = goa_client_new_sync (NULL, &error);
+ if (error != NULL)
+ {
+ g_warning ("Failed to connect to GOA: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ self->accounts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+
+ accounts = goa_client_get_accounts (self->client);
+ for (l = accounts; l !=NULL; l = l->next)
+ add_account (self, GOA_OBJECT (l->data));
+
+ g_list_free_full (accounts, g_object_unref);
+
+ g_signal_connect (self->client, "account-added", G_CALLBACK (account_added_cb), self);
+ g_signal_connect (self->client, "account-removed", G_CALLBACK (account_removed_cb), self);
+}
+
+GVolumeMonitor *
+g_vfs_goa_volume_monitor_new (void)
+{
+ return g_object_new (G_VFS_TYPE_GOA_VOLUME_MONITOR, NULL);
+}
diff --git a/monitor/goa/goavolumemonitor.h b/monitor/goa/goavolumemonitor.h
new file mode 100644
index 0000000..149f86e
--- /dev/null
+++ b/monitor/goa/goavolumemonitor.h
@@ -0,0 +1,63 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* gvfs - extensions for gio
+ *
+ * Copyright (C) 2012 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Debarshi Ray <debarshir gnome org>
+ */
+
+#ifndef __GOA_VOLUME_MONITOR_H__
+#define __GOA_VOLUME_MONITOR_H__
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define G_VFS_TYPE_GOA_VOLUME_MONITOR (g_vfs_goa_volume_monitor_get_type())
+
+#define G_VFS_GOA_VOLUME_MONITOR(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST((o), \
+ G_VFS_TYPE_GOA_VOLUME_MONITOR, GVfsGoaVolumeMonitor))
+
+#define G_VFS_GOA_VOLUME_MONITOR_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_CAST((k), \
+ G_VFS_TYPE_GOA_VOLUME_MONITOR, GVfsGoaVolumeMonitorClass))
+
+#define G_VFS_IS_GOA_VOLUME_MONITOR(o) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((o), \
+ G_VFS_TYPE_GOA_VOLUME_MONITOR))
+
+#define G_VFS_IS_GOA_VOLUME_MONITOR_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_TYPE((k), \
+ G_VFS_TYPE_GOA_VOLUME_MONITOR))
+
+#define G_VFS_GOA_VOLUME_MONITOR_GET_CLASS(o) \
+ (G_TYPE_INSTANCE_GET_CLASS((o), \
+ G_VFS_TYPE_GOA_VOLUME_MONITOR, GVfsGoaVolumeMonitorClass))
+
+typedef struct _GVfsGoaVolumeMonitor GVfsGoaVolumeMonitor;
+typedef struct _GVfsGoaVolumeMonitorClass GVfsGoaVolumeMonitorClass;
+
+GType g_vfs_goa_volume_monitor_get_type (void) G_GNUC_CONST;
+
+GVolumeMonitor *g_vfs_goa_volume_monitor_new (void);
+
+G_END_DECLS
+
+#endif /* __GOA_VOLUME_MONITOR_H__ */
diff --git a/monitor/goa/goavolumemonitordaemon.c b/monitor/goa/goavolumemonitordaemon.c
new file mode 100644
index 0000000..5765a67
--- /dev/null
+++ b/monitor/goa/goavolumemonitordaemon.c
@@ -0,0 +1,49 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* gvfs - extensions for gio
+ *
+ * Copyright (C) 2012 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Debarshi Ray <debarshir gnome org>
+ */
+
+#include <config.h>
+
+#include <locale.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+
+#include <gvfsproxyvolumemonitordaemon.h>
+#include "goavolumemonitor.h"
+
+int
+main (int argc, char *argv[])
+{
+ setlocale (LC_ALL, "");
+
+ bindtextdomain (GETTEXT_PACKAGE, GVFS_LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ g_vfs_proxy_volume_monitor_daemon_init ();
+ return g_vfs_proxy_volume_monitor_daemon_main (argc,
+ argv,
+ "org.gtk.Private.GoaVolumeMonitor",
+ G_VFS_TYPE_GOA_VOLUME_MONITOR);
+}
diff --git a/monitor/goa/org.gtk.Private.GoaVolumeMonitor.service.in b/monitor/goa/org.gtk.Private.GoaVolumeMonitor.service.in
new file mode 100644
index 0000000..cb9a351
--- /dev/null
+++ b/monitor/goa/org.gtk.Private.GoaVolumeMonitor.service.in
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.gtk.Private.GoaVolumeMonitor
+Exec= libexecdir@/gvfs-goa-volume-monitor
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]