[glib] appinfo: support opening files through document portal



commit 62bd8f54bbf46b0c34151d6f8b6bd1003155f4a8
Author: Cosimo Cecchi <cosimo endlessm com>
Date:   Mon Jul 11 15:14:34 2016 -0700

    appinfo: support opening files through document portal
    
    In addition to URIs, we now also support opening files internal to the
    sandboxed application through the document portal.

 gio/Makefile.am                          |    5 +
 gio/gappinfo.c                           |   28 +++++++-
 gio/gdocumentportal.c                    |  126 ++++++++++++++++++++++++++++++
 gio/gdocumentportal.h                    |   31 +++++++
 gio/org.freedesktop.portal.Documents.xml |   71 +++++++++++++++++
 5 files changed, 260 insertions(+), 1 deletions(-)
---
diff --git a/gio/Makefile.am b/gio/Makefile.am
index 4ef98aa..e1c0344 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -344,6 +344,7 @@ BUILT_SOURCES += $(xdp_dbus_built_sources)
 CLEANFILES += $(xdp_dbus_built_sources)
 
 portal_interfaces = \
+       org.freedesktop.portal.Documents.xml \
        org.freedesktop.portal.NetworkMonitor.xml \
        org.freedesktop.portal.ProxyResolver.xml \
        $(NULL)
@@ -357,6 +358,8 @@ $(xdp_dbus_built_sources) : $(portal_interfaces)
                --interface-prefix org.freedesktop.portal.              \
                --c-namespace GXdp                                      \
                --generate-c-code $(builddir)/xdp-dbus                  \
+               --annotate "org.freedesktop.portal.Documents.Add()" "org.gtk.GDBus.C.UnixFD" "true" \
+               --annotate "org.freedesktop.portal.Documents.AddNamed()" "org.gtk.GDBus.C.UnixFD" "true" \
                $^
 
 portal_sources = \
@@ -389,6 +392,8 @@ libgio_2_0_la_SOURCES =             \
        gdatagrambased.c        \
        gdatainputstream.c      \
        gdataoutputstream.c     \
+       gdocumentportal.c       \
+       gdocumentportal.h       \
        gdrive.c                \
        gdummyfile.h            \
        gdummyfile.c            \
diff --git a/gio/gappinfo.c b/gio/gappinfo.c
index b6f56b8..78ecab6 100644
--- a/gio/gappinfo.c
+++ b/gio/gappinfo.c
@@ -29,6 +29,7 @@
 #include "glibintl.h"
 #include <gioerror.h>
 #include <gfile.h>
+#include "gdocumentportal.h"
 #include "gportalsupport.h"
 
 
