diff options
author | Philip Langdale <philipl@overt.org> | 2018-04-17 20:29:05 -0700 |
---|---|---|
committer | Philip Langdale <philipl@overt.org> | 2018-04-18 16:02:38 -0700 |
commit | efc76d0cd84df8904ea661cb0e04728e3e6205d4 (patch) | |
tree | 0abc0ab0c9003cb4e9db1fcb0359815199951533 /monitor/gphoto2 | |
parent | ca9d86e6265480829c935593c38f0b3678a000bb (diff) | |
download | gvfs-efc76d0cd84df8904ea661cb0e04728e3e6205d4.tar.gz |
gphoto2: Switch to a stable device uri
For the same reasons that the equivalent change to the mtp backend
was desirable, we want to do this in the gphoto2 (ptp) backend.
Stable URIs allow things like bookmarking and external scripting
to work across plug/unplug events (which is to say, allows them
to work at all).
See the change description for the mtp backend for more details.
https://bugzilla.gnome.org/show_bug.cgi?id=795311
Diffstat (limited to 'monitor/gphoto2')
-rw-r--r-- | monitor/gphoto2/ggphoto2volumemonitor.c | 60 |
1 files changed, 55 insertions, 5 deletions
diff --git a/monitor/gphoto2/ggphoto2volumemonitor.c b/monitor/gphoto2/ggphoto2volumemonitor.c index a9f51de0..6bd9fc8b 100644 --- a/monitor/gphoto2/ggphoto2volumemonitor.c +++ b/monitor/gphoto2/ggphoto2volumemonitor.c @@ -139,7 +139,10 @@ gudev_add_camera (GGPhoto2VolumeMonitor *monitor, GUdevDevice *device, gboolean GGPhoto2Volume *volume; GList *store_heads, *l; guint num_store_heads; - const char *usb_bus_num, *usb_device_num, *device_path; + const char *usb_bus_num, *usb_device_num, *usb_serial_id, *device_path; + gchar *prefix; + GFile *mount_prefix; + gboolean serial_conflict = FALSE; device_path = g_udev_device_get_device_file (device); if (!device_path) @@ -157,6 +160,17 @@ gudev_add_camera (GGPhoto2VolumeMonitor *monitor, GUdevDevice *device, gboolean } #endif /* HAVE_LIBMTP */ + /* + * We do not use ID_SERIAL_SHORT (the actualy device serial value) as + * this field is not populated when an ID_SERIAL has to be synthesized. + */ + usb_serial_id = g_udev_device_get_property (device, "ID_SERIAL"); + if (usb_serial_id == NULL) + { + g_warning ("device %s has no ID_SERIAL property, ignoring", device_path); + return; + } + usb_bus_num = g_udev_device_get_property (device, "BUSNUM"); if (usb_bus_num == NULL) { @@ -171,9 +185,45 @@ gudev_add_camera (GGPhoto2VolumeMonitor *monitor, GUdevDevice *device, gboolean return; } - g_debug ("gudev_add_camera: camera device %s (bus: %s, device: %s)", + prefix = g_strdup_printf ("gphoto2://%s", usb_serial_id); + mount_prefix = g_file_new_for_uri (prefix); + g_free (prefix); + + /* + * We do not support plugging in multiple devices that lack proper serial + * numbers. Linux will attempt to synthesize an ID based on the device + * product information, which will avoid collisions between different + * types of device, but two identical, serial-less, devices will still + * conflict. + */ + for (l = monitor->camera_volumes; l != NULL; l = l->next) + { + GGPhoto2Volume *volume = G_GPHOTO2_VOLUME (l->data); + + GFile *existing_root = g_volume_get_activation_root (G_VOLUME (volume)); + if (g_file_equal (existing_root, mount_prefix) || + g_file_has_prefix (existing_root, mount_prefix)) + { + serial_conflict = TRUE; + } + g_object_unref (existing_root); + if (serial_conflict) + { + break; + } + } + g_object_unref (mount_prefix); + if (serial_conflict) + { + g_warning ("device %s has an identical ID_SERIAL value to an " + "existing device. Multiple devices are not supported.", + g_udev_device_get_device_file (device)); + return; + } + + g_debug ("gudev_add_camera: camera device %s (id: %s)", g_udev_device_get_device_file (device), - usb_bus_num, usb_device_num); + usb_serial_id); store_heads = get_stores_for_camera (usb_bus_num, usb_device_num); num_store_heads = g_list_length (store_heads); @@ -189,11 +239,11 @@ gudev_add_camera (GGPhoto2VolumeMonitor *monitor, GUdevDevice *device, gboolean */ if (num_store_heads == 1) { - uri = g_strdup_printf ("gphoto2://[usb:%s,%s]", usb_bus_num, usb_device_num); + uri = g_strdup_printf ("gphoto2://%s", usb_serial_id); } else { - uri = g_strdup_printf ("gphoto2://[usb:%s,%s]/%s", usb_bus_num, usb_device_num, + uri = g_strdup_printf ("gphoto2://%s/%s", usb_serial_id, store_path[0] == '/' ? store_path + 1 : store_path); } g_debug ("gudev_add_camera: ... adding URI for storage head: %s", uri); |