Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plan for USB HID support? #29

Closed
RByers opened this issue Oct 28, 2015 · 21 comments
Closed

Plan for USB HID support? #29

RByers opened this issue Oct 28, 2015 · 21 comments

Comments

@RByers
Copy link
Member

RByers commented Oct 28, 2015

I'm trying to figure out what the long-term plan for web access to exotic input devices should be. Would it make sense for WebUSB to someday be extended to support HID devices somehow? Eg. consider a USB mouse or stylus with some extra non-standard capability (eg. extra buttons, wheel, z-axis, etc.). How would a device vendor build such a device such that it still behaves just like a normal mouse/stylus while also making the additional input data available to a web app such that it can be used in concert with the standard data? Synchronization of event streams might be challenging here.

Said another way, what's the open web equivalent of the Chrome.hid API?

Any thoughts? I'm happy to brainstorm further if/when you feel the time is right.

@reillyeon
Copy link
Collaborator

Interaction with existing driver support would certainly be an issue and isn't currently handled by the chrome.hid API. The design there assumes that the device is not at all supported by native drivers and so the standard event stream is not available.

I can imagine an extension to WebUSB that borrows the security model but allows access at the HID protocol layer instead of the USB protocol layer, but it would be interesting to investigate this from the perspective of the pointerevents API as well.

@kenchris
Copy link

kenchris commented Feb 2, 2016

How does that relate to USB headsets, which act like regular speakers/recording devices but have additional features like change volume, mute, call etc

@reillyeon
Copy link
Collaborator

A device that wanted to expose additional features in addition to a standard USB device class would have two interfaces and the WebUSB descriptors would mark only the one for the additional features as accessible from the web.

Though, in the specific case of a USB headset those buttons are already handled by the HID spec.

@prusnak
Copy link

prusnak commented Jan 9, 2017

WebUSB descriptor contains whitelist of WebUSB enabled interfaces. I don't see a reason why should I be forced to create two interfaces if I want to enable both WebUSB and HID on one device. Interfaces (and endpoints) are VERY scarce resources on embedded devices. Having two different interfaces with different access levels (HID vs WebUSB) is fine, but let's not make it mandatory, please.

@karelbilek
Copy link

I made a related issue on chromium bug tracker, since I think it's an implementation error (that could be fixed with two lines of code)

https://bugs.chromium.org/p/chromium/issues/detail?id=679314

@oostap1
Copy link

oostap1 commented Jan 18, 2017

About @reillyeon

A device that wanted to expose additional features in addition to a standard USB device class would have two interfaces and the WebUSB descriptors would mark only the one for the additional features as accessible from the web.
Your answer is confusing me. My believe, correct me if I'm wrong, that WebUSB descriptors cannot prevent OS of locking HID interfaces (by loading standard drivers) and they are custom descriptor for Chrome to select WebUSB allowed interfaces. Please, enlighten me on that matter.

My plan was to use WebUSB with existing USB devices where HID was used to expose some buttons and LEDs.

Let say there is device with standard Audio class and some HID buttons volume up/down (whose will be taken care by OS) and some more buttons for telephony. Then, if I am correct, OS(s) will prevent Chrome to get access over those telephony buttons due to loaded standard HID driver. Is it correct?

Cannot try that out due to missing "Public Device Registry" , issue #77

@reillyeon
Copy link
Collaborator

@oostap1: You are correct. Different OSes behave a bit differently but given its prevalence the Windows behavior is important here: There is nothing that the browser can (reasonably) do to prevent Windows from loading the HID driver for an interface with HID descriptors. The winusb.sys driver must be the selected driver or else the browser cannot send raw USB traffic to the device.

@prusnak is right that WebUSB allowed origin descriptors could be used to indicate that access to an HID interface was allowed but that is outside the scope of this specification because then you're talking about defining a completely separate API for communicating with devices using the HID protocol.

I'd be interested in seeing some experimentation with building a device that could be switched from an HID mode to a WebUSB mode so that endpoints only need to be allocated for one or the other at any given time. My thought is that the default mode would be a composite device with a HID interface and an endpoint-less WebUSB interface (to save resources). The web app can claim the WebUSB interface and send a control transfer that causes the device to re-enumerate in a WebUSB-only mode. If the device loses power it switches back to HID mode.

@oostap1
Copy link

oostap1 commented Jan 18, 2017

@reillyeon Thank you for quick and clear response. You mentioned before:

Interaction with existing driver support would certainly be an issue and isn't currently handled by the chrome.hid API. The design there assumes that the device is not at all supported by native drivers and so the standard event stream is not available.

Is it correct to assume that, if chrome.hid works well with device which have one of HID interfaces, it will most probably work with WebUSB?

@reillyeon
Copy link
Collaborator

@oostap1

