[Spice-commits] doc/reference src/map-file src/spice-glib-sym-file src/usb-backend.c src/usb-backend.h src/usb-device-manager.c src/usb-device-manager.h
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Jan 28 12:21:08 UTC 2022
doc/reference/spice-gtk-sections.txt | 1
src/map-file | 1
src/spice-glib-sym-file | 1
src/usb-backend.c | 53 +++++++++++++++++++++++++++++------
src/usb-backend.h | 3 +
src/usb-device-manager.c | 35 +++++++++++++++++++++++
src/usb-device-manager.h | 5 +++
7 files changed, 90 insertions(+), 9 deletions(-)
New commits:
commit 9a0cec4b2f818d30eb2aa1dca8f635ece7650fa2
Author: Iordan Iordanov <iiordanov at gmail.com>
Date: Thu Dec 23 21:17:45 2021 -0500
Implemented the ability to allocate SpiceUsbDevice instances
by passing an open file descriptor in order to support the modern
Android USB device permissioning scheme.
During the process, a handle obtained by a call to
libusb_wrap_sys_device() is stored in the SpiceUsbDevice instance.
A call to libusb_open() is skipped if there is already a handle
present in the SpiceUsbDevice instance.
Finally, on Android, the option LIBUSB_OPTION_NO_DEVICE_DISCOVERY
must be set prior to the call to libusb_init() as per libusb
documentation.
Acked-by: Frediano Ziglio <freddy77 at gmail.com>
diff --git a/doc/reference/spice-gtk-sections.txt b/doc/reference/spice-gtk-sections.txt
index d5a7d58..5cd6686 100644
--- a/doc/reference/spice-gtk-sections.txt
+++ b/doc/reference/spice-gtk-sections.txt
@@ -358,6 +358,7 @@ spice_usb_device_manager_connect_device_finish
spice_usb_device_manager_disconnect_device
spice_usb_device_manager_disconnect_device_async
spice_usb_device_manager_disconnect_device_finish
+spice_usb_device_manager_allocate_device_for_file_descriptor
<SUBSECTION>
SpiceUsbDevice
spice_usb_device_get_description
diff --git a/src/map-file b/src/map-file
index 2dbb0d0..c0d8ca6 100644
--- a/src/map-file
+++ b/src/map-file
@@ -182,6 +182,7 @@ spice_usb_device_manager_get_devices_with_filter;
spice_usb_device_manager_get_type;
spice_usb_device_manager_is_device_connected;
spice_usb_device_manager_is_redirecting;
+spice_usb_device_manager_allocate_device_for_file_descriptor;
spice_usb_device_manager_create_shared_cd_device;
spice_usb_device_manager_is_device_shared_cd;
spice_usb_device_widget_get_type;
diff --git a/src/spice-glib-sym-file b/src/spice-glib-sym-file
index 2cc80aa..ccaad1a 100644
--- a/src/spice-glib-sym-file
+++ b/src/spice-glib-sym-file
@@ -160,6 +160,7 @@ spice_usb_device_manager_get_devices_with_filter
spice_usb_device_manager_get_type
spice_usb_device_manager_is_device_connected
spice_usb_device_manager_is_redirecting
+spice_usb_device_manager_allocate_device_for_file_descriptor
spice_usbredir_channel_get_type
spice_util_get_debug
spice_util_get_version_string
diff --git a/src/usb-backend.c b/src/usb-backend.c
index c76d576..930ae4e 100644
--- a/src/usb-backend.c
+++ b/src/usb-backend.c
@@ -49,6 +49,7 @@ struct _SpiceUsbDevice
/* Pointer to device. Either real device (libusb_device)
* or emulated one (edev) */
libusb_device *libusb_device;
+ libusb_device_handle *handle;
SpiceUsbEmulatedDevice *edev;
gint ref_count;
SpiceUsbBackendChannel *attached_to;
@@ -436,6 +437,9 @@ SpiceUsbBackend *spice_usb_backend_new(GError **error)
SpiceUsbBackend *be;
SPICE_DEBUG("%s >>", __FUNCTION__);
be = g_new0(SpiceUsbBackend, 1);
+#ifdef __ANDROID__
+ libusb_set_option(NULL, LIBUSB_OPTION_NO_DEVICE_DISCOVERY);
+#endif
rc = libusb_init(&be->libusb_context);
if (rc < 0) {
const char *desc = libusb_strerror(rc);
@@ -1208,7 +1212,7 @@ gboolean spice_usb_backend_channel_attach(SpiceUsbBackendChannel *ch,
SpiceUsbDevice *dev,
GError **error)
{
- int rc;
+ int rc = 0;
SPICE_DEBUG("%s >> ch %p, dev %p (was attached %p)", __FUNCTION__, ch, dev, ch->attached);
g_return_val_if_fail(dev != NULL, FALSE);
@@ -1222,20 +1226,22 @@ gboolean spice_usb_backend_channel_attach(SpiceUsbBackendChannel *ch,
return FALSE;
}
- libusb_device_handle *handle = NULL;
+ libusb_device_handle *handle = dev->handle;
if (ch->state != USB_CHANNEL_STATE_INITIALIZING) {
ch->state = USB_CHANNEL_STATE_HOST;
}
- /*
- Under Windows we need to avoid updating
- list of devices when we are acquiring the device
- */
- set_redirecting(ch->backend, TRUE);
+ if (!handle) {
+ /*
+ Under Windows we need to avoid updating
+ list of devices when we are acquiring the device
+ */
+ set_redirecting(ch->backend, TRUE);
- rc = libusb_open(dev->libusb_device, &handle);
+ rc = libusb_open(dev->libusb_device, &handle);
- set_redirecting(ch->backend, FALSE);
+ set_redirecting(ch->backend, FALSE);
+ }
if (rc) {
const char *desc = libusb_strerror(rc);
@@ -1522,3 +1528,32 @@ spice_usb_backend_create_emulated_device(SpiceUsbBackend *be,
return TRUE;
}
+
+SpiceUsbDevice *
+spice_usb_backend_allocate_device_for_file_descriptor(SpiceUsbBackend *be,
+ int file_descriptor,
+ GError **err)
+{
+ libusb_device_handle *handle = NULL;
+ libusb_context *ctx = be->libusb_context;
+ if (!ctx) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("libusb backend is null"));
+ return NULL;
+ }
+
+ if (libusb_wrap_sys_device(ctx, (intptr_t)file_descriptor, &handle) < 0) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("libusb failed to create handle for specified file descriptor"));
+ return NULL;
+ }
+
+ SpiceUsbDevice *device = allocate_backend_device(libusb_get_device(handle));
+ if (!device) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("failed to allocate SpiceUsbDevice"));
+ } else {
+ device->handle = handle;
+ }
+ return device;
+}
\ No newline at end of file
diff --git a/src/usb-backend.h b/src/usb-backend.h
index 4dff03f..3dd7dfc 100644
--- a/src/usb-backend.h
+++ b/src/usb-backend.h
@@ -93,5 +93,8 @@ void spice_usb_backend_channel_get_guest_filter(SpiceUsbBackendChannel *ch,
int *count);
void spice_usb_backend_return_write_data(SpiceUsbBackendChannel *ch, void *data);
gchar *spice_usb_backend_device_get_description(SpiceUsbDevice *dev, const gchar *format);
+SpiceUsbDevice *spice_usb_backend_allocate_device_for_file_descriptor(SpiceUsbBackend *be,
+ int file_descriptor,
+ GError **err);
G_END_DECLS
diff --git a/src/usb-device-manager.c b/src/usb-device-manager.c
index 738eba5..24b6727 100644
--- a/src/usb-device-manager.c
+++ b/src/usb-device-manager.c
@@ -1521,6 +1521,41 @@ spice_usb_device_manager_is_device_shared_cd(SpiceUsbDeviceManager *manager,
#endif
}
+/**
+ * spice_usb_device_manager_allocate_device_for_file_descriptor:
+ * @manager: (type SpiceUsbDeviceManager): the #SpiceUsbDeviceManager manager.
+ * @file_descriptor: an open file descriptor for the USB device.
+ * @err: (allow-none): a return location for a #GError, or %NULL.
+ *
+ * Allocates a SpiceUsbDevice instance for the specified file descriptor.
+ *
+ * Returns: (nullable) (transfer full): an allocated SpiceUsbDevice instance or %NULL in case of failure.
+ *
+ * Since: 0.40
+ */
+SpiceUsbDevice *
+spice_usb_device_manager_allocate_device_for_file_descriptor(SpiceUsbDeviceManager *manager,
+ int file_descriptor,
+ GError **err)
+{
+#ifdef USE_USBREDIR
+ SpiceUsbDeviceManagerPrivate *priv = manager->priv;
+ if (!priv->context) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("libusb backend is null"));
+ return NULL;
+ }
+
+ return spice_usb_backend_allocate_device_for_file_descriptor(priv->context,
+ file_descriptor,
+ err);
+#else
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("USB redirection support not compiled in"));
+ return NULL;
+#endif
+}
+
#ifdef USE_USBREDIR
/*
* SpiceUsbDevice
diff --git a/src/usb-device-manager.h b/src/usb-device-manager.h
index 4747dd4..1cebeb8 100644
--- a/src/usb-device-manager.h
+++ b/src/usb-device-manager.h
@@ -152,6 +152,11 @@ gboolean
spice_usb_device_manager_is_device_shared_cd(SpiceUsbDeviceManager *manager,
SpiceUsbDevice *device);
+SpiceUsbDevice *
+spice_usb_device_manager_allocate_device_for_file_descriptor(SpiceUsbDeviceManager *manager,
+ int file_descriptor,
+ GError **err);
+
G_END_DECLS
#endif /* __SPICE_USB_DEVICE_MANAGER_H__ */
More information about the Spice-commits
mailing list