gvfs r2239 - in trunk: . daemon monitor/gphoto2



Author: davidz
Date: Fri Feb 20 21:27:22 2009
New Revision: 2239
URL: http://svn.gnome.org/viewvc/gvfs?rev=2239&view=rev

Log:
2009-02-20  David Zeuthen  <davidz redhat com>

	Make the gphoto2 backend work with buggy devices (such as the
	iPhone) where the basedir of the store changes.

	* daemon/gvfsbackendgphoto2.c: Revert the patch from #520123 that
	removed the ignore_prefix handling. Change ensure_ignore_prefix()
	to only use an ignore prefix if there is exactly one storage head.

	* monitor/gphoto2/ggphoto2volumemonitor.c: Nuke orphan mount
	handling since that is superseeded by shadow mounts. Also avoid
	appending the store name if there is only one storage head.

	* monitor/gphoto2/ggphoto2volume.[ch]: Rename foreign_mount_root
	to activation_root since that is really what it is now. Also
	fix a silly logical bug whereby music players (as reported by
	HAL) weren't detected.




Modified:
   trunk/ChangeLog
   trunk/daemon/gvfsbackendgphoto2.c
   trunk/monitor/gphoto2/ggphoto2volume.c
   trunk/monitor/gphoto2/ggphoto2volume.h
   trunk/monitor/gphoto2/ggphoto2volumemonitor.c

Modified: trunk/daemon/gvfsbackendgphoto2.c
==============================================================================
--- trunk/daemon/gvfsbackendgphoto2.c	(original)
+++ trunk/daemon/gvfsbackendgphoto2.c	Fri Feb 20 21:27:22 2009
@@ -172,6 +172,9 @@
   GPContext *context;
   Camera *camera;
 
+  /* see comment in ensure_ignore_prefix() */
+  char *ignore_prefix;
+
   /* list of open files */
   int num_open_files_for_reading;
 
@@ -226,7 +229,7 @@
 /* ------------------------------------------------------------------------------------------------- */
 
 typedef struct {
-  /* this is the path of the dir/file */
+  /* this is the path of the dir/file including ignore_prefix */
   char *path;
   GVfsMonitor *vfs_monitor;
 } MonitorProxy;
@@ -348,6 +351,8 @@
   GList *l;
   char *filepath;
 
+  g_return_if_fail (g_str_has_prefix (dir, gphoto2_backend->ignore_prefix));
+
   DEBUG ("monitors_emit_internal() %s for '%s' '%s'", event_name, dir, name);
 
   for (l = gphoto2_backend->dir_monitor_proxies; l != NULL; l = l->next)
@@ -356,7 +361,7 @@
       if (strcmp (proxy->path, dir) == 0)
         {
           char *path;
-          path = g_build_filename (dir, name, NULL);
+          path = g_build_filename (dir + strlen (gphoto2_backend->ignore_prefix), name, NULL);
           g_vfs_monitor_emit_event (proxy->vfs_monitor, event, path, NULL);
           DEBUG ("  emitted %s for '%s' on dir monitor for '%s'", event_name, path, dir);
           g_free (path);
@@ -369,8 +374,9 @@
       MonitorProxy *proxy = l->data;
       if (strcmp (proxy->path, filepath) == 0)
         {
-          g_vfs_monitor_emit_event (proxy->vfs_monitor, event, filepath, NULL);
-          DEBUG ("  emitted %s for '%s' on file monitor", event_name, filepath);
+          const char *path = filepath + strlen (gphoto2_backend->ignore_prefix);
+          g_vfs_monitor_emit_event (proxy->vfs_monitor, event, path, NULL);
+          DEBUG ("  emitted %s for '%s' on file monitor", event_name, path);
         }
     }
   g_free (filepath);
@@ -555,6 +561,9 @@
   g_free (gphoto2_backend->hal_icon_name);
   gphoto2_backend->hal_icon_name = NULL;
 
