L'API WebHID permet aux sites Web d'accéder à d'autres claviers auxiliaires et à des manettes de jeu exotiques.
Il existe une longue traîne d'appareils d'interface humaine (HID), tels que des claviers ou des manettes de jeu exotiques, qui sont trop récents, trop anciens ou trop rares pour être accessibles par les systèmes pilotes de périphériques. L'API WebHID résout ce problème en fournissant un pour implémenter une logique spécifique à l'appareil en JavaScript.
Cas d'utilisation suggérés
Un appareil HID reçoit des entrées ou fournit des sorties à des humains. Exemples d'appareils comme les claviers, les dispositifs de pointage (souris, écrans tactiles, etc.) et les manettes de jeu. Le protocole HID permet d'accéder à ces appareils depuis un ordinateur. ordinateurs à l’aide de pilotes de système d’exploitation. La plate-forme Web est compatible avec les appareils HID en s'appuyant sur ces pilotes.
L'impossibilité d'accéder à des appareils HID peu courants est particulièrement pénible mais plutôt d'autres claviers auxiliaires (par exemple, Elgato Stream Deck et Jabra). des casques audio et des touches X) et la compatibilité avec des manettes de jeu exotiques. Manettes de jeu conçues pour ordinateur utilisent souvent HID pour les entrées et sorties de la manette de jeu (boutons, joysticks, déclencheurs) (LED, bruits). Malheureusement, les entrées et sorties de la manette ne sont pas bien standardisés et les navigateurs web nécessitent souvent une logique personnalisée pour des appareils spécifiques. Cette situation n'est pas durable et entraîne une mauvaise prise en charge de la longue traîne des anciennes et appareils peu courants. Cela oblige également le navigateur à dépendre de particularités dans le comportement d'appareils spécifiques.
Terminologie
La fonctionnalité HID repose sur deux concepts fondamentaux: les rapports et les descripteurs de rapport. Les rapports désignent les données échangées entre un appareil et un client logiciel. Le descripteur du rapport décrit le format et la signification des données que l'appareil compatibles.
Un HID (Human Interface Device) est un type de dispositif qui reçoit des entrées de ou fournit des résultats à des humains. Il fait également référence au protocole HID, une norme une communication bidirectionnelle entre un hôte et un appareil conçue pour pour simplifier la procédure d'installation. À l'origine, le protocole HID a été développé pour les périphériques USB, mais a depuis été implémentée sur de nombreux autres protocoles, y compris le Bluetooth.
Les applications et les appareils HID échangent des données binaires via trois types de rapports:
Type de rapport | Description |
---|---|
Rapport d'entrée | Données envoyées de l'appareil à l'application (par exemple, sur un bouton). |
Rapport sur les résultats | Données envoyées de l'application à l'appareil (demande d'activation du rétroéclairage du clavier, par exemple) |
Rapport sur les fonctionnalités | Données pouvant être envoyées dans les deux sens. Le format est spécifique à chaque appareil. |
Un descripteur de rapport décrit le format binaire des rapports compatibles avec appareil. Sa structure est hiérarchique et permet de regrouper les rapports pour en créer de la collection de premier niveau. Le format du descripteur est défini par la spécification HID.
L'utilisation d'un HID est une valeur numérique faisant référence à une entrée ou à une sortie standardisées. Les valeurs d'utilisation permettent à un appareil de décrire l'usage auquel il est destiné et les l'objectif de chaque champ dans ses rapports. Par exemple, l'un est défini pour la partie gauche bouton d'une souris. Les utilisations sont également organisées en pages d'utilisation, qui fournissent indique la catégorie générale de l'appareil ou du rapport.
Utiliser l'API WebHID
Détection de caractéristiques
Pour vérifier si l'API WebHID est compatible, utilisez:
if ("hid" in navigator) {
// The WebHID API is supported.
}
Ouvrir une connexion HID
L'API WebHID est asynchrone par la conception pour empêcher l'interface utilisateur du site Web en attente d'une entrée. C'est important, car les données HID peuvent être reçues à tout moment, nécessitant un moyen de l'écouter.
Pour ouvrir une connexion HID, accédez d'abord à un objet HIDDevice
. Pour cela, vous pouvez
soit inviter l'utilisateur à sélectionner un appareil en appelant
navigator.hid.requestDevice()
, ou choisissez-en un dans navigator.hid.getDevices()
qui renvoie une liste des appareils auxquels le site Web a accès
précédemment.
La fonction navigator.hid.requestDevice()
utilise un objet obligatoire qui
définit des filtres. Ils sont utilisés pour correspondre à tout appareil connecté à un fournisseur USB
un identifiant (vendorId
), un code produit USB (productId
), une page d'utilisation
(usagePage
) et une valeur d'utilisation (usage
). Vous pouvez les obtenir dans la page
Dépôt d'ID USB et le document sur les tableaux d'utilisation HID.
Les multiples objets HIDDevice
renvoyés par cette fonction représentent plusieurs
interfaces HID sur le même appareil physique.
// Filter on devices with the Nintendo Switch Joy-Con USB Vendor/Product IDs.
const filters = [
{
vendorId: 0x057e, // Nintendo Co., Ltd
productId: 0x2006 // Joy-Con Left
},
{
vendorId: 0x057e, // Nintendo Co., Ltd
productId: 0x2007 // Joy-Con Right
}
];
// Prompt user to select a Joy-Con device.
const [device] = await navigator.hid.requestDevice({ filters });
// Get all devices the user has previously granted the website access to.
const devices = await navigator.hid.getDevices();
![Capture d'écran d'une invite concernant un appareil HID sur un site Web.](https://developer.chrome.com/static/docs/capabilities/hid/image/screenshot-an-hid-device-e26b194feb58a.jpg?authuser=19&hl=fr)
Vous pouvez également utiliser la clé exclusionFilters
facultative dans
navigator.hid.requestDevice()
pour exclure certains appareils du sélecteur de navigateur
qui sont connus pour
dysfonctionnement, par exemple.
// Request access to a device with vendor ID 0xABCD. The device must also have
// a collection with usage page Consumer (0x000C) and usage ID Consumer
// Control (0x0001). The device with product ID 0x1234 is malfunctioning.
const [device] = await navigator.hid.requestDevice({
filters: [{ vendorId: 0xabcd, usagePage: 0x000c, usage: 0x0001 }],
exclusionFilters: [{ vendorId: 0xabcd, productId: 0x1234 }],
});
Un objet HIDDevice
contient des identifiants de fournisseur et de produit USB pour l'appareil.
l'identification. Son attribut collections
est initialisé avec une
description des formats de rapport de l'appareil.
for (let collection of device.collections) {
// An HID collection includes usage, usage page, reports, and subcollections.
console.log(`Usage: ${collection.usage}`);
console.log(`Usage page: ${collection.usagePage}`);
for (let inputReport of collection.inputReports) {
console.log(`Input report: ${inputReport.reportId}`);
// Loop through inputReport.items
}
for (let outputReport of collection.outputReports) {
console.log(`Output report: ${outputReport.reportId}`);
// Loop through outputReport.items
}
for (let featureReport of collection.featureReports) {
console.log(`Feature report: ${featureReport.reportId}`);
// Loop through featureReport.items
}
// Loop through subcollections with collection.children
}
Par défaut, les appareils HIDDevice
sont renvoyés dans un état "fermé" et doit être
ouvert en appelant open()
avant que des données puissent être envoyées ou reçues.
// Wait for the HID connection to open before sending/receiving data.
await device.open();
Recevoir les rapports d'entrée
Une fois la connexion HID établie, vous pouvez gérer l'entrée entrante.
en écoutant les événements "inputreport"
depuis l'appareil. Ces événements
contiennent les données HID en tant qu'objet DataView
(data
), c'est-à-dire l'appareil HID auquel ils appartiennent.
à (device
) et l'ID de rapport 8 bits associé au rapport d'entrée
(reportId
).
![Photo Nintendo Switch rouge et bleue.](https://developer.chrome.com/static/docs/capabilities/hid/image/red-blue-nintendo-switch-9754d1c61bf3.jpg?authuser=19&hl=fr)
Reprenons l'exemple précédent. Le code ci-dessous montre comment détecter le bouton sur lequel l'utilisateur a appuyé sur un appareil Joy-Con de droite afin que vous puissiez si tout va bien, essayez à la maison.
device.addEventListener("inputreport", event => {
const { data, device, reportId } = event;
// Handle only the Joy-Con Right device and a specific report ID.
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]}.`);
});
Envoyer les rapports de sortie
Pour envoyer un rapport de sortie à un appareil HID, transmettez l'ID de rapport 8 bits associé
avec le rapport de sortie (reportId
) et les octets sous forme de BufferSource
(data
) pour
device.sendReport()
La promesse renvoyée est résolue une fois que le rapport a été
envoyé. Si l'appareil HID n'utilise pas d'ID de rapport, définissez reportId
sur 0.
L'exemple ci-dessous s'applique à un appareil Joy-Con et vous montre comment le avec les rapports de sortie.
// First, send a command to enable vibration.
// Magical bytes come from https://github.com/mzyy94/joycon-toolweb
const enableVibrationData = [1, 0, 1, 64, 64, 0, 1, 64, 64, 0x48, 0x01];
await device.sendReport(0x01, new Uint8Array(enableVibrationData));
// Then, send a command to make the Joy-Con device rumble.
// Actual bytes are available in the sample below.
const rumbleData = [ /* ... */ ];
await device.sendReport(0x10, new Uint8Array(rumbleData));
Envoyer et recevoir des rapports sur les fonctionnalités
Les rapports sur les fonctionnalités sont le seul type de rapports de données HID pouvant être transmis à la fois les instructions de navigation. Elles permettent aux applications et appareils HID d'échanger des données non standardisées données HID. Contrairement aux rapports d'entrée et de sortie, les rapports sur les fonctionnalités ne sont ni reçus, envoyées régulièrement par l'application.
<ph type="x-smartling-placeholder">![Photo d'un ordinateur portable en noir et argent.](https://developer.chrome.com/static/docs/capabilities/hid/image/black-silver-laptop-comp-91a25010b2b48.jpg?authuser=19&hl=fr)
Pour envoyer un rapport de fonctionnalité à un appareil HID, transmettez l'ID de rapport 8 bits associé
avec le rapport sur les fonctionnalités (reportId
) et les octets sous forme de BufferSource
(data
) pour
device.sendFeatureReport()
La promesse renvoyée est résolue une fois que le rapport a
envoyé. Si l'appareil HID n'utilise pas d'ID de rapport, définissez reportId
sur 0.
L'exemple ci-dessous illustre l'utilisation des rapports sur les fonctionnalités en vous montrant comment demander un dispositif de rétroéclairage à clavier Apple, ouvrez-le et faites-le clignoter.
const waitFor = duration => new Promise(r => setTimeout(r, duration));
// Prompt user to select an Apple Keyboard Backlight device.
const [device] = await navigator.hid.requestDevice({
filters: [{ vendorId: 0x05ac, usage: 0x0f, usagePage: 0xff00 }]
});
// Wait for the HID connection to open.
await device.open();
// Blink!
const reportId = 1;
for (let i = 0; i < 10; i++) {
// Turn off
await device.sendFeatureReport(reportId, Uint32Array.from([0, 0]));
await waitFor(100);
// Turn on
await device.sendFeatureReport(reportId, Uint32Array.from([512, 0]));
await waitFor(100);
}
Pour recevoir un rapport sur les fonctionnalités d'un appareil HID, transmettez l'ID de rapport 8 bits
associé au rapport sur les fonctionnalités (reportId
) pour
device.receiveFeatureReport()
La promesse renvoyée se résout avec une
Objet DataView
incluant le contenu du rapport sur les fonctionnalités. Si le HID
appareil n'utilise pas les ID de rapport, définissez reportId
sur 0.
// Request feature report.
const dataView = await device.receiveFeatureReport(/* reportId= */ 1);
// Read feature report contents with dataView.getInt8(), getUint8(), etc...
Écouter la connexion et la déconnexion
Lorsque le site Web a été autorisé à accéder à un appareil HID, il peut
recevoir activement les événements de connexion et de déconnexion en écoutant "connect"
et "disconnect"
événements.
navigator.hid.addEventListener("connect", event => {
// Automatically open event.device or warn user a device is available.
});
navigator.hid.addEventListener("disconnect", event => {
// Remove |event.device| from the UI.
});
Révoquer l'accès à un appareil HID
Le site Web peut supprimer les autorisations d'accès à un appareil HID dont il n'est plus
que vous souhaitez conserver en appelant forget()
sur l'instance HIDDevice
. Pour
exemple, pour une application Web éducative utilisée
sur un ordinateur partagé avec de nombreux
les appareils mobiles, un grand nombre d'autorisations accumulées par l'utilisateur
l'expérience utilisateur.
En appelant forget()
sur une seule instance HIDDevice
, vous révoquez l'accès à tous
les interfaces HID sur le
même appareil physique.
// Voluntarily revoke access to this HID device.
await device.forget();
Comme forget()
est disponible dans Chrome 100 ou version ultérieure, vérifiez si cette fonctionnalité est
compatible avec les éléments suivants:
if ("hid" in navigator && "forget" in HIDDevice.prototype) {
// forget() is supported.
}
Conseils de développement
Déboguer facilement HID dans Chrome grâce à la page interne about://device-log
où vous pouvez voir tous les événements liés
aux périphériques HID et USB au même endroit.
![Capture d'écran de la page interne pour déboguer HID.](https://developer.chrome.com/static/docs/capabilities/hid/image/screenshot-the-internal-958992d62d73e.jpg?authuser=19&hl=fr)
Consultez l'explorateur HID pour vider le cache de l'appareil HID. les informations dans un format lisible par l'humain. Elle fait correspondre les valeurs d'utilisation aux noms de chaque Utilisation de HID
Sur la plupart des systèmes Linux, les périphériques HID
sont mappés avec des autorisations de lecture seule par
par défaut. Pour autoriser Chrome à ouvrir un appareil HID, vous devez ajouter un nouveau udev
règle. Créez un fichier à l'emplacement /etc/udev/rules.d/50-yourdevicename.rules
avec la
les contenus suivants:
KERNEL=="hidraw*", ATTRS{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"
Dans la ligne ci-dessus, [yourdevicevendor]
est 057e
si votre appareil est une Nintendo Switch
Joy-Con, par exemple. Vous pouvez également ajouter ATTRS{idProduct}
pour un
d'une règle. Assurez-vous que votre user
est un membre du groupe plugdev
. Ensuite,
reconnectez votre appareil.
Prise en charge des navigateurs
L'API WebHID est disponible sur toutes les plates-formes de bureau (ChromeOS, Linux, macOS, et Windows) dans Chrome 89.
Démonstrations
Certaines démos WebHID sont répertoriées sur web.dev/hid-examples. Allez voir !
Sécurité et confidentialité
Les auteurs des spécifications ont conçu et implémenté l'API WebHID à l'aide de l'API définis dans l'article Contrôler l'accès à des fonctionnalités de plate-forme Web performantes, y compris le contrôle de l'utilisateur, la transparence et l'ergonomie. La possibilité d'utiliser L'API est principalement contrôlée par un modèle d'autorisation qui n'accorde l'accès qu'à un seul accès HID périphérique à la fois. En réponse à l'invite de l'utilisateur, celui-ci doit prendre des mesures pour sélectionner un appareil HID particulier.
Pour comprendre les compromis en termes de sécurité, consultez le guide Considérations de la spécification WebHID.
De plus, Chrome inspecte l'utilisation de chaque collection de niveau supérieur et si un la collection de niveau supérieur a une utilisation protégée (par exemple, clavier générique, souris), puis un site Web ne pourra pas envoyer ni recevoir de rapports définis dans ce collection. La liste complète des utilisations protégées est accessible au public.
Notez que les périphériques HID sensibles à la sécurité (tels que les périphériques HID FIDO utilisés pour une authentification plus forte) sont également bloqués dans Chrome. Consultez la liste de blocage USB et Fichiers de liste de blocage HID
Commentaires
L'équipe Chrome aimerait connaître votre avis et votre expérience concernant la API WebHID.
Présentez-nous la conception de l'API
Y a-t-il un aspect de l'API qui ne fonctionne pas comme prévu ? Ou y a-t-il des méthodes ou des propriétés dont vous avez besoin pour mettre en œuvre votre idée ?
Signalez un problème de spécification dans le dépôt GitHub de l'API WebHID ou faites part de vos commentaires à un problème existant.
Signaler un problème d'implémentation
Avez-vous détecté un bug dans l'implémentation de Chrome ? Ou l'implémentation différent des spécifications ?
Pour en savoir plus, consultez Signaler des bugs WebHID. Assurez-vous d'inclure autant
détaillez le plus possible, fournissez des instructions simples pour reproduire le bug
Composants définis sur Blink>HID
. Glitch fonctionne parfaitement
pour partager des répétitions
rapidement et facilement.
Montrez votre soutien
Prévoyez-vous d'utiliser l'API WebHID ? Votre assistance publique permet au Chrome l'équipe à hiérarchiser les fonctionnalités et montre aux autres fournisseurs de navigateurs à quel point il est essentiel les accompagner.
Envoyez un tweet à @ChromiumDev en utilisant le hashtag.
#WebHID
et n'hésitez pas à nous en faire part
où et comment vous l'utilisez.
Liens utiles
- Spécification
- Bug de suivi
- Entrée ChromeStatus.com
- Composant Blink:
Blink>HID
Remerciements
Merci à Matt Reynolds et Joe Medley pour leurs commentaires sur cet article. Photo Nintendo Switch rouge et bleue de Sara Kurfeß, et ordinateur portable noir et argenté photo d'ordinateur par Athul Cyriac Ajay sur Unsplash.