Re: attaching a USB device by libusb_device or libusb_device_handle on Android

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Uri,

Thanks for your assistance. I got it working. I'm attaching a patch
that does the job, and would really like it if we can make it
acceptable for inclusion into spice-gtk.

In general, the changes accomplish the following:

- Add the ability to allocate a SpiceUsbDevice using a file descriptor
- Added a field that can keep a reference to the device handle that is
created by libusb from a file descriptor. This handle is used on
Android in place of a call to libusb_open() that would fail.
- On Android, set option LIBUSB_OPTION_NO_DEVICE_DISCOVERY prior to
libusb_init()
- Implement a method of retrieving the SpiceUsbBackend context from
the SpiceUsbDeviceManager (which holds the properly initialized libusb
context). This backend can be passed to the new
allocate_device_for_file_descriptor() method.

Please let me know what changes you think are needed.

Many thanks!
iordan

On Tue, Dec 21, 2021 at 8:05 AM Uri Lublin <uril@xxxxxxxxxx> wrote:
>
> Hi,
>
> On Tue, Dec 21, 2021 at 9:24 AM i iordanov <iiordanov@xxxxxxxxx> wrote:
> >
> > Hello,
> >
> > Thanks for responding! As mentioned, I am trying to find a working,
> > programmatic way to pass a USB devices by either libusb_device or
> > libusb_device_handle from aSPICE and Opaque.
> >
> > I've now compiled libusb, usbredir 0.12, and recompiled spice-gtk 0.39
> > with usbredir support.
> >
> > The code I came up with looks like the following. The integer
> > fileDescriptor holds a file descriptor for the USB device obtained in
> > java after requesting permissions from the user.
> >
> > The first bit is from
> > https://github.com/libusb/libusb/blob/master/android/README.
> >
> > NOTE: For the part after the call to allocate_backend_device(), I had
> > to include the entire usb-backend.c file as you do in your tests in
> > spice-gtk, since I couldn't find a public API that allows me to
> > construct a SpiceUsbDevice. This may be a feature request that I'd
> > need to open with your project provided we can get USB redirection to
> > work in the first place.
> >
> > ======================================
> > JNIEXPORT void JNICALL
> > Java_com_undatech_opaque_SpiceCommunicator_SpiceSetNativeFileDescriptor(JNIEnv
> > *env,
> >
> >  jobject obj,
> >
> >  jint fileDescriptor)
> > {
> >     // START: https://github.com/libusb/libusb/blob/master/android/README
> >
> >     libusb_context *ctx = NULL;
> >     libusb_device_handle *devh = NULL;
> >     int r = 0;
> >     r = libusb_set_option(NULL, LIBUSB_OPTION_NO_DEVICE_DISCOVERY, NULL);
> >     if (r != LIBUSB_SUCCESS) {
> >         LOGE("%s: libusb_set_option failed", __FUNCTION__);
> >         return;
> >     }
> >     r = libusb_init(&ctx);
> >     if (r < 0) {
> >         LOGE("%s: libusb_init failed", __FUNCTION__);
> >         return;
> >     }
> >
> >     LOGD("%s: calling libusb_wrap_sys_device", __FUNCTION__);
> >     r = libusb_wrap_sys_device(ctx, (intptr_t)fileDescriptor, &devh);
> >     if (r < 0) {
> >         LOGE("%s: libusb_wrap_sys_device failed", __FUNCTION__);
> >         return;
> >     } else if (devh == NULL) {
> >         LOGE("%s: libusb_wrap_sys_device returned invalid handle",
> > __FUNCTION__);
> >         return;
> >     }
> >
> >     // END: https://github.com/libusb/libusb/blob/master/android/README
>
>
> That means the code should not call libusb_init without setting
> NO_DEVICE_DISCOVERY.
> Likely it should not call libusb_open either.
> The current code does call those functions and also gets the list of
> USB devices.
>
> >
> >     // Calling functionality from usb-backend.c
> >     SpiceUsbDevice *device = allocate_backend_device(libusb_get_device(devh));
>
> I think you need to call libusb_set_option (as above) before any libusb_init().
> Also, maybe you can pass here devh too (or only, and get the device
> inside the function)
> and skip calling libusb_open.
>
> >
> >     SpiceUsbDeviceManager *manager =
> > spice_usb_device_manager_get(global_conn->session, NULL);
> >     if (manager == NULL) {
> >         LOGE("%s: spice_usb_device_manager_get returned null manager",
> > __FUNCTION__);
> >         return;
> >     }
> >
> >     LOGD("%s: Attaching device via
> > spice_usb_device_manager_connect_device_async", __FUNCTION__);
> >     spice_usb_device_manager_connect_device_async(manager, device,
> > NULL, NULL, NULL);
> > }
> > ======================================
> >
> > During initialization I do get a few errors, which I suppose are due
> > to spice-gtk attempting to read USB devices directly, but I am not
> > certain:
>
> It seems libusb_init() fails.
>
> >
> > ======================================
> > 2021-12-21 02:13:59.761 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:286 New session (compiled from package
> > spice-gtk 0.39.4-ce0b8)
> > 2021-12-21 02:13:59.762 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:290 Supported channels: main, display, inputs,
> > cursor, playback, record, usbredir
> > 2021-12-21 02:13:59.765 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/usb-device-manager.c:391 auto-connect filter set to
> > 0x03,-1,-1,-1,0|-1,-1,-1,-1,1
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE
> > W/GLib+android-spice: Error initializing LIBUSB support: Input/Output
> > Error [-1]
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE
> > E/GLib+android-spice: spice_usb_backend_deregister_hotplug: assertion
> > 'be != NULL' failed
> > 2021-12-21 02:13:59.762 3011-3011/com.iiordanov.aSPICE W/Thread-4:
> > type=1400 audit(0.0:1572): avc: denied { read } for name="usb"
> > dev="tmpfs" ino=1397419
> > scontext=u:r:untrusted_app:s0:c181,c257,c512,c768
> > tcontext=u:object_r:usb_device:s0 tclass=dir permissive=0
> > app=com.iiordanov.aSPICE
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:1578 Could not initialize SpiceUsbDeviceManager
> > - Error initializing LIBUSB support: Input/Output Error [-1]
>
> For example here.
>
> Regards,
>     Uri.
>
>
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/usb-device-manager.c:391 auto-connect filter set to
> > 0x03,-1,-1,-1,0|-1,-1,-1,-1,1
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE
> > W/GLib+android-spice: Error initializing LIBUSB support: Input/Output
> > Error [-1]
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE
> > E/GLib+android-spice: spice_usb_backend_deregister_hotplug: assertion
> > 'be != NULL' failed
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE
> > W/GLib+android-spice: Error initializing LIBUSB support: Input/Output
> > Error [-1]
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:1578 Could not initialize SpiceUsbDeviceManager
> > - Error initializing LIBUSB support: Input/Output Error [-1]
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE
> > W/GLib+android-spice: Error initializing LIBUSB support: Input/Output
> > Error [-1]
> > ======================================
> >
> > The rest of the log looks very encouraging, save for the fact that no
> > device is attached to the remote. The same device does attach when I
> > use spicy from my laptop to the same VM. Here is the log that is
> > output from the above code and subsequently by spice-gtk:
> >
> > ======================================
> > 2021-12-21 02:13:59.957 3011-3060/com.iiordanov.aSPICE
> > D/SpiceCommunicator: Passing fd: 85 to SPICE for device:
> > UsbDevice[mName=/dev/bus/usb/001/002,mVendorId=7741,mProductId=8338,mClass=0,mSubclass=0,mProtocol=0,mManufacturerName=CBM
> >     ,mProductName=Flash Disk
> > ,mVersion=1.00,mSerialNumberReader=android.hardware.usb.IUsbSerialReader$Stub$Proxy@ecfcac3,
> > mHasAudioPlayback=false, mHasAudioCapture=false, mHasMidi=false,
> > mHasVideoCapture=false, mHasVideoPlayback=false, mConfigurations=[
> >     UsbConfiguration[mId=1,mName=null,mAttributes=128,mMaxPower=50,mInterfaces=[
> >     UsbInterface[mId=0,mAlternateSetting=0,mName=null,mClass=8,mSubclass=6,mProtocol=80,mEndpoints=[
> >     UsbEndpoint[mAddress=1,mAttributes=2,mMaxPacketSize=512,mInterval=0]
> >     UsbEndpoint[mAddress=129,mAttributes=2,mMaxPacketSize=512,mInterval=0]]]]
> > 2021-12-21 02:13:59.957 3011-3060/com.iiordanov.aSPICE
> > D/android-service:
> > Java_com_undatech_opaque_SpiceCommunicator_SpiceSetNativeFileDescriptor:
> > start
> > 2021-12-21 02:13:59.957 3011-3060/com.iiordanov.aSPICE
> > D/android-service:
> > Java_com_undatech_opaque_SpiceCommunicator_SpiceSetNativeFileDescriptor:
> > calling libusb_wrap_sys_device
> > 2021-12-21 02:13:59.958 3011-3060/com.iiordanov.aSPICE
> > D/android-service:
> > Java_com_undatech_opaque_SpiceCommunicator_SpiceSetNativeFileDescriptor:
> > calling allocate_backend_device
> > 2021-12-21 02:13:59.958 3011-3060/com.iiordanov.aSPICE
> > D/android-service:
> > Java_com_undatech_opaque_SpiceCommunicator_SpiceSetNativeFileDescriptor:
> > calling spice_usb_device_manager_get
> > 2021-12-21 02:13:59.956 3011-3011/com.iiordanov.aSPICE W/Thread-4:
> > type=1400 audit(0.0:1578): avc: denied { read } for name="usb"
> > dev="tmpfs" ino=1397419
> > scontext=u:r:untrusted_app:s0:c181,c257,c512,c768
> > tcontext=u:object_r:usb_device:s0 tclass=dir permissive=0
> > app=com.iiordanov.aSPICE
> > 2021-12-21 02:13:59.958 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/usb-device-manager.c:391 auto-connect filter set to
> > 0x03,-1,-1,-1,0|-1,-1,-1,-1,1
> > 2021-12-21 02:13:59.960 3011-3060/com.iiordanov.aSPICE
> > D/android-service:
> > Java_com_undatech_opaque_SpiceCommunicator_SpiceSetNativeFileDescriptor:
> > Attaching device via spice_usb_device_manager_connect_device_async
> > 2021-12-21 02:13:59.960 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/usb-device-manager.c:1103 connecting device 0x70efaf1490
> > 2021-12-21 02:13:59.960 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/channel-usbredir.c:344 usbredir-9:0: connecting device
> > 1e3d:2092 (0x70efaf1490) to channel 0x725fae4540
> > 2021-12-21 02:13:59.960 3011-3079/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2921 test cap 1 in 0x1052: yes
> > 2021-12-21 02:13:59.961 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2703 usbredir-9:0: Open coroutine starting
> > 0x725fae4540
> > 2021-12-21 02:13:59.962 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2540 usbredir-9:0: Started background coroutine
> > 0x725fae43f8
> > 2021-12-21 02:13:59.962 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:2265 usbredir-9:0: Using plain text, port 6001
> > 2021-12-21 02:13:59.962 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2703 usbredir-9:1: Open coroutine starting
> > 0x725fae4340
> > 2021-12-21 02:13:59.963 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2540 usbredir-9:1: Started background coroutine
> > 0x725fae41f8
> > 2021-12-21 02:13:59.963 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:2265 usbredir-9:1: Using plain text, port 6001
> > 2021-12-21 02:13:59.965 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:2196 open host MYHOST:6001
> > 2021-12-21 02:13:59.965 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:2118 usbredir-9:0: connecting 0x709fb7aaf0...
> > 2021-12-21 02:13:59.965 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:2196 open host MYHOST:6001
> > 2021-12-21 02:13:59.966 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:2118 usbredir-9:1: connecting 0x709fa7caf0...
> > 2021-12-21 02:13:59.992 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:2102 usbredir-9:0: connect ready
> > 2021-12-21 02:13:59.992 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1372 usbredir-9:0: channel type 9 id 0 num
> > common caps 1 num caps 1
> > 2021-12-21 02:14:00.002 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1396 usbredir-9:0: Peer version: 2:2
> > 2021-12-21 02:14:00.002 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1952 usbredir-9:0: spice_channel_recv_link_msg:
> > 2 caps
> > 2021-12-21 02:14:00.002 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1966 usbredir-9:0: got remote common caps:
> > 2021-12-21 02:14:00.002 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1902     0:0xB
> > 2021-12-21 02:14:00.002 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1973 usbredir-9:0: got remote channel caps:
> > 2021-12-21 02:14:00.002 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1902     0:0x1
> > 2021-12-21 02:14:00.002 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2921 test cap 0 in 0xB: yes
> > 2021-12-21 02:14:00.002 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2921 test cap 1 in 0xB: yes
> > 2021-12-21 02:14:00.003 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2921 test cap 3 in 0xB: yes
> > 2021-12-21 02:14:00.003 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2005 usbredir-9:0: use mini header: 1
> > 2021-12-21 02:14:00.003 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:2102 usbredir-9:1: connect ready
> > 2021-12-21 02:14:00.003 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1372 usbredir-9:1: channel type 9 id 1 num
> > common caps 1 num caps 1
> > 2021-12-21 02:14:00.005 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1303 usbredir-9:0: channel up, state 3
> > 2021-12-21 02:14:00.013 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1396 usbredir-9:1: Peer version: 2:2
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1952 usbredir-9:1: spice_channel_recv_link_msg:
> > 2 caps
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1966 usbredir-9:1: got remote common caps:
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1902     0:0xB
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1973 usbredir-9:1: got remote channel caps:
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1902     0:0x1
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2921 test cap 0 in 0xB: yes
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2921 test cap 1 in 0xB: yes
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2921 test cap 3 in 0xB: yes
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2005 usbredir-9:1: use mini header: 1
> > 2021-12-21 02:14:00.018 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1303 usbredir-9:1: channel up, state 3
> > ======================================
> >
> > Your help and suggestions are highly appreciated!
> >
> > Sincerely,
> > iordan
> >
> > On Mon, Dec 20, 2021 at 5:57 AM Uri Lublin <uril@xxxxxxxxxx> wrote:
> > >
> > > Hi iordan,
> > >
> > > On Mon, Dec 20, 2021 at 9:46 AM i iordanov <iiordanov@xxxxxxxxx> wrote:
> > > >
> > > > Hi guys,
> > > >
> > > > I saw that the developers at libusb have done a bunch of work to
> > > > support accessing USB devices on unrooted Android devices, and in
> > > > response to a user request, I decided to look into the current state
> > > > of the implementation.
> > >
> > > Congrats to libusb developers.
> > >
> > > >
> > > > I am able to obtain permissions and get both:
> > > >
> > > > libusb_device *dev
> > > >
> > > > and
> > > >
> > > > libusb_device_handle *handle
> > > >
> > > > for an attached USB stick, but now do not have a good idea how to
> > > > request libspice to attach the device to the remote.
> > > >
> > > > Is there an API exposed that would permit me to attach devices by
> > > > either libusb_device or libusb_device_handle? In either case, any
> > > > pointers on how to accomplish this are welcome!
> > >
> > > On the client side, you need to build usbredir and rebuild spice-gtk
> > > with usbredir enabled.
> > >
> > > On the server side you need to build usbredir and rebuild Qemu with
> > > usbredir enabled.
> > > You also need to add to your VM configuration some USB devices and
> > > attach them to SPICE.
> > > See SPICE User Manual [1] "USB redirection" for details.
> > >
> > > [1] https://www.spice-space.org/spice-user-manual.html
> > >
> > > Regards,
> > >     Uri.
> > >
> > > >
> > > > Sincerely,
> > > > iordan
> > > >
> > > > --
> > > > The conscious mind has only one thread of execution.
> > > >
> > >
> >
> >
> > --
> > The conscious mind has only one thread of execution.
> >
>


-- 
The conscious mind has only one thread of execution.
From 3ad05ce677c74b3b680ac82b1c2b310167f7de67 Mon Sep 17 00:00:00 2001
From: Iordan Iordanov <iiordanov@xxxxxxxxx>
Date: Tue, 21 Dec 2021 11:09:40 -0500
Subject: [PATCH 5/5] Implemented the ability to attach USB devices by open
 file descriptor to support modern Android USB device permissioning scheme.

On Android, set option LIBUSB_OPTION_NO_DEVICE_DISCOVERY prior to libusb_init()
call as per libusb documentation, and skip the call to libusb_open() since
it would not be permitted on Android.

Implemented ability to obtain SpiceUsbBackend from SpiceUsbDeviceManager.
---
 src/usb-backend.c        | 32 ++++++++++++++++++++++++++++++--
 src/usb-backend.h        |  2 ++
 src/usb-device-manager.c | 10 ++++++++++
 src/usb-device-manager.h |  2 +-
 4 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/src/usb-backend.c b/src/usb-backend.c
index c76d576..da6e47b 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,7 +1226,7 @@ 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;
     }
@@ -1231,11 +1235,20 @@ gboolean spice_usb_backend_channel_attach(SpiceUsbBackendChannel *ch,
        Under Windows we need to avoid updating
        list of devices when we are acquiring the device
     */
+    #ifndef __ANDROID__
     set_redirecting(ch->backend, TRUE);
 
     rc = libusb_open(dev->libusb_device, &handle);
 
     set_redirecting(ch->backend, FALSE);
+    #else
+    /*
+       Under Android, we expect handle to have been
+       initialized from a file_descriptor and stored
+       in the SpiceUsbDevice instance already.
+    */
+    handle = dev->handle;
+    #endif
 
     if (rc) {
         const char *desc = libusb_strerror(rc);
@@ -1522,3 +1535,18 @@ spice_usb_backend_create_emulated_device(SpiceUsbBackend *be,
 
     return TRUE;
 }
+
+SpiceUsbDevice *allocate_device_for_file_descriptor(SpiceUsbBackend *be,
+                                                    int file_descriptor)
+{
+    libusb_device_handle *handle = NULL;
+    libusb_context *ctx = be->libusb_context;
+
+    if (libusb_wrap_sys_device(ctx, (intptr_t)file_descriptor, &handle) < 0) {
+        return NULL;
+    }
+
+    SpiceUsbDevice *device = allocate_backend_device(libusb_get_device(handle));
+    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..bb2afa2 100644
--- a/src/usb-backend.h
+++ b/src/usb-backend.h
@@ -22,6 +22,7 @@
 
 #include <usbredirfilter.h>
 #include "usb-device-manager.h"
+#include <libusb.h>
 
 G_BEGIN_DECLS
 
@@ -70,6 +71,7 @@ const UsbDeviceInformation* spice_usb_backend_device_get_info(const SpiceUsbDevi
 gboolean spice_usb_backend_device_isoch(SpiceUsbDevice *dev);
 void spice_usb_backend_device_eject(SpiceUsbBackend *be, SpiceUsbDevice *device);
 void spice_usb_backend_device_report_change(SpiceUsbBackend *be, SpiceUsbDevice *device);
+SpiceUsbDevice *allocate_device_for_file_descriptor(SpiceUsbBackend *be, int file_descriptor);
 
 /* returns 0 if the device passes the filter otherwise returns the error value from
  * usbredirhost_check_device_filter() such as -EIO or -ENOMEM */
diff --git a/src/usb-device-manager.c b/src/usb-device-manager.c
index 738eba5..0bd6982 100644
--- a/src/usb-device-manager.c
+++ b/src/usb-device-manager.c
@@ -1521,6 +1521,16 @@ spice_usb_device_manager_is_device_shared_cd(SpiceUsbDeviceManager *manager,
 #endif
 }
 
+gconstpointer spice_get_usb_backend(SpiceUsbDeviceManager *manager)
+{
+#ifdef USE_USBREDIR
+    SpiceUsbDeviceManagerPrivate *priv = manager->priv;
+    return priv->context;
+#else
+    return NULL;
+#endif
+}
+
 #ifdef USE_USBREDIR
 /*
  * SpiceUsbDevice
diff --git a/src/usb-device-manager.h b/src/usb-device-manager.h
index 4747dd4..d8e3a16 100644
--- a/src/usb-device-manager.h
+++ b/src/usb-device-manager.h
@@ -100,7 +100,7 @@ GType spice_usb_device_get_type(void);
 GType spice_usb_device_manager_get_type(void);
 
 gchar *spice_usb_device_get_description(SpiceUsbDevice *device, const gchar *format);
-gconstpointer spice_usb_device_get_libusb_device(const SpiceUsbDevice *device);
+gconstpointer spice_get_usb_backend(SpiceUsbDeviceManager *manager);
 
 SpiceUsbDeviceManager *spice_usb_device_manager_get(SpiceSession *session,
                                                     GError **err);
-- 
2.25.1


[Index of Archives]     [Linux Virtualization]     [Linux Virtualization]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]