Interfejs WebHID API umożliwia witrynom dostęp do alternatywnych klawiatur pomocniczych i egzotycznych padów do gier.
W obrębie długiego ogona są układy HID, takie jak klawiatur lub padów do gier, które są zbyt nowe, zbyt stare lub zbyt rzadko używane które są dostępne dla systemów sterowników urządzeń. Interfejs WebHID API rozwiązuje ten problem, udostępniając za pomocą JavaScriptu.
Sugerowane zastosowania
Urządzenie HID pobiera dane wejściowe ludziom lub przekazuje je ludziom. Przykłady urządzeń obejmują klawiatury, urządzenia wskazujące (myszy, ekrany dotykowe itp.) i pady do gier. Protokół HID umożliwia dostęp do tych urządzeń na komputerach. komputery ze sterownikami systemu operacyjnego. Platforma internetowa obsługuje urządzenia HID dzięki tym sterownikom.
Brak dostępu do rzadko używanych urządzeń HID jest szczególnie uciążliwy, gdy dotyczy alternatywnych klawiatur pomocniczych (np. Elgato Stream Deck, Jabra zestawy słuchawkowe, klawisze X) i egzotyczne pady do gier. Pady do gier zaprojektowane z myślą o komputerach często używają HID jako wejścia i wyjścia pada do gier (przyciski, joysticki, spusty) (diody LED, wibracje). Wejścia i wyjścia pada do gier nie działają poprawnie ustandaryzowane, a przeglądarki często wymagają niestandardowej logiki dla określonych urządzeń. Takie działanie jest nieskuteczne i skutkuje słabym wsparciem dla „długich ogonów” starszych i starszych na rzadko spotykane urządzenia. Sprawia też, że przeglądarka jest zależna od osobliwości w działaniu określonych urządzeń.
Terminologia
HID składa się z 2 podstawowych pojęć: raportów i deskryptorów raportów. Raporty to dane wymieniane między urządzeniem a klientem oprogramowania. Deskryptor raportu opisuje format i znaczenie danych, obsługuje.
HID (Human Interface Device) to typ urządzenia, które pobiera dane z dostarcza dane wyjściowe użytkownikom. Odnosi się też do protokołu HID, który jest standardem dla dwukierunkowa komunikacja między hostem a urządzeniem, która uprościć procedurę instalacji. Protokół HID został pierwotnie stworzony urządzeń USB, ale obecnie jest zaimplementowane za pomocą wielu innych protokołów w tym Bluetooth.
Aplikacje i urządzenia HID wymieniają dane binarne za pomocą 3 typów raportów:
Typ raportu | Opis |
---|---|
Raport wejściowy | Dane wysyłane z urządzenia do aplikacji (np. gdy naciśniesz przycisk). |
Raport wyjściowy | Dane wysyłane z aplikacji na urządzenie (np. żądanie włączenia podświetlenia klawiatury). |
Raport o funkcjach | Dane, które mogą być wysyłane w dowolnym kierunku. Format zależy od urządzenia. |
Deskryptor raportu opisuje binarny format raportów obsługiwanych przez urządzenia. Ma ona hierarchiczną strukturę i może grupować raporty jako osobne w kolekcji najwyższego poziomu. Format deskryptora to zdefiniowane w specyfikacji HID.
Użycie HID to wartość liczbowa odnosząca się do ustandaryzowanych danych wejściowych lub wyjściowych. Wartości użycia pozwalają urządzeniu opisać jego zamierzone zastosowanie oraz przez poszczególne pola w raportach. Na przykład 1 jest zdefiniowany dla lewej strony przycisk myszy. Informacje o wykorzystaniu są też uporządkowane na stronach wykorzystania, które zawierają ogólna kategoria urządzenia lub raportu.
Korzystanie z interfejsu WebHID API
Wykrywanie cech
Aby sprawdzić, czy interfejs WebHID API jest obsługiwany, użyj:
if ("hid" in navigator) {
// The WebHID API is supported.
}
Otwórz połączenie HID
Interfejs WebHID API jest z założenia asynchroniczny i uniemożliwia na czas oczekiwania na dane wejściowe. To ważne, ponieważ można odbierać dane HID w dowolnym momencie, wymagając podania sposobu, w jaki ją wysłuchać.
Aby otworzyć połączenie HID, najpierw uzyskaj dostęp do obiektu HIDDevice
. Aby to zrobić,
możesz poprosić użytkownika o wybranie urządzenia przez połączenie
navigator.hid.requestDevice()
lub wybierz coś z witryny navigator.hid.getDevices()
które zwraca listę urządzeń, do których strona ma dostęp
wcześniej.
Funkcja navigator.hid.requestDevice()
przyjmuje obowiązkowy obiekt, który
definiuje filtry. Służą one do dopasowywania dowolnego urządzenia podłączonego do dostawcy USB.
identyfikator (vendorId
), identyfikator produktu USB (productId
), strona użycia
wartość (usagePage
) oraz wartość wykorzystania (usage
). Znajdziesz je w
Repozytorium identyfikatorów USB i dokumentacja tabel użytkowania HID.
Wiele obiektów HIDDevice
zwróconych przez tę funkcję reprezentuje wiele obiektów
z interfejsami HID na tym samym urządzeniu fizycznym.
// 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();
Możesz też użyć opcjonalnego klucza exclusionFilters
w
navigator.hid.requestDevice()
, aby wykluczyć niektóre urządzenia z selektora przeglądarki
o których wiemy, że działają nieprawidłowo.
// 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 }],
});
Obiekt HIDDevice
zawiera identyfikatory dostawcy i produktu USB urządzenia
danych identyfikacyjnych. Jego atrybut collections
jest zainicjowany przy użyciu wartości hierarchicznej
z opisem formatów raportów dostępnych na poszczególnych urządzeniach.
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
}
Urządzenia HIDDevice
są domyślnie zwracane jako „zamknięte” i musi być
należy otworzyć, wywołując metodę open()
, zanim będzie można wysyłać lub odbierać dane.
// Wait for the HID connection to open before sending/receiving data.
await device.open();
Otrzymuj raporty wejściowe
Po ustanowieniu połączenia HID możesz obsługiwać przychodzące dane wejściowe.
raportów, nasłuchując zdarzeń "inputreport"
z urządzenia. Te wydarzenia
zawierają dane HID w postaci obiektu DataView
(data
), czyli urządzenia HID, do którego należą
do (device
) oraz 8-bitowy identyfikator raportu powiązany z raportem z danymi wejściowymi
(reportId
).
Kontynuując poprzedni przykład, poniżej pokazujemy kod pokazujący, jak wykryć który przycisk został naciśnięty przez użytkownika na urządzeniu Joy-Con Right, aby można było spróbuję w domu.
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]}.`);
});
Wysyłanie raportów wyjściowych
Aby wysłać raport wyjściowy do urządzenia HID, przekaż 8-bitowy identyfikator powiązany z
z raportem wyjściowym (reportId
) i bajtami w postaci BufferSource
(data
) do
device.sendReport()
. Zwrócona obietnica wygasa, gdy raport zostanie
wysłano. Jeśli urządzenie HID nie używa identyfikatorów raportów, ustaw reportId
na 0.
Poniższy przykład dotyczy urządzenia Joy-Con i pokazuje, jak je zrobić z raportami wyników.
// 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));
Wysyłanie i odbieranie raportów dotyczących nowych funkcji
Raporty o funkcjach to jedyny typ raportów z danymi HID, które mogą być przesyłane wskazówek dojazdu. Umożliwiają one urządzeniom i aplikacjom HID wymianę nieustandaryzowanych Dane HID. W przeciwieństwie do raportów wejściowych i wyjściowych raporty dotyczące funkcji nie są przekazywane, regularnie wysyłane przez aplikację.
Aby wysłać raport dotyczący funkcji na urządzenie HID, przekaż 8-bitowy identyfikator powiązany z raportem
z raportem funkcji (reportId
) i bajtami w postaci BufferSource
(data
) do
device.sendFeatureReport()
. Zwrócona obietnica wygasa, gdy raport
wysłano. Jeśli urządzenie HID nie używa identyfikatorów raportów, ustaw reportId
na 0.
Poniższy przykład pokazuje, jak korzystać z raportów funkcji. wyślij żądanie urządzenia z podświetleniem klawiatury Apple, otwórz je i spraw, żeby mrugnęło.
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);
}
Aby otrzymać raport dotyczący funkcji z urządzenia HID, przekaż 8-bitowy identyfikator raportu
powiązane z raportem funkcji (reportId
) na
device.receiveFeatureReport()
Zwrócona obietnica rozwiązuje
DataView
– obiekt zawierający zawartość raportu dotyczącego cech. Jeśli HID
urządzenie nie używa identyfikatorów raportów, ustaw reportId
na 0.
// Request feature report.
const dataView = await device.receiveFeatureReport(/* reportId= */ 1);
// Read feature report contents with dataView.getInt8(), getUint8(), etc...
Nasłuchuj połączenia i rozłączania
Jeśli strona ma dostęp do urządzenia HID, może
aktywnie odbieraj zdarzenia połączenia i rozłączenia przez nasłuchiwanie "connect"
i "disconnect"
zdarzenia.
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.
});
Unieważnij dostęp do urządzenia HID
Strona może wyczyścić uprawnienia dostępu do urządzenia HID, do którego już nie jest
chcesz zachować zainteresowanie, wywołując funkcję forget()
w wystąpieniu HIDDevice
. Dla:
przykładowa edukacyjna aplikacja internetowa używana na współdzielonym komputerze
tych urządzeń, duża liczba zebranych uprawnień użytkowników powoduje,
użytkowników.
Wywołanie forget()
w pojedynczej instancji HIDDevice
anuluje dostęp do wszystkich
z interfejsami HID na tym samym urządzeniu.
// Voluntarily revoke access to this HID device.
await device.forget();
Funkcja forget()
jest dostępna w Chrome 100 i nowszych wersjach, więc sprawdź, czy jest ona
obsługiwane przez:
if ("hid" in navigator && "forget" in HIDDevice.prototype) {
// forget() is supported.
}
Wskazówki dla programistów
Debugowanie HID w Chrome jest proste dzięki stronie wewnętrznej: about://device-log
który umożliwia przeglądanie wszystkich zdarzeń związanych z urządzeniem HID i USB w jednym miejscu.
W narzędziu HID Explorer możesz zainstalować zrzut danych z urządzenia HID w formacie zrozumiałym dla człowieka. Mapowanie od wartości użycia na nazwy Wykorzystanie HID.
W większości systemów Linux urządzenia HID są mapowane z uprawnieniami tylko do odczytu przez
wartość domyślną. Aby zezwolić Chrome na otwieranie urządzenia HID, musisz dodać nowy udev
. Utwórz plik pod adresem /etc/udev/rules.d/50-yourdevicename.rules
z
ta treść:
KERNEL=="hidraw*", ATTRS{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"
W wierszu powyżej [yourdevicevendor]
to 057e
, jeśli Twoje urządzenie to Nintendo Switch
Joy-Con. Możesz też dodać ATTRS{idProduct}
, aby dokładniej określić
. Upewnij się, że user
jest członkiem grupy plugdev
. Potem wystarczy,
Ponownie podłącz urządzenie.
Obsługa przeglądarek
Interfejs WebHID API jest dostępny na wszystkich platformach komputerowych (ChromeOS, Linux, macOS, i Windows) w Chrome 89.
Prezentacje
Niektóre wersje demonstracyjne WebHID znajdziesz na stronie web.dev/hid-examples. Zobacz!
Bezpieczeństwo i prywatność
Autorzy specyfikacji zaprojektowali i zaimplementowali interfejs WebHID API, wykorzystując podstawowe zasad zdefiniowanych w artykule Kontrolowanie dostępu do zaawansowanych funkcji platform internetowych, takich jak kontrola użytkownika, przejrzystość i ergonomia. Możliwość korzystania z tej karty Interfejs API jest chroniony głównie przez model uprawnień, który przyznaje dostęp tylko jedno urządzenie HID. W odpowiedzi na prośbę użytkownika musi on podjąć decyzję kroków, aby wybrać konkretne urządzenie HID.
Aby poznać zalety zabezpieczeń, zapoznaj się z artykułem na temat bezpieczeństwa i prywatności Uwagi w specyfikacji WebHID.
Oprócz tego Chrome sprawdza wykorzystanie każdej kolekcji najwyższego poziomu oraz czy kolekcji najwyższego poziomu mają chronione użycie (np. standardowa klawiatura, mysz), a następnie witryna nie będzie mogła wysyłać ani odbierać raportów zdefiniowanych w tej kolekcji. Pełna lista chronionych zastosowań jest dostępna publicznie.
Należy pamiętać, że urządzenia HID newralgiczne (takie jak urządzenia FIDO HID używane do silniejsze uwierzytelnianie) są też blokowane w Chrome. Zobacz listę zablokowanych USB oraz plików z listą zablokowanych HID.
Prześlij opinię
Zespół Chrome chętnie pozna Twoje przemyślenia i doświadczenia dotyczące Interfejs API WebHID.
Opowiedz nam o konstrukcji interfejsu API
Czy jest coś, co w interfejsie API nie działa zgodnie z oczekiwaniami? Czy są jeśli brakuje metod lub właściwości niezbędnych do realizacji pomysłu?
Zgłoś problem ze specyfikacją w repozytorium GitHub interfejsu WebHID API lub dodaj opinię do istniejącego problemu.
Zgłoś problem z implementacją
Czy wystąpił błąd z implementacją Chrome? Czy wdrożenie różni się od specyfikacji?
Zapoznaj się z artykułem Jak zgłaszać błędy WebHID. Podaj jak najwięcej
jak najwięcej szczegółów, podać proste instrukcje dotyczące odtworzenia błędu oraz
Ustawiono Komponenty na Blink>HID
. Glitch działa świetnie:
szybkie i łatwe udostępnianie.
Pokaż wsparcie
Czy zamierzasz korzystać z interfejsu WebHID API? Wasze publiczne wsparcie pomaga nam ulepszyć Chrome nadaje priorytet funkcjom i pokazuje innym dostawcom przeglądarek, jak ważne jest, ich wsparcie.
Wyślij tweeta na adres @ChromiumDev, używając hashtagu
#WebHID
i poinformuj nas o tym
gdzie i jak z niej korzystasz.
Przydatne linki
- Specyfikacja
- Śledzenie błędu
- Wpis na temat ChromeStatus.com
- Komponent Blink:
Blink>HID
Podziękowania
Dziękujemy Mattowi Reynoldsowi i Joe Medley za opinię o tym artykule. Czerwono-niebieskie zdjęcie Nintendo Switch, wykonawca: Sara Kurfeß, oraz czarno-srebrny laptop zdjęcie komputera: Athul Cyriac Ajay w Unsplash.