[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