summaryrefslogtreecommitdiff
path: root/monitor/gphoto2
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2009-02-20 21:27:22 +0000
committerDavid Zeuthen <davidz@src.gnome.org>2009-02-20 21:27:22 +0000
commit61b5f9a39c236d96ffc01716d95e165de4af4deb (patch)
tree0e7f397a5a6cf0e0bd2cb9cebfa41231154bdeb4 /monitor/gphoto2
parent530167e203f195a64c9420ffe90f1d28528b7000 (diff)
downloadgvfs-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.c113
-rw-r--r--monitor/gphoto2/ggphoto2volume.h8
-rw-r--r--monitor/gphoto2/ggphoto2volumemonitor.c97
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);
}