L'API WebHID consente ai siti web di accedere a tastiere ausiliarie alternative e gamepad esotici.
C'è una "long tail" di dispositivi con interfaccia umana (HID), come tastiere o gamepad esotici, troppo nuovi, troppo vecchi o troppo insoliti per essere accessibili dai sistemi i driver di dispositivo. L'API WebHID risolve questo problema fornendo un per implementare una logica specifica per il dispositivo in JavaScript.
Casi d'uso suggeriti
Un dispositivo HID riceve l'input dagli esseri umani o li fornisce. Esempi di dispositivi includono tastiere, dispositivi di puntamento (Mouse, touchscreen e così via) e gamepad. Il protocollo HID consente di accedere a questi dispositivi da computer. computer che utilizzano driver del sistema operativo. La piattaforma web supporta i dispositivi HID facendo affidamento su questi fattori.
L'impossibilità di accedere a dispositivi HID insoliti è particolarmente dolorosa quando offre tastiere ausiliarie alternative (ad es. Elgato Stream Deck, Jabra) cuffie, tasti X) ed esotico supporto per gamepad. Gamepad progettati per i computer spesso utilizzano l'HID per gli input (pulsanti, joystick, trigger) e gli output del gamepad (LED, rumore). Purtroppo, gli input e gli output del gamepad non sono ben standardizzati e browser web spesso richiedono una logica personalizzata per dispositivi specifici. È una soluzione insostenibile e si traduce in un supporto scarso per la long tail di bambini e ragazzi dispositivi insoliti. Inoltre, il browser potrebbe dipendere da anomalie nel comportamento. di dispositivi specifici.
Terminologia
L'HID si basa su due concetti fondamentali: report e descrittori dei report. I report sono i dati scambiati tra un dispositivo e un client software. Il descrittore del report descrive il formato e il significato dei dati che il dispositivo Google Cloud.
Un HID (Human Interface Device) è un tipo di dispositivo che riceve input da o fornisce output agli esseri umani. Si riferisce anche al protocollo HID, uno standard per comunicazione bidirezionale tra un host e un dispositivo progettato per semplificare la procedura di installazione. Il protocollo HID è stato originariamente sviluppato per i dispositivi USB, ma da allora è stato implementato su molti altri protocolli, incluso il Bluetooth.
Applicazioni e dispositivi HID scambiano dati binari tramite tre tipi di report:
Tipo di rapporto | Descrizione |
---|---|
Report input | Dati inviati dal dispositivo all'applicazione (ad esempio la pressione di un pulsante). |
Output report | Dati inviati dall'applicazione al dispositivo (ad es. la richiesta di attivare la retroilluminazione della tastiera). |
Report Funzionalità | Dati che possono essere inviati in entrambe le direzioni. Il formato è specifico per dispositivo. |
Un descrittore di report descrive il formato binario dei report supportati dal dispositivo. La sua struttura è gerarchica e può raggruppare i report in modo all'interno della raccolta di primo livello. Il formato del descrittore è definito dalla specifica HID.
Un utilizzo HID è un valore numerico che fa riferimento a un input o output standardizzato. I valori di utilizzo consentono a un dispositivo di descrivere l'utilizzo previsto del dispositivo lo scopo di ogni campo nei suoi report. Ad esempio, ne viene definito uno per il il pulsante del mouse. Gli utilizzi sono inoltre organizzati in pagine di utilizzo, che forniscono una un'indicazione della categoria di alto livello del dispositivo o del report.
Utilizzo dell'API WebHID
Rilevamento delle caratteristiche
Per verificare se l'API WebHID è supportata, utilizza:
if ("hid" in navigator) {
// The WebHID API is supported.
}
Apri una connessione HID
L'API WebHID è asincrona per impedire all'interfaccia utente del sito web di quando sono in attesa di input. Questo è importante perché è possibile ricevere dati HID in qualsiasi momento, richiedendo un modo per ascoltarli.
Per aprire una connessione HID, accedi prima a un oggetto HIDDevice
. A questo scopo, puoi
puoi chiedere all'utente di selezionare un dispositivo chiamando
navigator.hid.requestDevice()
o scegline una da navigator.hid.getDevices()
che restituisce un elenco dei dispositivi a cui è stato concesso l'accesso al sito web
in precedenza.
La funzione navigator.hid.requestDevice()
accetta un oggetto obbligatorio che
definisce i filtri. Questi vengono utilizzati per abbinare qualsiasi dispositivo collegato a un fornitore USB
identificatore di prodotto (vendorId
), un codice identificativo di prodotto USB (productId
), una pagina Utilizzo
(usagePage
) e un valore di utilizzo (usage
). Puoi recuperare questi dati dal
USB ID Repository e il documento delle tabelle di utilizzo HID.
I vari oggetti HIDDevice
restituiti da questa funzione rappresentano più
Interfacce HID sullo stesso dispositivo fisico.
// 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();
Puoi anche utilizzare la chiave facoltativa exclusionFilters
in
navigator.hid.requestDevice()
per escludere alcuni dispositivi dal selettore del browser
noti per esempio per essere malfunzionanti.
// 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 oggetto HIDDevice
contiene il fornitore USB e gli ID prodotto del dispositivo
l'identificazione personale. Il suo attributo collections
è inizializzato con un ordine gerarchico
descrizione dei formati dei report del dispositivo.
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
}
Per impostazione predefinita, i dispositivi HIDDevice
vengono restituiti in un contenitore "chiuso" e deve essere
aperta chiamando open()
prima che i dati possano essere inviati o ricevuti.
// Wait for the HID connection to open before sending/receiving data.
await device.open();
Ricevi report di input
Una volta stabilita la connessione HID, puoi gestire l'input in entrata
i report ascoltando gli eventi "inputreport"
dal dispositivo. Questi eventi
Contenere i dati HID come oggetto DataView
(data
), il dispositivo HID a cui appartiene
a (device
) e l'ID report a 8 bit associato al report di input
(reportId
).
Continuando con l'esempio precedente, il codice seguente mostra come rilevare quale pulsante ha premuto l'utente su un dispositivo Joy-Con destro per spero di provarla a casa.
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]}.`);
});
Invia report di output
Per inviare un report di output a un dispositivo HID, trasmetti l'ID report a 8 bit associato
con il report di output (reportId
) e byte come BufferSource
(data
) per
device.sendReport()
, La promessa restituita si risolve una volta che il report è stato
inviate. Se il dispositivo HID non usa gli ID report, imposta reportId
su 0.
L'esempio riportato di seguito riguarda un dispositivo Joy-Con e ti mostra come realizzare creare report di output.
// 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));
Invia e ricevi report sulle funzionalità
I report sulle funzionalità sono l'unico tipo di report sui dati HID che può essere inviato indicazioni stradali. Consentono lo scambio di applicazioni e dispositivi HID non standardizzati Dati HID. A differenza dei report di input e output, i report sulle funzionalità non vengono ricevuti inviate regolarmente dall'applicazione.
Per inviare un report sulle funzionalità a un dispositivo HID, trasmetti l'ID report a 8 bit associato
con il report sulle funzionalità (reportId
) e i byte come BufferSource
(data
) per
device.sendFeatureReport()
, La promessa restituita si risolve una volta che il report
inviate. Se il dispositivo HID non usa gli ID report, imposta reportId
su 0.
L'esempio riportato di seguito illustra l'utilizzo dei report sulle funzionalità mostrando come richiedere un dispositivo per la retroilluminazione della tastiera Apple, aprirlo e farlo lampeggiare.
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);
}
Per ricevere un report sulle funzionalità da un dispositivo HID, trasmetti l'ID report a 8 bit
associate al report sulle funzionalità (reportId
) per
device.receiveFeatureReport()
. La promessa restituita si risolve con
DataView
che include i contenuti del report sulle funzionalità. Se l'HID
Il dispositivo non utilizza gli ID report, imposta reportId
su 0.
// Request feature report.
const dataView = await device.receiveFeatureReport(/* reportId= */ 1);
// Read feature report contents with dataView.getInt8(), getUint8(), etc...
Ascolta connessione e disconnessione
Quando al sito web viene concessa l'autorizzazione ad accedere a un dispositivo HID, può
ricevere attivamente eventi di connessione e disconnessione ascoltando "connect"
e "disconnect"
eventi.
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.
});
Revocare l'accesso a un dispositivo HID
Il sito web può eliminare le autorizzazioni per accedere a un dispositivo HID che non è più
che ti interessa mantenere chiamando forget()
sull'istanza HIDDevice
. Per
per un'applicazione web didattica utilizzata su un computer condiviso con molte
dispositivi, un numero elevato di autorizzazioni generate dagli utenti
un'esperienza utente positiva.
La chiamata di forget()
su una singola istanza HIDDevice
revocherà l'accesso a tutti
le interfacce HID sullo stesso dispositivo fisico.
// Voluntarily revoke access to this HID device.
await device.forget();
Poiché forget()
è disponibile in Chrome 100 o versioni successive, controlla se questa funzionalità è
supportati con quanto segue:
if ("hid" in navigator && "forget" in HIDDevice.prototype) {
// forget() is supported.
}
Suggerimenti per gli sviluppatori
Eseguire il debug di HID in Chrome è facile con la pagina interna about://device-log
dove puoi vedere in un unico posto tutti gli eventi relativi a dispositivi HID e USB.
Controlla l'Explorer HID per eseguire il dump del dispositivo HID in un formato leggibile. Mappa dai valori di utilizzo ai nomi di ogni Utilizzo dell'HID.
Sulla maggior parte dei sistemi Linux, i dispositivi HID sono mappati con autorizzazioni di sola lettura
predefinito. Per consentire a Chrome di aprire un dispositivo HID, dovrai aggiungere un nuovo udev
personalizzata. Crea un file all'indirizzo /etc/udev/rules.d/50-yourdevicename.rules
con
i seguenti contenuti:
KERNEL=="hidraw*", ATTRS{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"
Nella riga precedente, [yourdevicevendor]
è 057e
se il tuo dispositivo è Nintendo Switch
ad esempio Joy-Con. Puoi anche aggiungere ATTRS{idProduct}
per una configurazione
personalizzata. Assicurati che user
sia un membro del gruppo plugdev
. Poi,
ricollega il dispositivo.
Supporto browser
L'API WebHID è disponibile su tutte le piattaforme desktop (ChromeOS, Linux, macOS, e Windows) in Chrome 89.
Demo
Alcune demo di WebHID sono elencate all'indirizzo web.dev/hid-examples. Dai un'occhiata!
Sicurezza e privacy
Gli autori delle specifiche hanno progettato e implementato l'API WebHID utilizzando le principi definiti in Controllo dell'accesso a potenti funzionalità della piattaforma web, tra cui controllo dell'utente, trasparenza ed ergonomia. Possibilità di utilizzare L'API è controllata principalmente da un modello di autorizzazione che concede l'accesso solo a un singolo Dispositivo HID alla volta. In risposta al prompt di un utente, quest'ultimo deve attivare passaggi per selezionare un determinato dispositivo HID.
Per comprendere i compromessi in termini di sicurezza, consulta Sicurezza e privacy Considerazioni della specifica WebHID.
Inoltre, Chrome controlla l'utilizzo di ogni raccolta di primo livello e se raccolta di primo livello ha un utilizzo protetto (ad es. tastiera generica, mouse), quindi un sito web non potrà inviare e ricevere i report definiti in questo . L'elenco completo degli utilizzi protetti è disponibile pubblicamente.
Tieni presente che i dispositivi HID sensibili alla sicurezza (come i dispositivi HID FIDO utilizzati per autenticazione più forte) sono bloccati anche in Chrome. Consulta la lista bloccata USB e File della lista bloccata HID.
Feedback
Il team di Chrome vorrebbe conoscere la tua opinione ed esperienza con gli API WebHID.
Parlaci della progettazione dell'API
C'è qualcosa che non funziona come previsto nell'API? Oppure ci sono mancano metodi o proprietà necessari per implementare la tua idea?
Segnala un problema relativo alle specifiche nel repository GitHub dell'API WebHID o aggiungi le tue opinioni a un problema esistente.
Segnalare un problema con l'implementazione
Hai trovato un bug nell'implementazione di Chrome? Oppure l'implementazione rispetto alle specifiche?
Leggi l'articolo su come segnalare bug WebHID. Assicurati di includere
fornire maggiori dettagli possibili, fornire semplici istruzioni per riprodurre il bug e
Componenti impostati su Blink>HID
. Glitch è perfetto per
e condividere riproduzioni facili e veloci.
Mostra il tuo sostegno
Intendi utilizzare l'API WebHID? Il tuo supporto pubblico aiuta Chrome del team assegna la priorità alle funzionalità e mostra ad altri fornitori di browser quanto sia fondamentale supportarle.
Invia un tweet a @ChromiumDev utilizzando l'hashtag
#WebHID
e faccelo sapere
dove e come lo usi.
Link utili
- Specifiche
- Monitoraggio del bug
- Voce ChromeStatus.com
- Componente Blink:
Blink>HID
Ringraziamenti
Grazie a Matt Reynolds e Joe Medley per le loro recensioni su questo articolo. Foto di Nintendo Switch rossa e blu di Sara Kurfeß e laptop nero e argento foto al computer di Athul Cyriac Ajay su Unsplash.