+  g_free (gphoto2_backend->ignore_prefix);
+  gphoto2_backend->ignore_prefix = NULL;
+
   if (gphoto2_backend->info_cache != NULL)
     {
       g_hash_table_unref (gphoto2_backend->info_cache);
@@ -903,15 +912,15 @@
 /* ------------------------------------------------------------------------------------------------- */
 
 static void
-split_filename (GVfsBackendGphoto2 *gphoto2_backend, const char *filename, char **dir, char **name)
+split_filename_with_ignore_prefix (GVfsBackendGphoto2 *gphoto2_backend, const char *filename, char **dir, char **name)
 {
   char *s;
 
   s = g_path_get_dirname (filename);
   if (s[0] == '/')
-    *dir = g_strconcat ("/", s + 1, NULL);
+    *dir = g_strconcat (gphoto2_backend->ignore_prefix, s + 1, NULL);
   else
-    *dir = g_strconcat ("/", s, NULL);
+    *dir = g_strconcat (gphoto2_backend->ignore_prefix, s, NULL);
   g_free (s);
 
   if (strcmp (filename, "/") == 0)
@@ -923,11 +932,28 @@
   if (s[strlen(s)] == '/')
     s[strlen(s)] = '\0';
 
-  /*DEBUG ("split_filename: '%s' -> '%s' '%s'", filename, *dir, *name);*/
+  /*DEBUG ("split_filename_with_ignore_prefix: '%s' -> '%s' '%s'", filename, *dir, *name);*/
 }
 
 /* ------------------------------------------------------------------------------------------------- */
 
+static char *
+add_ignore_prefix (GVfsBackendGphoto2 *gphoto2_backend, const char *filename)
+{
+  char *result;
+
+  if (filename[0] == '/')
+    result = g_strconcat (gphoto2_backend->ignore_prefix, filename + 1, NULL);
+  else
+    result = g_strconcat (gphoto2_backend->ignore_prefix, filename, NULL);
+
+  /*DEBUG ("add_ignore_prefix: '%s' -> '%s'", filename, result);*/
+  return result;
+}
+
+/* ------------------------------------------------------------------------------------------------- */
+
+/* the passed 'dir' variable must contain ignore_prefix */
 static gboolean
 file_get_info (GVfsBackendGphoto2 *gphoto2_backend, 
                const char *dir, 
@@ -951,7 +977,7 @@
   full_path = g_build_filename (dir, name, NULL);
   DEBUG ("file_get_info() try_cache_only=%d dir='%s', name='%s'\n"
          "                full_path='%s'", 
-         try_cache_only, dir, name, full_path);
+         try_cache_only, dir, name, full_path, gphoto2_backend->ignore_prefix);
 
 
   /* first look up cache */
@@ -978,7 +1004,7 @@
   g_file_info_unset_attribute_mask (info);
 
   /* handle root directory */
-  if (strcmp (full_path, "/") == 0)
+  if (strcmp (full_path, gphoto2_backend->ignore_prefix) == 0 || strcmp (full_path, "/") == 0)
     {
       char *display_name;
       display_name = compute_display_name (gphoto2_backend);
@@ -1110,7 +1136,7 @@
       GMountSpec *mount_spec;
 
       mount_spec = g_vfs_backend_get_mount_spec (G_VFS_BACKEND (gphoto2_backend));
-      icon_id = g_strdup_printf ("preview:%s/%s", dir, name);
+      icon_id = g_strdup_printf ("preview:%s/%s", dir + strlen (gphoto2_backend->ignore_prefix), name);
       icon = g_vfs_icon_new (mount_spec,
                              icon_id);
       g_file_info_set_attribute_object (info,
@@ -1268,6 +1294,54 @@
 
 /* ------------------------------------------------------------------------------------------------- */
 
+/* If we only have a single storage head, the gphoto2 volume monitor
+ * will not use activation roots into our mount. This is mainly to
+ * work around buggy devices where the basedir of the storage head
+ * changes on every camera initialization, e.g. the iPhone.
+ *
+ * So, if we have only one storage head, do use basedir of that
+ * head as ignore_prefix.
+ *
+ * See also update_cameras() in ggphoto2volumemonitor.c.
+ *
+ * This function needs to be called from do_mount().
+ */
+static gboolean
+ensure_ignore_prefix (GVfsBackendGphoto2 *gphoto2_backend, GVfsJob *job)
+{
+  gchar *prefix;
+  CameraStorageInformation *storage_info;
+  int num_storage_info;
+
+  /* already set */
+  if (gphoto2_backend->ignore_prefix != NULL)
+    return TRUE;
+
+  prefix = NULL;
+
+  if (gp_camera_get_storageinfo (gphoto2_backend->camera,
+                                 &storage_info,
+                                 &num_storage_info,
+                                 gphoto2_backend->context) != 0)
+    goto out;
+
+  if (num_storage_info > 1)
+    goto out;
+
+  prefix = g_strdup_printf ("%s/", storage_info[0].basedir);
+
+ out:
+
+  if (prefix == NULL)
+    gphoto2_backend->ignore_prefix = g_strdup ("/");
+  else
+    gphoto2_backend->ignore_prefix = prefix;
+
+  return TRUE;
+}
+
+/* ------------------------------------------------------------------------------------------------- */
+
 static void
 do_mount (GVfsBackend *backend,
 	  GVfsJobMount *job,
@@ -1443,6 +1517,12 @@
       return;
     }
 
+  if (!ensure_ignore_prefix (gphoto2_backend, G_VFS_JOB (job)))
+    {
+      release_device (gphoto2_backend);
+      return;
+    }
+
   /* Translator: %s represents the device, e.g. usb:001,042  */
   fuse_name = g_strdup_printf (_("gphoto2 mount on %s"), gphoto2_backend->gphoto2_port);
   icon_name = compute_icon_name (gphoto2_backend);
@@ -1589,7 +1669,7 @@
 
   ensure_not_dirty (gphoto2_backend);
 
-  split_filename (gphoto2_backend, filename, &dir, &name);
+  split_filename_with_ignore_prefix (gphoto2_backend, filename, &dir, &name);
 
   if (is_directory (gphoto2_backend, dir, name))
     {
@@ -1819,7 +1899,7 @@
 
   DEBUG ("query_info (%s)", filename);
 
-  split_filename (gphoto2_backend, filename, &dir, &name);
+  split_filename_with_ignore_prefix (gphoto2_backend, filename, &dir, &name);
 
   error = NULL;
   if (!file_get_info (gphoto2_backend, dir, name, info, &error, FALSE))
@@ -1855,7 +1935,7 @@
 
   ret = FALSE;
 
-  split_filename (gphoto2_backend, filename, &dir, &name);
+  split_filename_with_ignore_prefix (gphoto2_backend, filename, &dir, &name);
 
   if (!file_get_info (gphoto2_backend, dir, name, info, NULL, TRUE))
     {
@@ -1889,6 +1969,7 @@
   CameraList *list;
   int n;
   int rc;
+  char *filename;
   gboolean using_cached_dir_list;
   gboolean using_cached_file_list;
   char *as_dir;
@@ -1898,9 +1979,10 @@
   using_cached_dir_list = FALSE;
   using_cached_file_list = FALSE;
 
+  filename = add_ignore_prefix (gphoto2_backend, given_filename);
   DEBUG ("enumerate (%s)", given_filename);
 
-  split_filename (gphoto2_backend, given_filename, &as_dir, &as_name);
+  split_filename_with_ignore_prefix (gphoto2_backend, given_filename, &as_dir, &as_name);
   if (!is_directory (gphoto2_backend, as_dir, as_name))
     {
       if (is_regular (gphoto2_backend, as_dir, as_name))
@@ -1924,18 +2006,18 @@
 
   /* first, list the folders */
   g_mutex_lock (gphoto2_backend->lock);
-  list = g_hash_table_lookup (gphoto2_backend->dir_name_cache, given_filename);
+  list = g_hash_table_lookup (gphoto2_backend->dir_name_cache, filename);
   if (list == NULL)
     {
       g_mutex_unlock (gphoto2_backend->lock);
 
       ensure_not_dirty (gphoto2_backend);
 
-      DEBUG ("  Generating dir list for dir '%s'", given_filename);
+      DEBUG ("  Generating dir list for dir '%s'", filename);
 
       gp_list_new (&list);
       rc = gp_camera_folder_list_folders (gphoto2_backend->camera, 
-                                          given_filename, 
+                                          filename, 
                                           list, 
                                           gphoto2_backend->context);
       if (rc != 0)
@@ -1943,12 +2025,13 @@
           error = get_error_from_gphoto2 (_("Failed to get folder list"), rc);
           g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
           g_error_free (error);
+          g_free (filename);
           return;
         }  
     }
   else
     {
-      DEBUG ("  Using cached dir list for dir '%s'", given_filename);
+      DEBUG ("  Using cached dir list for dir '%s'", filename);
       using_cached_dir_list = TRUE;
       gp_list_ref (list);
       g_mutex_unlock (gphoto2_backend->lock);
@@ -1961,7 +2044,7 @@
       DEBUG ("  enum folder '%s'", name);
       info = g_file_info_new ();
       error = NULL;
-      if (!file_get_info (gphoto2_backend, given_filename, name, info, &error, FALSE))
+      if (!file_get_info (gphoto2_backend, filename, name, info, &error, FALSE))
         {
           g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
           g_error_free (error);
@@ -1976,7 +2059,7 @@
     {
 #ifndef DEBUG_NO_CACHING
       g_mutex_lock (gphoto2_backend->lock);
-      g_hash_table_insert (gphoto2_backend->dir_name_cache, g_strdup (given_filename), list);
+      g_hash_table_insert (gphoto2_backend->dir_name_cache, g_strdup (filename), list);
       g_mutex_unlock (gphoto2_backend->lock);
 #endif
     }
@@ -1990,17 +2073,17 @@
 
   /* then list the files in each folder */
   g_mutex_lock (gphoto2_backend->lock);
-  list = g_hash_table_lookup (gphoto2_backend->file_name_cache, given_filename);
+  list = g_hash_table_lookup (gphoto2_backend->file_name_cache, filename);
   if (list == NULL)
     {
       g_mutex_unlock (gphoto2_backend->lock);
       ensure_not_dirty (gphoto2_backend);
 
-      DEBUG ("  Generating file list for dir '%s'", given_filename);
+      DEBUG ("  Generating file list for dir '%s'", filename);
 
       gp_list_new (&list);
       rc = gp_camera_folder_list_files (gphoto2_backend->camera, 
-                                        given_filename,
+                                        filename, 
                                         list, 
                                         gphoto2_backend->context);
       if (rc != 0)
@@ -2008,12 +2091,13 @@
           error = get_error_from_gphoto2 (_("Failed to get file list"), rc);
           g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
           g_error_free (error);
+          g_free (filename);
           return;
         }
     }
   else
     {
-      DEBUG ("  Using cached file list for dir '%s'", given_filename);
+      DEBUG ("  Using cached file list for dir '%s'", filename);
       using_cached_file_list = TRUE;
       gp_list_ref (list);
       g_mutex_unlock (gphoto2_backend->lock);
@@ -2027,7 +2111,7 @@
 
       info = g_file_info_new ();
       error = NULL;
-      if (!file_get_info (gphoto2_backend, given_filename, name, info, &error, FALSE))
+      if (!file_get_info (gphoto2_backend, filename, name, info, &error, FALSE))
         {
           g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
           g_error_free (error);
@@ -2042,7 +2126,7 @@
     {
 #ifndef DEBUG_NO_CACHING
       g_mutex_lock (gphoto2_backend->lock);
-      g_hash_table_insert (gphoto2_backend->file_name_cache, g_strdup (given_filename), list);
+      g_hash_table_insert (gphoto2_backend->file_name_cache, g_strdup (filename), list);
       g_mutex_unlock (gphoto2_backend->lock);
 #endif
     }
@@ -2060,6 +2144,8 @@
   g_list_foreach (l, (GFunc) g_object_unref, NULL);
   g_list_free (l);
   g_vfs_job_enumerate_done (job);
+
+  g_free (filename);
 }
 
 /* ------------------------------------------------------------------------------------------------- */
@@ -2077,15 +2163,17 @@
   GError *error;
   CameraList *list;
   int n;
+  char *filename;
   const char *name;
 
   l = NULL;
 
+  filename = add_ignore_prefix (gphoto2_backend, given_filename);
   DEBUG ("try_enumerate (%s)", given_filename);
 
   /* first, list the folders */
   g_mutex_lock (gphoto2_backend->lock);
-  list = g_hash_table_lookup (gphoto2_backend->dir_name_cache, given_filename);
+  list = g_hash_table_lookup (gphoto2_backend->dir_name_cache, filename);
   if (list == NULL)
     {
       g_mutex_unlock (gphoto2_backend->lock);
@@ -2098,7 +2186,7 @@
       gp_list_get_name (list, n, &name);
       DEBUG ("  try_enum folder '%s'", name);
       info = g_file_info_new ();
-      if (!file_get_info (gphoto2_backend, given_filename, name, info, &error, TRUE))
+      if (!file_get_info (gphoto2_backend, filename, name, info, &error, TRUE))
         {
           g_mutex_lock (gphoto2_backend->lock);
           gp_list_unref (list);
@@ -2113,7 +2201,7 @@
 
   /* then list the files in each folder */
   g_mutex_lock (gphoto2_backend->lock);
-  list = g_hash_table_lookup (gphoto2_backend->file_name_cache, given_filename);
+  list = g_hash_table_lookup (gphoto2_backend->file_name_cache, filename);
   if (list == NULL)
     {
       g_mutex_unlock (gphoto2_backend->lock);
@@ -2127,7 +2215,7 @@
       DEBUG ("  try_enum file '%s'", name);
 
       info = g_file_info_new ();
-      if (!file_get_info (gphoto2_backend, given_filename, name, info, &error, TRUE))
+      if (!file_get_info (gphoto2_backend, filename, name, info, &error, TRUE))
         {
           g_mutex_lock (gphoto2_backend->lock);
           gp_list_unref (list);
@@ -2148,6 +2236,7 @@
   g_list_free (l);
   g_vfs_job_enumerate_done (job);
 
+  g_free (filename);
   DEBUG ("  YAY got info from cache for try_enumerate (%s)", given_filename);
   return TRUE;
 
@@ -2155,6 +2244,7 @@
   g_list_foreach (l, (GFunc) g_object_unref, NULL);
   g_list_free (l);
 
+  g_free (filename);
   DEBUG ("  BUU no info from cache for try_enumerate (%s)", given_filename);
   return FALSE;
 }
@@ -2282,7 +2372,7 @@
       goto out;
     }
 
-  split_filename (gphoto2_backend, filename, &dir, &name);
+  split_filename_with_ignore_prefix (gphoto2_backend, filename, &dir, &name);
 
   rc = gp_camera_folder_make_dir (gphoto2_backend->camera,
                                   dir,
@@ -2491,7 +2581,7 @@
       goto out;
     }
 
-  split_filename (gphoto2_backend, filename, &dir, &name);
+  split_filename_with_ignore_prefix (gphoto2_backend, filename, &dir, &name);
 
   /* refuse is desired name is already taken */
   if (is_directory (gphoto2_backend, dir, display_name) ||
@@ -2546,7 +2636,7 @@
   monitors_emit_deleted (gphoto2_backend, dir, name);
   monitors_emit_created (gphoto2_backend, dir, display_name);
 
-  new_name = g_build_filename (dir, display_name, NULL);
+  new_name = g_build_filename (dir + strlen (gphoto2_backend->ignore_prefix), display_name, NULL);
   g_vfs_job_set_display_name_set_new_path (job, new_name);
 
   g_vfs_job_succeeded (G_VFS_JOB (job));
@@ -2588,11 +2678,12 @@
       goto out;
     }
 
-  split_filename (gphoto2_backend, filename, &dir, &name);
+  split_filename_with_ignore_prefix (gphoto2_backend, filename, &dir, &name);
 
   if (is_directory (gphoto2_backend, dir, name))
     {
-      if (!is_directory_empty (gphoto2_backend, filename))
+      dir_name = add_ignore_prefix (gphoto2_backend, filename);
+      if (!is_directory_empty (gphoto2_backend, dir_name))
         {
           g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR,
                             G_IO_ERROR_NOT_EMPTY,
@@ -2680,7 +2771,7 @@
       goto out;
     }
 
-  split_filename (gphoto2_backend, filename, &dir, &name);
+  split_filename_with_ignore_prefix (gphoto2_backend, filename, &dir, &name);
 
   if (is_directory (gphoto2_backend, dir, name))
     {
@@ -2838,7 +2929,7 @@
 
   dir = NULL;
   name = NULL;
-  split_filename (gphoto2_backend, filename, &dir, &name);
+  split_filename_with_ignore_prefix (gphoto2_backend, filename, &dir, &name);
   
   /* write a new file
    * - will delete the existing one when done in do_close_write() 
@@ -2865,7 +2956,7 @@
 
   dir = NULL;
   name = NULL;
-  split_filename (gphoto2_backend, filename, &dir, &name);
+  split_filename_with_ignore_prefix (gphoto2_backend, filename, &dir, &name);
   
   /* write a new file
    * - will read existing data in do_create_internal
@@ -3085,8 +3176,8 @@
 
   ensure_not_dirty (gphoto2_backend);
 
-  split_filename (gphoto2_backend, source, &src_dir, &src_name);
-  split_filename (gphoto2_backend, destination, &dst_dir, &dst_name);
+  split_filename_with_ignore_prefix (gphoto2_backend, source, &src_dir, &src_name);
+  split_filename_with_ignore_prefix (gphoto2_backend, destination, &dst_dir, &dst_name);
 
   /* this is an limited implementation that can only move files / folders in the same directory */
   if (strcmp (src_dir, dst_dir) != 0)
@@ -3220,10 +3311,10 @@
 
   DEBUG ("create_dir_monitor (%s)", filename);
 
-  split_filename (gphoto2_backend, filename, &dir, &name);
+  split_filename_with_ignore_prefix (gphoto2_backend, filename, &dir, &name);
 
   proxy = g_new0 (MonitorProxy, 1);
-  proxy->path = g_strdup (filename);
+  proxy->path = add_ignore_prefix (gphoto2_backend, filename);
   proxy->vfs_monitor = g_vfs_monitor_new (backend);
 
   gphoto2_backend->dir_monitor_proxies = g_list_prepend (gphoto2_backend->dir_monitor_proxies, proxy);
@@ -3270,10 +3361,10 @@
 
   DEBUG ("create_file_monitor (%s)", filename);
 
-  split_filename (gphoto2_backend, filename, &dir, &name);
+  split_filename_with_ignore_prefix (gphoto2_backend, filename, &dir, &name);
 
   proxy = g_new0 (MonitorProxy, 1);
-  proxy->path = g_strdup (filename);
+  proxy->path = add_ignore_prefix (gphoto2_backend, filename);
   proxy->vfs_monitor = g_vfs_monitor_new (backend);
 
   gphoto2_backend->file_monitor_proxies = g_list_prepend (gphoto2_backend->file_monitor_proxies, proxy);

Modified: trunk/monitor/gphoto2/ggphoto2volume.c
==============================================================================
--- trunk/monitor/gphoto2/ggphoto2volume.c	(original)
+++ trunk/monitor/gphoto2/ggphoto2volume.c	Fri Feb 20 21:27:22 2009
@@ -47,8 +47,7 @@
   HalDevice *device;
   HalDevice *drive_device;
 
-  GFile *foreign_mount_root;
-  GMount *foreign_mount;
+  GFile *activation_root;
 
   char *name;
   char *icon;
@@ -70,11 +69,8 @@
   if (volume->device != NULL)
     g_object_unref (volume->device);
 
-  if (volume->foreign_mount_root != NULL)
-    g_object_unref (volume->foreign_mount_root);
-
-  if (volume->foreign_mount != NULL)
-    g_object_unref (volume->foreign_mount);
+  if (volume->activation_root != NULL)
+    g_object_unref (volume->activation_root);
 
   if (volume->volume_monitor != NULL)
     g_object_remove_weak_pointer (G_OBJECT (volume->volume_monitor), (gpointer) &(volume->volume_monitor));
@@ -248,7 +244,7 @@
 g_gphoto2_volume_new (GVolumeMonitor   *volume_monitor,
                       HalDevice        *device,
                       HalPool          *pool,
-                      GFile            *foreign_mount_root)
+                      GFile            *activation_root)
 {
   GGPhoto2Volume *volume;
   HalDevice *drive_device;
@@ -258,11 +254,11 @@
   g_return_val_if_fail (volume_monitor != NULL, NULL);
   g_return_val_if_fail (device != NULL, NULL);
   g_return_val_if_fail (pool != NULL, NULL);
-  g_return_val_if_fail (foreign_mount_root != NULL, NULL);
+  g_return_val_if_fail (activation_root != NULL, NULL);
 
-  if (!hal_device_has_capability (device, "camera") ||
-      (hal_device_has_capability (device, "portable_audio_player") &&
-       hal_device_get_property_bool (device, "camera.libgphoto2.support")))
+  if (!(hal_device_has_capability (device, "camera") ||
+        (hal_device_has_capability (device, "portable_audio_player") &&
+         hal_device_get_property_bool (device, "camera.libgphoto2.support"))))
     return NULL;
 
   /* OK, so we abuse storage_udi and drive_device for the USB main
@@ -287,7 +283,7 @@
   volume->device_path = g_strdup (device_path);
   volume->device = g_object_ref (device);
   volume->drive_device = g_object_ref (drive_device);
-  volume->foreign_mount_root = foreign_mount_root != NULL ? g_object_ref (foreign_mount_root) : NULL;
+  volume->activation_root = g_object_ref (activation_root);
 
   g_signal_connect_object (device, "hal_property_changed", (GCallback) hal_changed, volume, 0);
   g_signal_connect_object (drive_device, "hal_property_changed", (GCallback) hal_changed, volume, 0);
@@ -361,16 +357,7 @@
 static GMount *
 g_gphoto2_volume_get_mount (GVolume *volume)
 {
-  GGPhoto2Volume *gphoto2_volume = G_GPHOTO2_VOLUME (volume);
-  GMount *mount;
-
-  G_LOCK (gphoto2_volume);
-  mount = NULL;
-  if (gphoto2_volume->foreign_mount != NULL)
-    mount = g_object_ref (gphoto2_volume->foreign_mount);
-  G_UNLOCK (gphoto2_volume);
-
-  return mount;
+  return NULL;
 }
 
 gboolean
@@ -388,101 +375,51 @@
   return res;
 }
 
-static void
-foreign_mount_unmounted (GMount *mount, gpointer user_data)
-{
-  GGPhoto2Volume *volume = G_GPHOTO2_VOLUME (user_data);
-  gboolean check;
-
-  G_LOCK (gphoto2_volume);
-  check = volume->foreign_mount == mount;
-  G_UNLOCK (gphoto2_volume);
-  if (check)
-    g_gphoto2_volume_adopt_foreign_mount (volume, NULL);
-}
-
-void
-g_gphoto2_volume_adopt_foreign_mount (GGPhoto2Volume *volume, GMount *foreign_mount)
-{
-  G_LOCK (gphoto2_volume);
-  if (volume->foreign_mount != NULL)
-    g_object_unref (volume->foreign_mount);
-
-  if (foreign_mount != NULL)
-    {
-      volume->foreign_mount =  g_object_ref (foreign_mount);
-      g_signal_connect_object (foreign_mount, "unmounted", (GCallback) foreign_mount_unmounted, volume, 0);
-    }
-  else
-    volume->foreign_mount =  NULL;
-
-  g_idle_add (changed_in_idle, g_object_ref (volume));
-  G_UNLOCK (gphoto2_volume);
-}
-
-gboolean
-g_gphoto2_volume_has_foreign_mount_root (GGPhoto2Volume       *volume,
-                                     GFile            *mount_root)
-{
-  GGPhoto2Volume *gphoto2_volume = G_GPHOTO2_VOLUME (volume);
-  gboolean res;
-
-  G_LOCK (gphoto2_volume);
-  res = FALSE;
-  if (gphoto2_volume->foreign_mount_root != NULL)
-    res = g_file_equal (gphoto2_volume->foreign_mount_root, mount_root);
-  G_UNLOCK (gphoto2_volume);
-
-  return res;
-}
-
-
-
 typedef struct
 {
   GGPhoto2Volume *enclosing_volume;
   GAsyncReadyCallback  callback;
   gpointer user_data;
-} ForeignMountOp;
+} ActivationMountOp;
 
 static void
-mount_foreign_callback (GObject *source_object,
+mount_callback (GObject *source_object,
                         GAsyncResult *res,
                         gpointer user_data)
 {
-  ForeignMountOp *data = user_data;
+  ActivationMountOp *data = user_data;
   data->callback (G_OBJECT (data->enclosing_volume), res, data->user_data);
   g_free (data);
 }
 
 static void
 g_gphoto2_volume_mount (GVolume             *volume,
-                    GMountMountFlags     flags,
-                    GMountOperation     *mount_operation,
-                    GCancellable        *cancellable,
-                    GAsyncReadyCallback  callback,
-                    gpointer             user_data)
+                        GMountMountFlags     flags,
+                        GMountOperation     *mount_operation,
+                        GCancellable        *cancellable,
+                        GAsyncReadyCallback  callback,
+                        gpointer             user_data)
 {
   GGPhoto2Volume *gphoto2_volume = G_GPHOTO2_VOLUME (volume);
-  ForeignMountOp *data;
+  ActivationMountOp *data;
 
   /*g_warning ("gphoto2_volume_mount (can_mount=%d foreign=%p device_path=%s)",
               g_gphoto2_volume_can_mount (volume),
-              gphoto2_volume->foreign_mount_root,
+              gphoto2_volume->activation_root,
               gphoto2_volume->device_path);*/
 
   G_LOCK (gphoto2_volume);
 
-  data = g_new0 (ForeignMountOp, 1);
+  data = g_new0 (ActivationMountOp, 1);
   data->enclosing_volume = gphoto2_volume;
   data->callback = callback;
   data->user_data = user_data;
 
-  g_file_mount_enclosing_volume (gphoto2_volume->foreign_mount_root,
+  g_file_mount_enclosing_volume (gphoto2_volume->activation_root,
                                  0,
                                  mount_operation,
                                  cancellable,
-                                 mount_foreign_callback,
+                                 mount_callback,
                                  data);
 
   G_UNLOCK (gphoto2_volume);
@@ -497,7 +434,7 @@
   gboolean res;
 
   G_LOCK (gphoto2_volume);
-  res = g_file_mount_enclosing_volume_finish (gphoto2_volume->foreign_mount_root, result, error);
+  res = g_file_mount_enclosing_volume_finish (gphoto2_volume->activation_root, result, error);
   G_UNLOCK (gphoto2_volume);
 
   return res;
@@ -551,7 +488,7 @@
 {
   GGPhoto2Volume *gphoto2_volume = G_GPHOTO2_VOLUME (volume);
 
-  return g_object_ref (gphoto2_volume->foreign_mount_root);
+  return g_object_ref (gphoto2_volume->activation_root);
 }
 
 static void

Modified: trunk/monitor/gphoto2/ggphoto2volume.h
==============================================================================
--- trunk/monitor/gphoto2/ggphoto2volume.h	(original)
+++ trunk/monitor/gphoto2/ggphoto2volume.h	Fri Feb 20 21:27:22 2009
@@ -48,17 +48,11 @@
 GGPhoto2Volume *g_gphoto2_volume_new            (GVolumeMonitor   *volume_monitor,
                                                  HalDevice        *device,
                                                  HalPool          *pool,
-                                                 GFile            *foreign_mount_root);
+                                                 GFile            *activation_root);
 
 gboolean    g_gphoto2_volume_has_udi        (GGPhoto2Volume       *volume,
                                              const char       *udi);
 
-gboolean    g_gphoto2_volume_has_foreign_mount_root (GGPhoto2Volume       *volume,
-                                                     GFile            *mount_root);
-
-void        g_gphoto2_volume_adopt_foreign_mount (GGPhoto2Volume *volume,
-                                                  GMount *foreign_mount);
-
 void        g_gphoto2_volume_removed        (GGPhoto2Volume       *volume);
 
 G_END_DECLS

Modified: trunk/monitor/gphoto2/ggphoto2volumemonitor.c
==============================================================================
--- trunk/monitor/gphoto2/ggphoto2volumemonitor.c	(original)
+++ trunk/monitor/gphoto2/ggphoto2volumemonitor.c	Fri Feb 20 21:27:22 2009
@@ -234,48 +234,6 @@
   return get_hal_pool() != NULL;
 }
 
-static GVolume *
-adopt_orphan_mount (GMount *mount, GVolumeMonitor *monitor)
-{
-  GList *l;
-  GFile *mount_root;
-  GVolume *ret;
-
-  /* This is called by the union volume monitor which does
-     have a ref to this. So its guaranteed to live, unfortunately
-     the pointer is not passed as an argument :/
-  */
-  ret = NULL;
-
-  G_LOCK (hal_vm);
-  if (the_volume_monitor == NULL)
-    {
-      G_UNLOCK (hal_vm);
-      return NULL;
-    }
-
-  mount_root = g_mount_get_root (mount);
-
-  /* gphoto2:// are foreign mounts */
-  for (l = the_volume_monitor->camera_volumes; l != NULL; l = l->next)
-    {
-      GGPhoto2Volume *volume = l->data;
-
-      if (g_gphoto2_volume_has_foreign_mount_root (volume, mount_root))
-        {
-          g_gphoto2_volume_adopt_foreign_mount (volume, mount);
-          ret = g_object_ref (volume);
-          goto found;
-        }
-    }
-
- found:
-  g_object_unref (mount_root);
-
-  G_UNLOCK (hal_vm);
-  return ret;
-}
-
 static void
 g_gphoto2_volume_monitor_class_init (GGPhoto2VolumeMonitorClass *klass)
 {
@@ -291,7 +249,6 @@
   monitor_class->get_connected_drives = get_connected_drives;
   monitor_class->get_volume_for_uuid = get_volume_for_uuid;
   monitor_class->get_mount_for_uuid = get_mount_for_uuid;
-  monitor_class->adopt_orphan_mount = adopt_orphan_mount;
   monitor_class->is_supported = is_supported;
 }
 
@@ -575,11 +532,11 @@
   for (l = added; l != NULL; l = l->next)
     {
       HalDevice *d = l->data;
-      GFile *foreign_mount_root;
       int usb_bus_num;
       int usb_device_num;
       gboolean found;
       GList *store_heads, *l;
+      guint num_store_heads;
 
       /* Look for the device in the added volumes, so as
        * not to add devices that are both audio players, and cameras */
@@ -600,32 +557,44 @@
       usb_device_num = hal_device_get_property_int (d, "usb.linux.device_number");
 
       store_heads = get_stores_for_camera (usb_bus_num, usb_device_num);
+      num_store_heads = g_list_length (store_heads);
       for (l = store_heads ; l != NULL; l = l->next)
         {
           char *store_path = (char *) l->data;
-          char *uri;
-
-	  uri = g_strdup_printf ("gphoto2://[usb:%03d,%03d]/%s", usb_bus_num, usb_device_num,
-	  			 store_path[0] == '/' ? store_path + 1 : store_path);
+          GFile *activation_mount_root;
+          gchar *uri;
 
-	  foreign_mount_root = g_file_new_for_uri (uri);
-	  g_free (uri);
-
-	  udi = hal_device_get_udi (d);
-	  volume = g_gphoto2_volume_new (G_VOLUME_MONITOR (monitor),
-					 d,
-					 monitor->pool,
-					 foreign_mount_root);
-	  g_object_unref (foreign_mount_root);
-	  if (volume != NULL)
+          /* If we only have a single store, don't use the store name at all. The backend automatically
+           * prepend the storename; this is to work around bugs with devices (like the iPhone) for which
+           * the store name changes every time the camera is initialized (e.g. mounted).
+           */
+          if (num_store_heads == 1)
+            {
+              uri = g_strdup_printf ("gphoto2://[usb:%03d,%03d]", usb_bus_num, usb_device_num);
+            }
+          else
             {
-	      monitor->camera_volumes = g_list_prepend (monitor->camera_volumes, volume);
-	      *added_volumes = g_list_prepend (*added_volumes, g_object_ref (volume));
-	    }
+              uri = g_strdup_printf ("gphoto2://[usb:%03d,%03d]/%s", usb_bus_num, usb_device_num,
+                                     store_path[0] == '/' ? store_path + 1 : store_path);
+            }
+          activation_mount_root = g_file_new_for_uri (uri);
+          g_free (uri);
 
-	  g_free (l->data);
+          udi = hal_device_get_udi (d);
+          volume = g_gphoto2_volume_new (G_VOLUME_MONITOR (monitor),
+                                         d,
+                                         monitor->pool,
+                                         activation_mount_root);
+          if (volume != NULL)
+            {
+              monitor->camera_volumes = g_list_prepend (monitor->camera_volumes, volume);
+              *added_volumes = g_list_prepend (*added_volumes, g_object_ref (volume));
+            }
 
+          if (activation_mount_root != NULL)
+            g_object_unref (activation_mount_root);
         }
+      g_list_foreach (store_heads, (GFunc) g_free, NULL);
       g_list_free (store_heads);
     }
 



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