@@ -680,6 +681,8 @@ launch_default_with_portal (const char         *uri,
   GDBusConnection *session_bus;
   GVariantBuilder opt_builder;
   const char *parent_window = NULL;
+  GFile *file;
+  char *real_uri;
 
   session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
   if (session_bus == NULL)
@@ -690,6 +693,28 @@ launch_default_with_portal (const char         *uri,
 
   g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
 
+  file = g_file_new_for_uri (uri);
+
+  if (g_file_is_native (file))
+    {
+      GError *local_error = NULL;
+
+      real_uri = g_document_portal_add_document (file, &local_error);
+      g_object_unref (file);
+
+      if (real_uri == NULL)
+        {
+          g_warning ("Can't register with document portal: %s", local_error->message);
+          g_propagate_error (error, local_error);
+          return FALSE;
+        }
+    }
+  else
+    {
+      g_object_unref (file);
+      real_uri = g_strdup (uri);
+    }
+
   g_dbus_connection_call (session_bus,
                           "org.freedesktop.portal.Desktop",
                           "/org/freedesktop/portal/desktop",
@@ -697,7 +722,7 @@ launch_default_with_portal (const char         *uri,
                           "OpenURI",
                           g_variant_new ("(ss@a{sv})",
                                          parent_window ? parent_window : "",
-                                         uri,
+                                         real_uri,
                                          g_variant_builder_end (&opt_builder)),
                           NULL,
                           G_DBUS_CALL_FLAGS_NONE,
@@ -708,6 +733,7 @@ launch_default_with_portal (const char         *uri,
 
   g_dbus_connection_flush (session_bus, NULL, NULL, NULL);
   g_object_unref (session_bus);
+  g_free (real_uri);
 
   return TRUE;
 }
diff --git a/gio/gdocumentportal.c b/gio/gdocumentportal.c
new file mode 100644
index 0000000..91c7ea2
--- /dev/null
+++ b/gio/gdocumentportal.c
@@ -0,0 +1,126 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright 2016 Endless Mobile, 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "gdocumentportal.h"
+#include "xdp-dbus.h"
+#include "gstdio.h"
+
+#ifdef G_OS_UNIX
+#include "gunixfdlist.h"
+#endif
+
+static GXdpDocuments *documents;
+static char *documents_mountpoint;
+
+static void
+init_document_portal (void)
+{
+  static gsize documents_inited = 0;
+
+  if (g_once_init_enter (&documents_inited))
+    {
+      GError *error = NULL;
+      GDBusConnection *connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+
+      if (connection != NULL)
+        {
+          documents = gxdp_documents_proxy_new_sync (connection, 0,
+                                                     "org.freedesktop.portal.Documents",
+                                                     "/org/freedesktop/portal/documents",
+                                                     NULL, NULL);
+          gxdp_documents_call_get_mount_point_sync (documents,
+                                                    &documents_mountpoint,
+                                                    NULL, NULL);
+
+          g_object_unref (connection);
+        }
+      else
+        {
+          g_warning ("Cannot connect to session bus when initializing document portal: %s",
+                     error->message);
+          g_error_free (error);
+        }
+
+      g_once_init_leave (&documents_inited, 1);
+    }
+}
+
+char *
+g_document_portal_add_document (GFile   *file,
+                                GError **error)
+{
+  char *doc_path, *path, *basename;
+  char *doc_id = NULL;
+  char *doc_uri = NULL;
+  GUnixFDList *fd_list = NULL;
+  int fd, fd_in;
+  gboolean ret;
+
+  init_document_portal ();
+
+  path = g_file_get_path (file);
+  fd = g_open (path, O_PATH | O_CLOEXEC);
+
+  if (fd == -1)
+    {
+      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+                   "Failed to open %s", path);
+      goto out;
+    }
+
+  fd_list = g_unix_fd_list_new ();
+  fd_in = g_unix_fd_list_append (fd_list, fd, error);
+  g_close (fd, NULL);
+
+  if (fd_in == -1)
+    goto out;
+
+  ret = gxdp_documents_call_add_sync (documents,
+                                      g_variant_new_handle (fd_in),
+                                      TRUE,
+                                      TRUE,
+                                      fd_list,
+                                      &doc_id,
+                                      NULL,
+                                      NULL,
+                                      error);
+
+  if (!ret)
+    goto out;
+
+  basename = g_path_get_basename (path);
+  doc_path = g_build_filename (documents_mountpoint, doc_id, basename, NULL);
+  g_free (basename);
+
+  doc_uri = g_filename_to_uri (doc_path, NULL, NULL);
+  g_free (doc_path);
+
+ out:
+  if (fd_list)
+    g_object_unref (fd_list);
+  g_free (path);
+  g_free (doc_id);
+
+  return doc_uri;
+}
diff --git a/gio/gdocumentportal.h b/gio/gdocumentportal.h
new file mode 100644
index 0000000..720768c
--- /dev/null
+++ b/gio/gdocumentportal.h
@@ -0,0 +1,31 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright 2016 Endless Mobile, 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __G_DOCUMENT_PORTAL_H__
+
+#include <glib.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+char * g_document_portal_add_document (GFile   *file,
+                                       GError **error);
+
+G_END_DECLS
+
+#endif
diff --git a/gio/org.freedesktop.portal.Documents.xml b/gio/org.freedesktop.portal.Documents.xml
new file mode 100644
index 0000000..c466c52
--- /dev/null
+++ b/gio/org.freedesktop.portal.Documents.xml
@@ -0,0 +1,71 @@
+<!DOCTYPE node PUBLIC
+"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
+
+<!--
+ Copyright (C) 2015 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: Alexander Larsson <alexl redhat com>
+-->
+
+<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd";>
+  <interface name='org.freedesktop.portal.Documents'>
+    <method name="GetMountPoint">
+      <arg type='ay' name='path' direction='out'/>
+    </method>
+    <method name="Add">
+      <arg type='h' name='o_path_fd' direction='in'/>
+      <arg type='b' name='reuse_existing' direction='in'/>
+      <arg type='b' name='persistent' direction='in'/>
+      <arg type='s' name='doc_id' direction='out'/>
+    </method>
+    <method name="AddNamed">
+      <arg type='h' name='o_path_parent_fd' direction='in'/>
+      <arg type='ay' name='filename' direction='in'/>
+      <arg type='b' name='reuse_existing' direction='in'/>
+      <arg type='b' name='persistent' direction='in'/>
+      <arg type='s' name='doc_id' direction='out'/>
+    </method>
+    <method name="GrantPermissions">
+      <arg type='s' name='doc_id' direction='in'/>
+      <arg type='s' name='app_id' direction='in'/>
+      <arg type='as' name='permissions' direction='in'/>
+    </method>
+    <method name="RevokePermissions">
+      <arg type='s' name='doc_id' direction='in'/>
+      <arg type='s' name='app_id' direction='in'/>
+      <arg type='as' name='permissions' direction='in'/>
+    </method>
+    <method name="Delete">
+      <arg type='s' name='doc_id' direction='in'/>
+    </method>
+    <method name="Lookup">
+      <arg type='ay' name='filename' direction='in'/>
+      <arg type='s' name='doc_id' direction='out'/>
+    </method>
+    <method name="Info">
+      <arg type='s' name='doc_id' direction='in'/>
+      <arg type='ay' name='path' direction='out'/>
+      <arg type='a{sas}' name='apps' direction='out'/>
+    </method>
+    <method name="List">
+      <arg type='s' name='app_id' direction='in'/>
+      <arg type='a{say}' name='docs' direction='out'/>
+    </method>
+  </interface>
+</node>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]