Skip to main content




The API de WebHID posibilita que los sitios Web accedan a teclados auxiliares alternativos y gamepads exóticos.

The WebHID API is part of the Capabilities project and is currently under development. This post will be updated as implementation progresses.

Existe una larga lista de dispositivos de interfaz humana (HID), como teclados alternativos o gamepads exóticos, que son demasiado nuevos, demasiado antiguos o poco comunes para que los controladores de dispositivos de los sistemas puedan ingresar a ellos. La API WebHID resuelve esto proporcionando una forma de poner en práctica la lógica específica del dispositivo en JavaScript.

Suggested use cases

An HID device takes input from humans or provides them with an output. Examples of devices include keyboards, pointing devices (mice, touchscreens, etc.), and gamepads. the HID protocol makes it feasible to access these devices on desktop computers using operating system drivers. The web platform supports HID devices based on these drivers.

The inability to access rare HID devices is particularly painful when it consists of alternative helper keyboards (eg. Elgato Stream cover, Jabra Headphones, X-keys) y soporte exótico para gamepad. Los gamepads diseñados para el escritorio a menudo utilizan HID para las entradas del gamepad (botones, joysticks, disparadores) y salidas (LED, rumble). Desafortunadamente, las entradas y salidas del gamepad no están bien estandarizadas y los browsers web a menudo requieren una lógica personalizada para dispositivos específicos. Esto es insostenible y da como consecuencia un soporte deficiente para la larga cola de dispositivos más antiguos y poco comunes. Además hace que el browser dependa de peculiaridades en el comportamiento de dispositivos específicos.

Actual state

Terminology

HID consta de dos conceptos fundamentales: informes y descriptores de informes. Los informes son los datos que se intercambian entre un dispositivo y un client from software. El descriptor de reporte describe el formato y el significado de los datos que admite el dispositivo.

Un HID (Dispositivo de interfaz humana) es un tipo de dispositivo que recibe entradas de persons o proporciona salidas a ellas. Además se refiere al protocolo HID, un estándar para la comunicación bidireccional entre un host y un dispositivo que está diseñado para simplificar el proceso de instalación. El protocolo HID se desarrolló originalmente para dispositivos USB, pero desde entonces se ha implementado en muchos otros protocolos, incluido Bluetooth.

HID devices and applications exchange binary data through three types of reports:

report type Description
input report Data that is sent from the device to the application (for example, a button is pressed).
output report Data that is sent from the application to the device (for example, a request to turn on the keyboard backlight).
Functions report Data that can be sent to any address. The format is device specific.

A report descriptor describes the binary format of the reports supported by the device. Its structure is hierarchical, and you can group reports as distinct collections within the top-level collection. the Format The descriptor is defined by the HID specification.

An HID usage is a numeric value that refers to a standardized input or output. Usage values enable a device to describe the intended usage of the device and the purpose of each field in its reports. As an example, one is set for the left button of a mouse. Usages are further organized into usage pages, which provide an indication of the high-level category of the device or report.

Using the WebHID API

Enabling via chrome: // flags

To experiment with the WebHID API locally on all desktop platforms, without a proof of origin token, enable the #experimental-web-platform-features flag on
chrome://flags.

Enable support during origin testing stage

The WebHID API is available on all desktop platforms (Chrome OS, Linux, macOS, and Windows) as a source test in Chrome 86. The source test is expected to end just before Chrome 89 goes live in February 2021. The API can also be enabled via a flag.

Origin testing allows you to test new features and provide feedback on their usability, practicality, and effectiveness to the web standards community. For more information, see the Origin testing guide for web developers. To enroll in this or any other proof of origin, visit the registration page.

Register for proof of origin

  1. Request a token by your origin.
  2. Add the token to your pages. There are two ways to do it:
    • Add a origin-trial tag to the header of each page. As an example, this might look like this:
    • Si puede configurar su server, además puede agregar el token utilizando un Origin-Trial Encabezado HTTP. El encabezado de respuesta resultante debería verse así:
      Origin-Trial: TOKEN_GOES_HERE

Feature detection

To check if the WebHID API is supported, use:

if ("hid" in navigator) {
}

Open a HID connection

La API de WebHID es asincrónica por diseño para evitar que la user interface del portal web se bloquee cuando se espera una entrada. Esto es esencial debido a que los datos HID se pueden recibir en cualquier momento, lo que necesita una forma de escucharlos.

To open an HID connection, first access a HIDDevice objeto. Para esto, puede solicitar al Username que seleccione un dispositivo llamando
navigator.hid.requestDevice ()or choose one of navigator.hid.getDevices ()
which returns a list of devices previously accessed by the web portal.

the navigator.hid.requestDevice () La función toma un objeto obligatorio que establece filters. Se usan para hacer coincidir cualquier dispositivo conectado con un identificador de proveedor USB (vendorId), a USB product identifier (productId), a usage page value (usagePage) and a use value (usage). You can get them from the USB ID repository and the HID Usage Tables Document.

The multiple HIDDevice The objects returned by this function represent multiple HID interfaces on the same physical device.


const filters = [
{
vendorId: 0x057e,
productId: 0x2006
},
{
vendorId: 0x057e,
productId: 0x2007
}
];


const [device] = await navigator.hid.requestDevice({ filters });


const devices = await navigator.hid.getDevices();

webhid-prompt-3406008
User message to choose a Nintendo Switch Joy-Con.

A HIDDevice The object contains USB vendor and product identifiers for device identification. Their collections The attribute se inicializa con una descripción jerárquica de los formatos de reporte del dispositivo.

