Blame SOURCES/gvfs-1.16.1-WIP-Use-android-extensions-to-support-in-place-read-.patch

769c0b
From 1dcd334d633a79bf2a81f8bcb8e463864a858fa1 Mon Sep 17 00:00:00 2001
769c0b
From: Philip Langdale <philipl@overt.org>
769c0b
Date: Mon, 11 Feb 2013 07:55:11 -0800
769c0b
Subject: [PATCH 2/5] WIP: Use android extensions to support in place read of
769c0b
 files.
769c0b
769c0b
Allows for opening files directly on the device and reading from them.
769c0b
---
769c0b
 configure.ac            |    5 +++
769c0b
 daemon/gvfsbackendmtp.c |   84 +++++++++++++++++++++++++++++++++++++++++++++--
769c0b
 daemon/gvfsbackendmtp.h |    2 ++
769c0b
 3 files changed, 89 insertions(+), 2 deletions(-)
769c0b
769c0b
diff --git a/configure.ac b/configure.ac
769c0b
index 0f5ab9a..4b88316 100644
769c0b
--- a/configure.ac
769c0b
+++ b/configure.ac
769c0b
@@ -548,6 +548,11 @@ if test "x$enable_libmtp" != "xno" -a "x$msg_gudev" = "xyes"; then
769c0b
         AC_DEFINE(HAVE_LIBMTP_1_1_5, 1, [Define to 1 if libmtp 1.1.5 is available]),
769c0b
         []
769c0b
     )
769c0b
+
769c0b
+    PKG_CHECK_MODULES(LIBMTP_1_1_6, libmtp >= 1.1.6,
769c0b
+        AC_DEFINE(HAVE_LIBMTP_1_1_6, 1, [Define to 1 if libmtp 1.1.6 is available]),
769c0b
+        []
769c0b
+    )
769c0b
   fi
769c0b
 fi
769c0b
 
769c0b
diff --git a/daemon/gvfsbackendmtp.c b/daemon/gvfsbackendmtp.c
769c0b
index 71fb732..9b58f2b 100644
769c0b
--- a/daemon/gvfsbackendmtp.c
769c0b
+++ b/daemon/gvfsbackendmtp.c
769c0b
@@ -631,6 +631,15 @@ get_device (GVfsBackend *backend, const char *id, GVfsJob *job) {
769c0b
     }
769c0b
   }
769c0b
 
769c0b
+  /* Check supported methods/extensions. */
769c0b
+  LIBMTP_device_extension_t *extension;
769c0b
+  for (extension = device->extensions; extension != NULL; extension = extension->next) {
769c0b
+    if (g_strcmp0 ("android.com", extension->name) == 0) {
769c0b
+      G_VFS_BACKEND_MTP (backend)->android_extension = TRUE;
769c0b
+      break;
769c0b
+    }
769c0b
+  }
769c0b
+
769c0b
  exit:
769c0b
   DEBUG ("(II) get_device done.");
769c0b
   return device;
769c0b
@@ -1455,6 +1464,64 @@ do_set_display_name (GVfsBackend *backend,
769c0b
 }
769c0b
 
769c0b
 