Is it correct to assume that, if chrome.hid works well with device which have one of HID interfaces, it will most probably work with WebUSB?

No, chrome.hid uses the platform's userspace HID API to connect to the device while chrome.usb and WebUSB use the platform's userspace USB API to connect to the device. This separation in the Chrome Apps APIs exists precisely because the HID driver is not unloadable on some platforms. HID is an additional layer on top of USB. Attempting to support WebUSB on top of HID would be a confusing hack because it would be limited to the subset of USB requests that could be generated through the system's HID APIs. Some versions of libusb for Windows attempt this and I do not want to go down the path of formally specifying that behavior.

@oostap1
Copy link

oostap1 commented Jan 18, 2017

@reillyeon Thank you for answer. Hmm. If I correctly understood your answer, web applications are going to miss HID support due to loaded HID driver in OS. Is it right?
There are thousands of devices useful for web with such extra HID interfaces. Do you have any recommendation to how to enable existing devices with HID interfaces like telephony?

@reillyeon
Copy link
Collaborator

My thought on supporting advanced HID devices is that we should be filing issues against specifications like [UIEvents-Code] to include mappings for more HID usages.

@oostap1
Copy link

oostap1 commented Jan 20, 2017

@reillyeon That was interesting and unexpected turn. Thank you for bringing that out. Adding extra buttons to that UIEvents spec will definitely cover HID inputs (buttons/events), unfortunately it still leaves HID output (LEDs) uncovered. Do you have something in mind for HID outputs as well?

@saleemrashid
Copy link

Also, a number of devices (ab)use HID to avoid requiring drivers on Windows. Do you have something in mind for them?

@saleemrashid
Copy link

saleemrashid commented Jan 21, 2017

For some use cases, the fact that interfaces aren't limited can solve this. You can create an HID interface and a WebUSB interface with the same endpoint (since endpoints are scarce on embedded devices). Now, you can claim the WebUSB interface and talk over the endpoint, but this also "claims" the HID interface (a disadvantage for some use cases). This appears to work for my device.

/cc @prusnak @Runn1ng

@karelbilek
Copy link

Does this solution work on all OSes, incl. Windows?

@reillyeon
Copy link
Collaborator

I was curious whether including an endpoint descriptor with the same endpoint number within multiple interface descriptors would work. Gonna have to do a reading of the USB spec to see just how horribly invalid that is but if it works then it's certainly a stopgap for devices that are already abusing the HID spec.

@saleemrashid
Copy link

saleemrashid commented Jan 21, 2017

@reillyeon @Runn1ng Working fine on Linux, haven't yet been able to test on Windows. Not going to be able to test on OS X.

@oostap1
Copy link

oostap1 commented Jan 23, 2017

It might save time for somebody who wants to start with existing HID on linux.
As mentioned in there should be udev rule to fix permissions on linux

SUBSYSTEM=="usb", ATTR{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"

To avoid jumping usbhid driver on it, just, add following line as well (works on Ubuntu):

SUBSYSTEM=="usb", ATTRS{idVendor}=="[yourdevicevendor]", ATTRS{idProduct}=="[yourdeviceid]", DRIVER=="usbhid", ACTION=="add", ATTR{authorized}="0"

restart udev
sudo service udev restart

Reconnect device and check whether usbhid is loaded for your device by lsusb -t.

@oostap1
Copy link

oostap1 commented Jan 23, 2017

@reillyeon
As for now I see following options to make HID working (on most platforms, not just Windows) with/without FW modifications:

  1. Implement new WebUSBHID interface for Chrome and provide to Chromium as spec/patch. It might be like chrome.hid on top of usbhid hid user space library.

  2. Cover extra HID buttons with mentioned UIEvents (still will lose HID LEDs or something else).

  3. Add "vendor specific" interface descriptor to expose HID over WebUSB but at the same time follow USBHID spec for HID.
    option 3 might be expanded to cover any "standard" classes and "vendor specific" descriptor will be used to fool OSs.

From comments above, it sounds like 1 has issues on some platforms. I'd appreciate more details, if possible.
To me 3 is quite clean solution. Except, device FW update will be required.

It would be great to hear your thoughts about those options from Chrome team point of view.

@reillyeon
Copy link
Collaborator

Following on my previous comments and addressing the original description on this issue I believe that the answer for exotic input devices is to improve the input and gamepad specifications to accommodate them. I don't want this specification to confuse that situation by also including a way to reach underneath the HID layer to talk to the device with raw USB commands.

That and the fact that most operating systems won't let us do that anyways.

@s-light
Copy link

s-light commented Jun 12, 2019

seems there are new options on the horizon: WebHID API / repository
in this comment from 04.04.2019 it is mentioned that this should come to Chromedev in near future..

more information:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants