WebHID API memungkinkan situs mengakses keyboard tambahan dan gamepad eksotis alternatif.
Terdapat bermacam-macam perangkat antarmuka manusia (HID), seperti perangkat {i>keyboard<i} atau {i>gamepad<i} yang eksotis, yang terlalu baru, terlalu tua, atau terlalu jarang untuk dapat diakses oleh sistem {i>driver <i}perangkat. WebHID API mengatasi masalah ini dengan menyediakan untuk menerapkan logika khusus perangkat di JavaScript.
Kasus penggunaan yang disarankan
Perangkat HID mengambil input dari atau memberikan output ke manusia. Contoh perangkat termasuk {i>keyboard<i}, perangkat penunjuk (tikus, layar sentuh, dll.), dan {i>gamepad<i}. Protokol HID memungkinkan akses perangkat ini di desktop komputer yang menggunakan {i>driver<i} sistem operasi. Platform web mendukung perangkat HID dengan mengandalkan {i>driver-<i}nya.
Ketidakmampuan untuk mengakses perangkat HID yang tidak biasa akan sangat menyakitkan ketika menggunakan keyboard tambahan alternatif (mis. Elgato Stream Deck, Jabra headset, tombol X) dan dukungan gamepad eksotis. Gamepad yang dirancang untuk desktop sering menggunakan HID untuk input gamepad (tombol, joystick, pemicu) dan output (LED, gemuruh). Sayangnya, input dan output gamepad tidak berfungsi dengan baik {i>standard<i} dan {i>browser<i} web sering kali memerlukan logika khusus untuk perangkat tertentu. Hal ini tidak berkelanjutan dan mengakibatkan dukungan yang buruk bagi kelompok yang lebih tua dan perangkat yang tidak umum. Hal ini juga menyebabkan browser bergantung pada kebiasaan perangkat tertentu.
Terminologi
HID terdiri dari dua konsep dasar: laporan dan deskripsi laporan. Laporan adalah data yang dipertukarkan antara perangkat dan klien perangkat lunak. Deskriptor laporan menjelaskan format dan arti data yang digunakan perangkat didukung.
HID (Human Interface Device) adalah jenis perangkat yang menerima input dari menyediakan {i>output<i} ke manusia. Ini juga mengacu pada protokol HID, sebuah standar untuk komunikasi dua arah antara {i>host<i} dan perangkat yang dirancang untuk menyederhanakan prosedur instalasi. Protokol HID awalnya dikembangkan untuk perangkat USB, tetapi sejak itu diimplementasikan ke banyak protokol lainnya, 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 dalam salah satu arah. Formatnya spesifik per perangkat. |
Deskriptor laporan menjelaskan format biner laporan yang didukung oleh perangkat seluler. Strukturnya hierarkis dan dapat mengelompokkan laporan bersama sebagai koleksi dalam koleksi tingkat atas. Format deskriptor adalah yang ditentukan oleh spesifikasi HID.
Penggunaan HID adalah nilai numerik yang mengacu pada input atau {i>output<i} standar. Nilai penggunaan memungkinkan perangkat mendeskripsikan penggunaan perangkat yang dimaksudkan dan kegunaan setiap kolom dalam laporannya. Misalnya, satu ditentukan untuk fungsi kiri tombol mouse. Penggunaan juga diatur ke dalam halaman penggunaan, yang menyediakan 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 agar asinkron untuk mencegah UI situs memblokir ketika menunggu input. Hal ini penting karena data HID dapat diterima kapan saja, sehingga memerlukan cara untuk mendengarkannya.
Untuk membuka koneksi HID, akses objek HIDDevice
terlebih dahulu. Untuk itu, Anda dapat
meminta pengguna untuk memilih perangkat dengan memanggil
navigator.hid.requestDevice()
, atau pilih satu dari navigator.hid.getDevices()
yang menampilkan daftar perangkat
yang telah diberi akses ke {i>website<i}
seperti yang telah dibahas sebelumnya.
Fungsi navigator.hid.requestDevice()
mengambil objek wajib yang
menentukan filter. Alamat ini digunakan untuk mencocokkan
perangkat apa pun yang terhubung dengan vendor USB
ID (vendorId
), kode produk USB (productId
), halaman penggunaan
nilai (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 di 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();
Anda juga dapat menggunakan kunci exclusionFilters
opsional di
navigator.hid.requestDevice()
untuk mengecualikan beberapa perangkat dari alat pilih browser
yang diketahui mengalami
malfungsi.
// 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 vendor USB dan kode produk untuk perangkat
identifikasi. Atribut collections
diinisialisasi dengan hierarki
deskripsi 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 mode "tertutup" negara bagian 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 dibuat, Anda dapat menangani input yang masuk
laporan dengan memproses peristiwa "inputreport"
dari perangkat. Acara tersebut
berisi data HID sebagai objek DataView
(data
), perangkat HID yang memilikinya
ke (device
), dan ID laporan 8-bit yang terkait dengan laporan input
(reportId
).
Melanjutkan dengan contoh sebelumnya, kode di bawah ini menunjukkan cara mendeteksi tombol mana yang ditekan pengguna pada perangkat Joy-Con Right sehingga Anda dapat semoga saja 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
) untuk
device.sendReport()
. Promise yang ditampilkan akan selesai setelah laporan
terkirim. Jika perangkat HID tidak menggunakan ID laporan, tetapkan reportId
ke 0.
Contoh di bawah berlaku untuk perangkat Joy-Con dan menunjukkan cara membuatnya menemukan 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 berpindah di petunjuk arah. Keduanya memungkinkan perangkat dan aplikasi HID bertukar data Data HID. Tidak seperti laporan input dan output, laporan fitur tidak diterima atau yang dikirim oleh aplikasi secara berkala.
Untuk mengirim laporan fitur ke perangkat HID, teruskan ID laporan 8-bit yang terkait
dengan laporan fitur (reportId
) dan byte sebagai BufferSource
(data
) untuk
device.sendFeatureReport()
. Promise yang ditampilkan akan selesai setelah laporan
terkirim. Jika perangkat HID tidak menggunakan ID laporan, tetapkan reportId
ke 0.
Contoh di bawah menggambarkan penggunaan laporan fitur dengan menunjukkan kepada Anda 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 dikaitkan dengan laporan fitur (reportId
) untuk
device.receiveFeatureReport()
. Promise yang ditampilkan akan di-resolve dengan
Objek DataView
yang berisi konten laporan fitur. Jika HID
perangkat 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
Ketika situs web telah diberikan izin untuk
mengakses perangkat HID, maka hal itu dapat
menerima peristiwa koneksi dan pemutusan koneksi secara aktif dengan memproses "connect"
dan "disconnect"
peristiwa.
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 tersedia
yang tertarik untuk mempertahankan dengan memanggil forget()
pada instance HIDDevice
. Sebagai
misalnya, untuk aplikasi web pendidikan yang digunakan
di komputer bersama dengan banyak
perangkat, sejumlah besar akumulasi izin
yang dibuat pengguna akan menciptakan
{i>user experience<i}.
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 tersedia
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.
Lihat penjelajah HID untuk membuang perangkat HID informasi ke dalam format yang dapat dibaca manusia. Diagram ini memetakan dari nilai penggunaan ke nama untuk masing-masing Penggunaan HID.
Pada sebagian besar sistem Linux, perangkat HID dipetakan dengan izin hanya baca berdasarkan
secara default. Untuk mengizinkan Chrome membuka perangkat HID, Anda perlu menambahkan udev baru
aturan. 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 misalnya. ATTRS{idProduct}
juga dapat ditambahkan untuk
aturan. Pastikan user
Anda adalah anggota grup plugdev
. Lalu, cukup
menghubungkan kembali perangkat Anda.
Dukungan browser
WebHID API tersedia di semua platform desktop (ChromeOS, Linux, macOS, dan Windows) di Chrome 89.
Demo
Beberapa demo WebHID tercantum di web.dev/hid-examples. Lihatlah!
Keamanan dan privasi
Penulis spesifikasi telah merancang dan mengimplementasikan WebHID API menggunakan yang ditentukan dalam Mengontrol Akses ke Fitur Platform Web yang Canggih, termasuk kontrol pengguna, transparansi, dan ergonomi. Kemampuan menggunakan API terutama dilindungi oleh model izin yang memberikan akses hanya ke satu perangkat HID pada satu waktu. Sebagai respons terhadap perintah pengguna, pengguna harus mengaktifkan langkah-langkah untuk memilih perangkat HID tertentu.
Untuk memahami konsekuensi dari segi keamanan, lihat Keamanan dan Privasi Pertimbangan dalam spesifikasi WebHID.
Selain itu, Chrome memeriksa penggunaan setiap koleksi tingkat atas dan apakah koleksi level atas memiliki penggunaan yang dilindungi (mis. keyboard, mouse generik), kemudian situs web tidak akan dapat mengirim dan menerima laporan apa pun yang ditentukan di pengumpulan data. Daftar lengkap penggunaan yang dilindungi tersedia untuk umum.
Perhatikan bahwa perangkat HID yang sensitif terhadap keamanan (seperti perangkat HID FIDO yang digunakan untuk autentikasi yang lebih kuat) juga diblokir di Chrome. Lihat Daftar yang tidak diizinkan USB dan File daftar yang tidak diizinkan HID.
Masukan
Tim Chrome ingin mengetahui pendapat dan pengalaman Anda dengan WebHID API.
Beri tahu kami tentang desain API
Apakah ada sesuatu terkait API yang tidak berfungsi seperti yang diharapkan? Atau apakah ada kehilangan metode atau properti yang diperlukan untuk mengimplementasikan ide?
Ajukan masalah spesifikasi di repo GitHub WebHID API atau tambahkan pendapat Anda terhadap masalah yang sudah ada.
Laporkan masalah terkait penerapan
Apakah Anda menemukan bug pada implementasi Chrome? Ataukah implementasi berbeda dengan spesifikasi?
Lihat Cara melaporkan bug WebHID. Pastikan untuk menyertakan sebanyak mungkin
sedetail mungkin, berikan petunjuk sederhana
untuk mereproduksi {i>bug<i}, dan
Komponen ditetapkan ke Blink>HID
. Glitch sangat cocok untuk
berbagi repro yang
cepat dan mudah.
Tunjukkan dukungan
Anda berencana menggunakan WebHID API? Dukungan publik Anda membantu Chrome tim memprioritaskan fitur dan menunjukkan kepada vendor browser lain betapa pentingnya untuk 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 Kedipan:
Blink>HID
Ucapan terima kasih
Terima kasih kepada Matt Reynolds dan Joe Medley atas ulasan mereka terkait artikel ini. Foto Nintendo Switch merah dan biru oleh Sara Kurfeß, dan laptop hitam dan perak foto komputer oleh Athul Cyriac Ajay di Unsplash.