769c0b
+#if HAVE_LIBMTP_1_1_6
769c0b
+static void
769c0b
+do_open_for_read (GVfsBackend *backend,
769c0b
+                  GVfsJobOpenForRead *job,
769c0b
+                  const char *filename)
769c0b
+{
769c0b
+  if (!G_VFS_BACKEND_MTP (backend)->android_extension) {
769c0b
+    g_vfs_job_failed_literal (G_VFS_JOB (job),
769c0b
+                              G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
769c0b
+                              _("Operation not supported."));
769c0b
+    return;
769c0b
+  }
769c0b
+
769c0b
+  DEBUG ("(I) do_open_for_read (%s)", filename);
769c0b
+  g_mutex_lock (&G_VFS_BACKEND_MTP (backend)->mutex);
769c0b
+
769c0b
+  gchar **elements = g_strsplit_set (filename, "/", -1);
769c0b
+  unsigned int ne = g_strv_length (elements);
769c0b
+
769c0b
+  if (ne < 3) {
769c0b
+    g_vfs_job_failed_literal (G_VFS_JOB (job),
769c0b
+                              G_IO_ERROR, G_IO_ERROR_FAILED,
769c0b
+                              _("Cannot open this entity"));
769c0b
+    goto exit;
769c0b
+  }
769c0b
+
769c0b
+  unsigned int id = strtol (elements[ne-1], NULL, 10);
769c0b
+
769c0b
+  LIBMTP_mtpdevice_t *device;
769c0b
+  device = G_VFS_BACKEND_MTP (backend)->device;
769c0b
+
769c0b
+  LIBMTP_file_t *file = LIBMTP_Get_Filemetadata (device, id);
769c0b
+  if (file == NULL) {
769c0b
+    fail_job (G_VFS_JOB (job), device);
769c0b
+    goto exit;
769c0b
+  }
769c0b
+
769c0b
+  RWHandle *handle = g_new0(RWHandle, 1);
769c0b
+  handle->handle_type = HANDLE_FILE;
769c0b
+  handle->id = id;
769c0b
+  handle->offset = 0;
769c0b
+  handle->size = file->filesize;
769c0b
+
769c0b
+  LIBMTP_destroy_file_t (file);
769c0b
+
769c0b
+  g_vfs_job_open_for_read_set_can_seek (G_VFS_JOB_OPEN_FOR_READ (job), TRUE);
769c0b
+  g_vfs_job_open_for_read_set_handle (G_VFS_JOB_OPEN_FOR_READ (job), handle);
769c0b
+  g_vfs_job_succeeded (G_VFS_JOB (job));
769c0b
+
769c0b
+ exit:
769c0b
+  g_strfreev (elements);
769c0b
+  g_mutex_unlock (&G_VFS_BACKEND_MTP (backend)->mutex);
769c0b
+
769c0b
+  DEBUG ("(I) do_open_for_read done.");
769c0b
+}
769c0b
+#endif /* HAVE_LIBMTP_1_1_6 */
769c0b
+
769c0b
+
769c0b
 #if HAVE_LIBMTP_1_1_5
769c0b
 static void
769c0b
 do_open_icon_for_read (GVfsBackend *backend,
769c0b
@@ -1521,7 +1588,7 @@ do_open_icon_for_read (GVfsBackend *backend,
769c0b
 
769c0b
   DEBUG ("(I) do_open_icon_for_read done.");
769c0b
 }
769c0b
-#endif /* HAVE_LIBMTP_GET_THUMBNAIL */
769c0b
+#endif /* HAVE_LIBMTP_1_1_5 */
769c0b
 
769c0b
 
769c0b
 static void
769c0b
@@ -1579,7 +1646,17 @@ do_read (GVfsBackend *backend,
769c0b
 
769c0b
   uint32_t actual;
769c0b
   if (handle->handle_type == HANDLE_FILE) {
769c0b
-    g_assert_not_reached();
769c0b
+    unsigned char *temp;
769c0b
+    int ret = LIBMTP_GetPartialObject (G_VFS_BACKEND_MTP (backend)->device, id, offset,
769c0b
+                                       bytes_requested, &temp, &actual);
769c0b
+    if (ret != 0) {
769c0b
+      fail_job (G_VFS_JOB (job), G_VFS_BACKEND_MTP (backend)->device);
769c0b
+      DEBUG ("(I) job failed.");
769c0b
+      goto exit;
769c0b
+    }
769c0b
+
769c0b
+    memcpy (buffer, temp, actual);
769c0b
+    free (temp);
769c0b
   } else {
769c0b
     GByteArray *bytes = handle->bytes;
769c0b
     actual = MIN (bytes->len - offset, bytes_requested);
769c0b
@@ -1637,6 +1714,9 @@ g_vfs_backend_mtp_class_init (GVfsBackendMtpClass *klass)
769c0b
   backend_class->set_display_name = do_set_display_name;
769c0b
   backend_class->create_dir_monitor = do_create_dir_monitor;
769c0b
   backend_class->create_file_monitor = do_create_file_monitor;
769c0b
+#if HAVE_LIBMTP_1_1_6
769c0b
+  backend_class->open_for_read = do_open_for_read;
769c0b
+#endif
769c0b
 #if HAVE_LIBMTP_1_1_5
769c0b
   backend_class->open_icon_for_read = do_open_icon_for_read;
769c0b
 #endif
769c0b
diff --git a/daemon/gvfsbackendmtp.h b/daemon/gvfsbackendmtp.h
769c0b
index 4137b65..0fe1dec 100644
769c0b
--- a/daemon/gvfsbackendmtp.h
769c0b
+++ b/daemon/gvfsbackendmtp.h
769c0b
@@ -57,6 +57,8 @@ struct _GVfsBackendMtp
769c0b
   GHashTable *monitors;
769c0b
   guint hb_id;
769c0b
   gint unmount_started;
769c0b
+
769c0b
+  gboolean android_extension;
769c0b
 };
769c0b
 
769c0b
 struct _GVfsBackendMtpClass
769c0b
-- 
769c0b
1.7.10.4
769c0b