WebHID API を使用すると、ウェブサイトで代替補助キーボードや珍しいゲームパッドにアクセスできます。
ヒューマン インターフェース デバイス(HID)のロングテールには、 新しすぎる、古すぎる、珍しい、キーボードや珍しいゲームパッド システムからアクセス可能なダウンロードします。WebHID API は、この問題を解決するため、 方法をいくつか見ていきましょう。
推奨されるユースケース
HID デバイスは、人間から入力を受け取る、または人間に出力を提供します。デバイスの例 キーボード、ポインティング デバイス(マウス、タッチスクリーンなど)、ゲームパッドが含まれます。 HID プロトコルにより、こうしたデバイスにパソコンでアクセスできるようになります。 接続することもできますウェブ プラットフォームが HID デバイスをサポートしている 大きな収益を得られます
一般的でない HID デバイスにアクセスできないのは、 は代替の補助キーボード(Elgato Stream Deck、Jabra など)に対応 ヘッドセット、X キーなど)、エキゾチックなゲームパッドのサポート。パソコン用に設計されたゲームパッド ゲームパッドの入力(ボタン、ジョイスティック、トリガー)と出力に HID を使用することが多い (LED、ランブル)残念ながら、ゲームパッドの入出力は ウェブブラウザが特定のデバイス用のカスタム ロジックを必要とする場合がよくあります。 このような状況は持続不可能であり、旧来の企業やカスタマー サービスのロングテール 保護します。また、ブラウザは動作の特性に依存します。 特定できます
用語
HID は、レポートとレポート記述子という 2 つの基本的な概念で構成されています。 レポートは、デバイスとソフトウェア クライアントの間で交換されるデータです。 レポート記述子は、デバイスで受信するデータの形式と意味を サポートします。
HID(ヒューマン インターフェース デバイス)は、デバイスから入力を受け取る、または 人間に出力を提供しますまた、HID プロトコルとも呼ばれる、HID プロトコルの標準規格です。 ホストとデバイス間の双方向通信は、ネットワーク間で通信が インストール手順を簡素化できます。HID プロトコルは、 それ以来、他の多くのプロトコルで実装され、 対応しています。
アプリケーションと HID デバイスは、次の 3 種類のレポートを通じてバイナリデータを交換します。
レポートの種類 | 説明 |
---|---|
入力レポート | デバイスからアプリに送信されるデータ(ボタンが押された場合など)。 |
出力レポート | アプリケーションからデバイスに送信されるデータ(キーボード バックライトをオンにするリクエストなど)。 |
機能レポート | どちらの方向にも送信できるデータです。形式はデバイスによって異なります。 |
レポート記述子は、 ダウンロードします構造は階層的で、レポートを個別のユーザーとしてグループ化できます。 含まれている場合は記述子の形式は次のとおりです。 使用されます。
HID 使用状況は、標準化された入力または出力を参照する数値です。 使用状況の値により、デバイスはデバイスの意図された用途と、 レポートの各フィールドの用途に使用します。たとえば、1 つは左側に定義され、 操作できます。使用状況は使用状況ページにも整理されており、 デバイスまたはレポートの大まかなカテゴリを示します。
WebHID API の使用
機能検出
WebHID API がサポートされているかどうかを確認するには、次のコマンドを使用します。
if ("hid" in navigator) {
// The WebHID API is supported.
}
HID 接続を開く
WebHID API は非同期に設計されているため、ウェブサイトの UI が ブロックします。HID データは受信される可能性があるため、これは重要です。 それを聞く手段が必要です。
HID 接続を開くには、まず HIDDevice
オブジェクトにアクセスします。そのためには
デバイスの選択を求めるメッセージが
navigator.hid.requestDevice()
、または navigator.hid.getDevices()
から選択してください
アクセスが許可されているデバイスのリストが返されます。
使用します。
navigator.hid.requestDevice()
関数は、次のような必須のオブジェクトを受け取ります。
フィルタを定義します。USB ベンダーに接続されたデバイスの照合に使用されます。
ID(vendorId
)、USB プロダクト ID(productId
)、使用状況ページ
値(usagePage
)、使用状況の値(usage
)。これらは
USB ID リポジトリと HID 使用状況の表のドキュメント。
この関数から返される複数の HIDDevice
オブジェクトは、複数の
同じ物理デバイス上の HID インターフェース。
// 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();
また、オプションの exclusionFilters
キーを使用して、
navigator.hid.requestDevice()
: ブラウザ選択ツールから一部のデバイスを除外します
たとえば 不具合のあることが判明している
// 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 }],
});
HIDDevice
オブジェクトには、デバイスの USB ベンダー ID と製品 ID が含まれます。
あります。その collections
属性は、階層構造で初期化されます。
デバイスのレポート形式に関する説明です。
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
}
HIDDevice
デバイスはデフォルトで「閉じた」状態として返されます。Pod の状態であり、
データを送受信できるようになる前に open()
を呼び出して開きます。
// Wait for the HID connection to open before sending/receiving data.
await device.open();
入力レポートを受け取る
HID 接続が確立されたら、受信入力を処理できます。
デバイスの "inputreport"
イベントをリッスンして、レポートを作成します。これらのイベント
HID データを DataView
オブジェクト(data
)として格納し、そのオブジェクトが属する HID デバイスを指定します。
を(device
)、入力レポートに関連付けられた 8 ビットのレポート ID
(reportId
)。
前の例の場合、以下のコードは、 Joy-Con Right デバイスでユーザーが押したボタン。 ぜひご自宅で試してみてください。
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]}.`);
});
出力レポートを送信する
出力レポートを HID デバイスに送信するには、そのデバイスに関連付けられた 8 ビットのレポート ID を
出力レポート(reportId
)とバイト数を BufferSource
(data
)として
device.sendReport()
。レポートが生成されると、返された Promise は解決されます。
送信しました。HID デバイスがレポート ID を使用しない場合は、reportId
を 0 に設定します。
以下の例は Joy-Con デバイスに適用し、その作成方法を示しています 出力レポートを使ってみましょう。
// 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));
機能レポートの送受信
機能レポートは、両方のタイプで送信できる唯一の HID データレポートです。 説明します。HID デバイスや HID アプリケーションで標準化されていない標準を交換できる HID データ。入力 / 出力レポートとは異なり、特徴レポートは受信または 定期的に送信されます。
<ph type="x-smartling-placeholder">機能レポートを HID デバイスに送信するには、関連付けられた 8 ビットのレポート ID を
特徴レポート(reportId
)とバイトを BufferSource
(data
)として
device.sendFeatureReport()
。レポートが生成されると、返された Promise は解決されます。
送信します。HID デバイスがレポート ID を使用しない場合は、reportId
を 0 に設定します。
以下の例では、特徴レポートの使い方と Apple キーボードバックライトデバイスをリクエストして デバイスを開けて点滅させます
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);
}
HID デバイスから機能レポートを受け取るには、8 ビットのレポート ID を渡します。
特徴レポート(reportId
)に関連付けられた
device.receiveFeatureReport()
。返された Promise は、
機能レポートのコンテンツを含む DataView
オブジェクト。HID が
デバイスでレポート ID が使用されていない場合は、reportId
を 0 に設定します。
// Request feature report.
const dataView = await device.receiveFeatureReport(/* reportId= */ 1);
// Read feature report contents with dataView.getInt8(), getUint8(), etc...
接続と切断のリッスン
HID デバイスへのアクセスが許可されている場合、ウェブサイトは
"connect"
をリッスンすることで、接続と切断のイベントをアクティブに受信する
と "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.
});
HID デバイスへのアクセス権を取り消す
ウェブサイトで、利用されなくなった HID デバイスにアクセスする権限をクリーンアップできる
HIDDevice
インスタンスの forget()
を呼び出して保持を検討している。対象
たとえば、多くのユーザーと共有のパソコンで使用される教育用ウェブ アプリケーションの場合、
蓄積されたアクセス許可が蓄積されてしまうと、
向上させることができます
1 つの HIDDevice
インスタンスで forget()
を呼び出すと、すべてのアクセス権が取り消されます
同じ物理デバイス上の HID インターフェースです
// Voluntarily revoke access to this HID device.
await device.forget();
forget()
は Chrome 100 以降で利用できるため、この機能に対応しているかどうかをご確認ください
以下でサポートされます。
if ("hid" in navigator && "forget" in HIDDevice.prototype) {
// forget() is supported.
}
開発のヒント
内部ページ about://device-log
を使用すると、Chrome の HID を簡単にデバッグできます。
HID および USB デバイスに関連するすべてのイベントを 1 か所で確認できます。
HID デバイスをダンプするには、HID エクスプローラを確認してください。 人が読める形式に変換されます。使用状況の値から各オブジェクトの名前に HID 使用状況。
ほとんどの Linux システムでは、HID デバイスは
あります。Chrome で HID デバイスを開けるようにするには、新しい udev コマンドを
ルールをご覧ください。/etc/udev/rules.d/50-yourdevicename.rules
にファイルを
次の内容が含まれます。
KERNEL=="hidraw*", ATTRS{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"
上記の行の [yourdevicevendor]
は、デバイスが Nintendo Switch の場合、057e
です。
Joy-Con などです。ATTRS{idProduct}
を追加して、より具体的な
適用できます。user
が plugdev
グループのメンバーであることを確認してください。次に、
デバイスを再接続してください。
ブラウザ サポート
WebHID API は、あらゆるデスクトップ プラットフォーム(ChromeOS、Linux、macOS、 (Chrome 89)でリリースされます。
デモ
一部の WebHID デモは web.dev/hid-examples に掲載されています。見てみよう!
セキュリティとプライバシー
仕様の作成者は、Core 強力なウェブ プラットフォーム機能へのアクセスの制御で定義されている原則 あらゆる側面に関与しています。この機能を API は主に、1 つのサービスにのみアクセスを許可する権限モデルによって 1 台につき 1 台までです。ユーザーのプロンプトに応じて、ユーザーは 選択します。
セキュリティのトレードオフについては、セキュリティとプライバシー (WebHID 仕様の考慮事項)セクションを参照してください。
さらに Chrome は、各トップレベル コレクションの使用状況を検査し、 最上位のコレクションに保護された使用法(汎用キーボード、マウスなど)がある場合、 そのウェブサイトで定義したレポートを送受信できなくなります あります保護されている用途の一覧については、公開されています。
セキュリティに影響を及ぼす HID デバイス(FIDO HID デバイスなど)は、 より強力な認証など)は、Chrome でもブロックされます。USB ブロックリストと HID ブロックリスト ファイル。
フィードバック
Chrome チームでは、 WebHID API
API 設計について教えてください
API に関して想定どおりに機能していないものはありますか?それとも アイデアを実装するために必要なメソッドやプロパティが足りませんか?
WebHID API の GitHub リポジトリで仕様に関する問題を報告するか、ご意見をお聞かせください 役立ちます
実装に関する問題を報告する
Chrome の実装にバグは見つかりましたか?それとも どうなるでしょうか
WebHID のバグを報告する方法をご確認ください。できるだけ多くの
バグを再現するための簡単な手順を提供し、さらに、バグを再現するための
コンポーネントを Blink>HID
に設定します。Glitch が適しているケース
簡単に再現できます。
サポートの気持ちを伝える
WebHID API を使用する予定はありますか?皆様の公開サポートは、Chrome を チームは機能の優先度を判断し、他のブラウザ ベンダーが サポートします。
ハッシュタグを使用して @ChromiumDev にツイートしてください
#WebHID
して、ご意見をお聞かせください
使用する場所と方法がわかります。
関連情報
- の仕様
- バグのトラッキング
- ChromeStatus.com のエントリ
- Blink コンポーネント:
Blink>HID
謝辞
この記事をレビューしてくれた Matt Reynolds と Joe Medley に感謝します。 Nintendo Switch の赤と青の写真(Sara Kurfe 取)と、黒と銀のノートパソコン コンピュータの写真、Athul Cyriac Ajay 氏、Unsplash より