WebHID API memungkinkan situs mengakses keyboard tambahan alternatif dan gamepad eksotis.
Ada banyak perangkat antarmuka manusia (HID), seperti keyboard alternatif atau gamepad eksotis, yang terlalu baru, terlalu lama, atau terlalu jarang dapat diakses oleh driver perangkat sistem. WebHID API mengatasi hal ini dengan menyediakan cara untuk menerapkan logika khusus perangkat di JavaScript.
Kasus penggunaan yang disarankan
Perangkat HID mengambil input dari atau memberikan output ke manusia. Contoh perangkat termasuk keyboard, perangkat penunjuk (mouse, layar sentuh, dll.), dan gamepad. Protokol HID memungkinkan akses perangkat ini di komputer desktop menggunakan driver sistem operasi. Platform web mendukung perangkat HID dengan mengandalkan {i>driver<i} ini.
Ketidakmampuan untuk mengakses perangkat HID yang tidak umum akan sangat menyakitkan saat menggunakan keyboard tambahan alternatif (misalnya, Elgato Stream Deck, headset Jabra, tombol X) dan dukungan gamepad eksotis. Gamepad yang dirancang untuk desktop sering menggunakan HID untuk input gamepad (tombol, joystick, pemicu) dan output (LED, rumble). Sayangnya, input dan output gamepad tidak distandarkan dengan baik dan browser web sering kali memerlukan logika kustom untuk perangkat tertentu. Hal ini tidak berkelanjutan dan mengakibatkan dukungan yang buruk bagi longtail perangkat lama dan tidak umum. Hal ini juga menyebabkan browser bergantung pada perilaku perangkat tertentu.
Terminologi
HID terdiri dari dua konsep dasar: laporan dan deskripsi laporan. Laporan adalah data yang dipertukarkan antara perangkat dan klien software. Deskripsi laporan menjelaskan format dan makna data yang didukung perangkat.
HID (Human Interface Device) adalah jenis perangkat yang mengambil input dari atau memberikan output kepada manusia. Ini juga mengacu pada protokol HID, yaitu standar untuk komunikasi dua arah antara host dan perangkat yang dirancang untuk menyederhanakan prosedur penginstalan. Protokol HID awalnya dikembangkan untuk perangkat USB, tetapi telah diterapkan pada banyak protokol lain, termasuk Bluetooth.
Aplikasi dan perangkat HID bertukar data biner melalui tiga jenis laporan:
Jenis laporan | Deskripsi |
---|---|
Laporan input | Data yang dikirim dari perangkat ke aplikasi (misalnya, tombol ditekan.) |
Laporan output | Data yang dikirim dari aplikasi ke perangkat (misalnya permintaan untuk menyalakan lampu latar keyboard). |
Laporan fitur | Data yang dapat dikirim ke salah satu arah. Formatnya berbeda-beda untuk perangkat tertentu. |
Deskripsi laporan menjelaskan format biner laporan yang didukung oleh perangkat. Strukturnya bersifat hierarkis dan dapat mengelompokkan laporan sebagai koleksi yang berbeda dalam koleksi tingkat atas. Format deskriptor ditentukan oleh spesifikasi HID.
Penggunaan HID adalah nilai numerik yang mengacu pada input atau {i>output<i} standar. Nilai penggunaan memungkinkan perangkat menjelaskan tujuan penggunaan perangkat dan tujuan setiap kolom dalam laporannya. Misalnya, satu{i> <i}ditentukan untuk tombol kiri {i>mouse<i}. Penggunaan juga disusun ke dalam halaman penggunaan yang memberikan indikasi kategori perangkat atau laporan tingkat tinggi.
Menggunakan WebHID API
Deteksi fitur
Untuk memeriksa apakah WebHID API didukung, gunakan:
if ("hid" in navigator) {
// The WebHID API is supported.
}
Membuka koneksi HID
WebHID API didesain secara asinkron untuk mencegah UI situs memblokir saat menunggu input. Hal ini penting karena data HID dapat diterima kapan saja, yang memerlukan cara untuk memprosesnya.
Untuk membuka koneksi HID, akses objek HIDDevice
terlebih dahulu. Untuk itu, Anda dapat
meminta pengguna memilih perangkat dengan memanggil
navigator.hid.requestDevice()
, atau memilih salah satu dari navigator.hid.getDevices()
yang menampilkan daftar perangkat yang sebelumnya diberi akses
oleh situs.
Fungsi navigator.hid.requestDevice()
mengambil objek wajib yang
menentukan filter. ID tersebut digunakan untuk mencocokkan perangkat apa pun yang terhubung dengan ID vendor USB (vendorId
), ID produk USB (productId
), nilai halaman penggunaan (usagePage
), dan nilai penggunaan (usage
). Anda bisa mendapatkannya dari Repositori ID USB dan dokumen tabel penggunaan HID.
Beberapa objek HIDDevice
yang ditampilkan oleh fungsi ini mewakili beberapa
antarmuka HID pada perangkat fisik yang sama.
// 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();
![Screenshot perintah perangkat HID di situs.](https://developer.chrome.com/static/docs/capabilities/hid/image/screenshot-an-hid-device-e26b194feb58a.jpg?authuser=6&hl=id)
Anda juga dapat menggunakan kunci exclusionFilters
opsional di
navigator.hid.requestDevice()
untuk mengecualikan beberapa perangkat dari alat pilih browser
yang diketahui mengalami kegagalan fungsi.
// 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 }],
});
Objek HIDDevice
berisi ID produk dan vendor USB untuk identifikasi
perangkat. Atribut collections
-nya diinisialisasi dengan deskripsi
hierarkis format laporan perangkat.
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
}
Perangkat HIDDevice
secara default ditampilkan dalam status "tertutup" dan harus
dibuka dengan memanggil open()
sebelum data dapat dikirim atau diterima.
// Wait for the HID connection to open before sending/receiving data.
await device.open();
Menerima laporan input
Setelah koneksi HID terhubung, Anda dapat menangani laporan input
yang masuk dengan memproses peristiwa "inputreport"
dari perangkat. Peristiwa tersebut
berisi data HID sebagai objek DataView
(data
), perangkat HID yang mencakupnya (device
), dan ID laporan 8 bit yang terkait dengan laporan input
(reportId
).
![Foto nintendo switch berwarna merah dan biru.](https://developer.chrome.com/static/docs/capabilities/hid/image/red-blue-nintendo-switch-9754d1c61bf3.jpg?authuser=6&hl=id)
Melanjutkan dengan contoh sebelumnya, kode di bawah ini menunjukkan cara mendeteksi tombol yang ditekan pengguna pada perangkat Joy-Con Kanan sehingga Anda dapat mencobanya di rumah.
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]}.`);
});
Mengirim laporan output
Untuk mengirim laporan output ke perangkat HID, teruskan ID laporan 8 bit yang terkait
dengan laporan output (reportId
) dan byte sebagai BufferSource
(data
) ke
device.sendReport()
. Promise yang ditampilkan akan diselesaikan setelah laporan dikirim. Jika perangkat HID tidak menggunakan ID laporan, tetapkan reportId
ke 0.
Contoh di bawah berlaku untuk perangkat Joy-Con dan menunjukkan cara membuatnya bergerak dengan laporan 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));
Mengirim dan menerima laporan fitur
Laporan fitur adalah satu-satunya jenis laporan data HID yang dapat bergerak secara dua arah. Izin ini memungkinkan perangkat dan aplikasi HID untuk bertukar data HID yang tidak standar. Tidak seperti laporan input dan output, laporan fitur tidak diterima atau dikirim oleh aplikasi secara berkala.
![Foto komputer laptop hitam dan perak.](https://developer.chrome.com/static/docs/capabilities/hid/image/black-silver-laptop-comp-91a25010b2b48.jpg?authuser=6&hl=id)
Untuk mengirim laporan fitur ke perangkat HID, teruskan ID laporan 8 bit yang terkait
dengan laporan fitur (reportId
) dan byte sebagai BufferSource
(data
) ke
device.sendFeatureReport()
. Promise yang ditampilkan akan diselesaikan setelah laporan dikirim. Jika perangkat HID tidak menggunakan ID laporan, tetapkan reportId
ke 0.
Contoh di bawah mengilustrasikan penggunaan laporan fitur dengan menunjukkan cara meminta perangkat lampu latar keyboard Apple, membukanya, dan membuatnya berkedip.
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);
}
Untuk menerima laporan fitur dari perangkat HID, teruskan ID laporan 8 bit
yang terkait dengan laporan fitur (reportId
) ke
device.receiveFeatureReport()
. Promise yang ditampilkan diselesaikan dengan objek DataView
yang berisi isi laporan fitur. Jika perangkat HID
tidak menggunakan ID laporan, tetapkan reportId
ke 0.
// Request feature report.
const dataView = await device.receiveFeatureReport(/* reportId= */ 1);
// Read feature report contents with dataView.getInt8(), getUint8(), etc...
Mendengarkan koneksi dan pemutusan koneksi
Jika situs diberi izin untuk mengakses perangkat HID, situs dapat
secara aktif menerima peristiwa koneksi dan pemutusan koneksi dengan memproses peristiwa "connect"
dan "disconnect"
.
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.
});
Mencabut akses ke perangkat HID
Situs dapat menghapus izin untuk mengakses perangkat HID yang tidak lagi
perlu dipertahankan dengan memanggil forget()
pada instance HIDDevice
. Misalnya, untuk aplikasi web pendidikan yang digunakan di komputer bersama dengan banyak
perangkat, akumulasi izin yang dibuat pengguna dalam jumlah besar akan memberikan pengalaman
pengguna yang buruk.
Memanggil forget()
pada satu instance HIDDevice
akan mencabut akses ke semua
antarmuka HID pada perangkat fisik yang sama.
// Voluntarily revoke access to this HID device.
await device.forget();
Karena forget()
tersedia di Chrome 100 atau yang lebih baru, periksa apakah fitur ini
didukung dengan hal berikut:
if ("hid" in navigator && "forget" in HIDDevice.prototype) {
// forget() is supported.
}
Tips Developer
Proses debug HID di Chrome mudah dilakukan dengan halaman internal, about://device-log
tempat Anda dapat melihat semua peristiwa terkait perangkat HID dan USB di satu tempat.
![Screenshot halaman internal untuk men-debug HID.](https://developer.chrome.com/static/docs/capabilities/hid/image/screenshot-the-internal-958992d62d73e.jpg?authuser=6&hl=id)
Lihat Penjelajah HID untuk membuang info perangkat HID ke format yang dapat dibaca manusia. Hal ini memetakan dari nilai penggunaan hingga nama untuk setiap penggunaan HID.
Pada sebagian besar sistem Linux, perangkat HID dipetakan dengan izin hanya baca secara
default. Agar Chrome dapat membuka perangkat HID, Anda perlu menambahkan aturan
udev baru. Buat file di /etc/udev/rules.d/50-yourdevicename.rules
dengan
konten berikut:
KERNEL=="hidraw*", ATTRS{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"
Pada baris di atas, [yourdevicevendor]
adalah 057e
jika perangkat Anda adalah Nintendo Switch
Joy-Con. ATTRS{idProduct}
juga dapat ditambahkan untuk aturan yang lebih spesifik. Pastikan user
Anda adalah anggota grup plugdev
. Kemudian, cukup
hubungkan kembali perangkat Anda.
Dukungan browser
WebHID API tersedia di semua platform desktop (ChromeOS, Linux, macOS, dan Windows) pada Chrome 89.
Demo
Beberapa demo WebHID tercantum di web.dev/hid-examples. Ayo lihat!
Keamanan dan privasi
Penulis spesifikasi telah mendesain dan menerapkan WebHID API menggunakan prinsip inti yang ditentukan dalam Mengontrol Akses ke Fitur Platform Web yang Canggih, termasuk kontrol pengguna, transparansi, dan ergonomi. Kemampuan untuk menggunakan API ini terutama dibatasi oleh model izin yang memberikan akses hanya ke satu perangkat HID pada satu waktu. Sebagai respons atas perintah pengguna, pengguna harus melakukan langkah aktif untuk memilih perangkat HID tertentu.
Untuk memahami konsekuensi keamanan, lihat bagian Pertimbangan Keamanan dan Privasi di spesifikasi WebHID.
Selain itu, Chrome juga memeriksa penggunaan setiap koleksi tingkat atas dan jika koleksi tingkat atas memiliki penggunaan yang dilindungi (misalnya, keyboard, mouse generik), maka situs tidak akan dapat mengirim dan menerima laporan apa pun yang ditentukan dalam koleksi tersebut. Daftar lengkap penggunaan yang dilindungi tersedia secara publik.
Perlu diketahui bahwa perangkat HID yang sensitif terhadap keamanan (seperti perangkat FIDO HID yang digunakan untuk autentikasi yang lebih kuat) juga diblokir di Chrome. Lihat file Daftar USB yang tidak diizinkan dan Daftar yang tidak diizinkan HID.
Masukan
Tim Chrome ingin mengetahui pendapat dan pengalaman Anda menggunakan WebHID API.
Beri tahu kami tentang desain API
Apakah ada sesuatu pada API yang tidak berfungsi seperti yang diharapkan? Atau apakah ada metode atau properti yang hilang yang Anda perlukan untuk menerapkan ide Anda?
Laporkan masalah spesifikasi di repo GitHub WebHID API atau tambahkan pendapat Anda ke masalah yang sudah ada.
Melaporkan masalah terkait penerapan
Apakah Anda menemukan bug pada implementasi Chrome? Atau apakah implementasinya berbeda dengan spesifikasi?
Lihat Cara melaporkan bug WebHID. Pastikan untuk menyertakan detail
sebanyak mungkin, memberikan petunjuk sederhana untuk mereproduksi bug, dan menyetel
Komponen ke Blink>HID
. Glitch berfungsi dengan baik untuk
berbagi repro dengan cepat dan mudah.
Tampilkan dukungan
Apakah Anda berencana menggunakan WebHID API? Dukungan publik Anda membantu tim Chrome memprioritaskan fitur dan menunjukkan kepada vendor browser lain betapa pentingnya mendukung mereka.
Kirim tweet ke @ChromiumDev menggunakan hashtag
#WebHID
dan beri tahu kami
di mana dan bagaimana Anda menggunakannya.
Link bermanfaat
- Spesifikasi
- Bug pelacakan
- Entri ChromeStatus.com
- Komponen Blink:
Blink>HID
Ucapan terima kasih
Terima kasih kepada Matt Reynolds dan Joe Medley atas ulasan mereka tentang artikel ini. Foto Nintendo Switch berwarna merah dan biru oleh Sara Kurfeß, serta foto komputer laptop hitam dan perak oleh Athul Cyriac Ajay di Unsplash.