for (let collection of device.collections) {
console.log(`Usage: ${collection.usage}`);
console.log(`Usage page: ${collection.usagePage}`);

for (let inputReport of collection.inputReports) {
console.log(`Input report: ${inputReport.reportId}`);
}

for (let outputReport of collection.outputReports) {
console.log(`Output report: ${outputReport.reportId}`);
}

for (let featureReport of collection.featureReports) {
console.log(`Feature report: ${featureReport.reportId}`);
}


}

the HIDDevice devices are returned by default in a "closed" state and must be opened by calling open () before data can be sent or received.


await device.open();

Receive input reports

Once the HID connection has been established, you can handle incoming incoming reports by listening "inputreport" device events. Those events contain the HID data like DataView objectdata), the HID device to which it belongs (device) and the 8-bit report ID associated with the input report (reportId).

joycon-switch-photo-9523996
Nintendo Switch Joy-Con devices.

Continuing with the previous example, the following code shows you how to detect which button the user has pressed on a Joy-Con Right device so that you can hopefully test it at home.

device.addEventListener("inputreport", event => {
const { data, device, reportId } = event;


if (device.productId !== 0x2007 && reportId !== 0x3f) return;

const value = data.getUint8(0);
if (value === 0) return;

const someButtons = { 1: "A", 2: "X", 4: "B", 8: "Y" };
console.log(`User pressed button ${someButtons[value]}.`);
});

Send outbound reports

To send an output report to an HID device, pass the 8-bit report ID associated with the output report (reportId) and bytes like BufferSource (data) to
device.sendReport (). The returned promise is resolved after the report has been sent. If the HID device does not use reporting ID, configure reportId to 0.

The following example applies to a Joy-Con device and shows you how to make it vibrate with the output reports.


const enableVibrationData = [1, 0, 1, 64, 64, 0, 1, 64, 64, 0x48, 0x01];
await device.sendReport(0x01, new Uint8Array(enableVibrationData));


const rumbleData = [ ];
await device.sendReport(0x10, new Uint8Array(rumbleData));

Send and receive function reports

Feature reports are the only type of HID data reports that can travel in both directions. They enable HID devices and applications to exchange non-standardized HID data. Unlike input and output reports, the application does not receive or send feature reports on a regular basis.

laptop-keyboard-photo-9051924
Laptop keyboard

To send a function report to an HID device, pass the 8-bit report ID associated with the function report (reportId) and bytes like BufferSource (data) to
device.sendFeatureReport (). The returned promise is resolved after the report has been sent. If the HID device does not use reporting ID, configure reportId to 0.

The following example illustrates the use of feature reports by showing you how to order an Apple keyboard backlight device, open it, and make it blink.

const waitFor = duration => new Promise(r => setTimeout(r, duration));


const [device] = await navigator.hid.requestDevice({
filters: [{ vendorId: 0x05ac, usage: 0x0f, usagePage: 0xff00 }]
});


await device.open();


const reportId = 1;
for (let i = 0; i < 10; i++) {
await device.sendFeatureReport(reportId, Uint32Array.desde([0, 0]));
await waitFor(100);
await device.sendFeatureReport(reportId, Uint32Array.desde([512, 0]));
await waitFor(100);
}

To receive a function report from an HID device, pass the 8-bit report ID associated with the function report (reportId) to
device.receiveFeatureReport (). The returned promise is resolved with a
DataView objeto que contiene el contents del reporte de características. Si el dispositivo HID no usa ID de reporte, configure reportId to 0.


const dataView = await device.receiveFeatureReport( 1);

Hear the connection and disconnection

When the web portal has permission to enter an HID device, it can actively receive connection and disconnection events by listening "connect"
and "disconnect" events.

navigator.hid.addEventListener("connect", event => {
});

navigator.hid.addEventListener("disconnect", event => {
});

Tips for developers

Debugging HID in Chrome is easy with the inner page, chrome://device-log
where you can see all events related to USB and HID devices in one place.

device-log-page-screenshot-4716868
Internal page in Chrome to debug HID.

Population

Some demos of WebHID are listed at web.dev/hid-examples. Go take a look!

Security and privacy

The spec authors have designed and implemented the WebHID API using the basic principles defined in Control access to powerful features of the web platform, including user control, transparency and ergonomics. The ability to use this API is primarily controlled by a permissions model that grants access to only one HID device at a time. In response to a user message, the user must take active steps to choose a particular HID device.

For safety trade-offs, see the Security and privacy considerations section of the WebHID specification.

Apart from this, Chrome inspects the usage of each top-level collection and if a top-level collection has protected usage (.eg generic keyboard, mouse), then a web portal will not be able to send or receive any defined reports. in that collection. The full list of protected uses is publicly available.

Note that security-sensitive HID devices (such as FIDO HID devices used for stronger authentication) are also blocked in Chrome. Watch the block list proceedings.

Feedback

The Chrome team would love to hear your thoughts and experiences with the WebHID API.

Tell us about the API design

Could there be something in the API not working as expected? Or are you missing methods or properties that you require to implement your idea?

Present a specification hurdle in the WebHID API GitHub repository or add your thoughts to an existing obstacle.

Report an obstacle with the implementation

Did you find a bug with the Chrome implementation? Or is the implementation different from the specification?

File a bug in https://new.crbug.com. Be sure to include as much detail as you can, provide simple instructions for reproducing the bug, and
Components adjusted to Blink> HID. Failure works great for quick and easy sharing of reps.

Show support

Thinking of using the WebHID API? Your public support helps the Chrome team prioritize features and shows other browser vendors how important it is to support them.

Send a tweet to @Cromodev with #WebHID and let us know where and how you are using it.

Useful Links

Thanks

Thanks to Matt reynolds and Joe medley por sus reseñas de este post. Hero image of Valentin Müller, red and blue nintendo switch picture of Sara kurfeß, and a black and silver laptop photo of Athul Cyriac Ajay on Unsplash.