diff options
author | David Zeuthen <davidz@redhat.com> | 2009-02-20 21:27:22 +0000 |
---|---|---|
committer | David Zeuthen <davidz@src.gnome.org> | 2009-02-20 21:27:22 +0000 |
commit | 61b5f9a39c236d96ffc01716d95e165de4af4deb (patch) | |
tree | 0e7f397a5a6cf0e0bd2cb9cebfa41231154bdeb4 /monitor/gphoto2 | |
parent | 530167e203f195a64c9420ffe90f1d28528b7000 (diff) | |
download | gvfs-61b5f9a39c236d96ffc01716d95e165de4af4deb.tar.gz |
Make the gphoto2 backend work with buggy devices (such as the iPhone)
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.
svn path=/trunk/; revision=2239
Diffstat (limited to 'monitor/gphoto2')
-rw-r--r-- | monitor/gphoto2/ggphoto2volume.c | 113 | ||||
-rw-r--r-- | monitor/gphoto2/ggphoto2volume.h | 8 | ||||
-rw-r--r-- | monitor/gphoto2/ggphoto2volumemonitor.c | 97 |
3 files changed, 59 insertions, 159 deletions
diff --git a/monitor/gphoto2/ggphoto2volume.c b/monitor/gphoto2/ggphoto2volume.c index 8cdf8257..1ddbee1f 100644 --- a/monitor/gphoto2/ggphoto2volume.c +++ b/monitor/gphoto2/ggphoto2volume.c @@ -47,8 +47,7 @@ struct _GGPhoto2Volume { HalDevice *device; HalDevice *drive_device; - GFile *foreign_mount_root; - GMount *foreign_mount; + GFile *activation_root; char *name; char *icon; @@ -70,11 +69,8 @@ g_gphoto2_volume_finalize (GObject *object) 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 @@ GGPhoto2Volume * 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_gphoto2_volume_new (GVolumeMonitor *volume_monitor, 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 @@ g_gphoto2_volume_new (GVolumeMonitor *volume_monitor, 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 @@ g_gphoto2_volume_get_drive (GVolume *volume) 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 @@ g_gphoto2_volume_has_udi (GGPhoto2Volume *volume, 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 @@ g_gphoto2_volume_mount_finish (GVolume *volume, 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 @@ g_gphoto2_volume_get_activation_root (GVolume *volume) { 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 diff --git a/monitor/gphoto2/ggphoto2volume.h b/monitor/gphoto2/ggphoto2volume.h index 20fe486a..a7a4131e 100644 --- a/monitor/gphoto2/ggphoto2volume.h +++ b/monitor/gphoto2/ggphoto2volume.h @@ -48,17 +48,11 @@ GType g_gphoto2_volume_get_type (void) G_GNUC_CONST; 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 diff --git a/monitor/gphoto2/ggphoto2volumemonitor.c b/monitor/gphoto2/ggphoto2volumemonitor.c index ce29757c..ed3fab62 100644 --- a/monitor/gphoto2/ggphoto2volumemonitor.c +++ b/monitor/gphoto2/ggphoto2volumemonitor.c @@ -234,48 +234,6 @@ is_supported (void) 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 @@ g_gphoto2_volume_monitor_class_init (GGPhoto2VolumeMonitorClass *klass) 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 @@ update_cameras (GGPhoto2VolumeMonitor *monitor, 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 @@ update_cameras (GGPhoto2VolumeMonitor *monitor, 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); - - 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) + GFile *activation_mount_root; + gchar *uri; + + /* 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) { - monitor->camera_volumes = g_list_prepend (monitor->camera_volumes, volume); - *added_volumes = g_list_prepend (*added_volumes, g_object_ref (volume)); - } - - g_free (l->data); + uri = g_strdup_printf ("gphoto2://[usb:%03d,%03d]", usb_bus_num, usb_device_num); + } + else + { + 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); + + 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); } |