असामान्य एचआईडी डिवाइसों से कनेक्ट करना

WebHID API की मदद से, वेबसाइटें अन्य सहायक कीबोर्ड और एक्सोटिक गेमपैड ऐक्सेस कर सकती हैं.

François Beaufort
François Beaufort

ह्यूमन इंटरफ़ेस डिवाइस (एचआईडी) की एक लंबी सूची है. जैसे, वैकल्पिक कीबोर्ड या एक्सोटिक गेमपैड. ये डिवाइस बहुत नए, बहुत पुराने या बहुत असामान्य होते हैं, इसलिए सिस्टम के डिवाइस ड्राइवर इन्हें ऐक्सेस नहीं कर पाते. WebHID API, JavaScript में डिवाइस के हिसाब से लॉजिक लागू करने का तरीका उपलब्ध कराकर, इस समस्या को हल करता है.

इस्तेमाल के सुझाए गए उदाहरण

एचआईडी डिवाइस, लोगों से इनपुट लेता है या उन्हें आउटपुट देता है. डिवाइसों के उदाहरणों में कीबोर्ड, पॉइंटिंग डिवाइस (माउस, टचस्क्रीन वगैरह), और गेमपैड शामिल हैं. एचआईडी प्रोटोकॉल की मदद से, ऑपरेटिंग सिस्टम ड्राइवर का इस्तेमाल करके, डेस्कटॉप कंप्यूटर पर इन डिवाइसों को ऐक्सेस किया जा सकता है. वेब प्लैटफ़ॉर्म, इन ड्राइवर के आधार पर एचआईडी डिवाइसों के साथ काम करता है.

असामान्य एचआईडी डिवाइसों को ऐक्सेस न कर पाना, खास तौर पर तब परेशानी का सबब बनता है, जब बात वैकल्पिक सहायक कीबोर्ड (जैसे, Elgato Stream Deck, Jabra हेडसेट, X-keys) और गेमपैड के असामान्य सपोर्ट की आती है. डेस्कटॉप के लिए डिज़ाइन किए गए गेमपैड, अक्सर गेमपैड इनपुट (बटन, जॉयस्टिक, ट्रिगर) और आउटपुट (एलईडी, रंबल) के लिए एचआईडी का इस्तेमाल करते हैं. माफ़ करें, गेमपैड के इनपुट और आउटपुट को अच्छी तरह से स्टैंडर्ड नहीं किया गया है. साथ ही, वेब ब्राउज़र को अक्सर कुछ खास डिवाइसों के लिए कस्टम लॉजिक की ज़रूरत होती है. ऐसा करना संभव नहीं है. इस वजह से, पुराने और असामान्य डिवाइसों के लिए, सहायता की सुविधा का स्तर खराब हो जाता है. इससे ब्राउज़र, कुछ डिवाइसों के व्यवहार में होने वाली गड़बड़ियों पर भी निर्भर हो जाता है.

शब्दावली

एचआईडी में दो बुनियादी कॉन्सेप्ट होते हैं: रिपोर्ट और रिपोर्ट डिस्क्रिप्टर. रिपोर्ट वह डेटा होता है जो किसी डिवाइस और सॉफ़्टवेयर क्लाइंट के बीच शेयर किया जाता है. रिपोर्ट डिस्क्रिप्टर, डिवाइस के साथ काम करने वाले डेटा के फ़ॉर्मैट और उसके मतलब के बारे में बताता है.

एचआईडी (ह्यूमन इंटरफ़ेस डिवाइस) एक तरह का डिवाइस है, जो लोगों से इनपुट लेता है या उन्हें आउटपुट देता है. यह एचआईडी प्रोटोकॉल भी है. यह प्रोटोकॉल, होस्ट और डिवाइस के बीच, दोनों तरफ़ से कम्यूनिकेशन के लिए एक स्टैंडर्ड है. इसे इंस्टॉलेशन की प्रोसेस को आसान बनाने के लिए डिज़ाइन किया गया है. एचआईडी प्रोटोकॉल को मूल रूप से यूएसबी डिवाइसों के लिए डिज़ाइन किया गया था. हालांकि, अब इसे कई अन्य प्रोटोकॉल के साथ भी इस्तेमाल किया जा सकता है. इनमें ब्लूटूथ भी शामिल है.

ऐप्लिकेशन और एचआईडी डिवाइस, तीन तरह की रिपोर्ट के ज़रिए बाइनरी डेटा का आदान-प्रदान करते हैं:

रिपोर्ट का टाइप ब्यौरा
इनपुट रिपोर्ट डिवाइस से ऐप्लिकेशन को भेजा जाने वाला डेटा. उदाहरण के लिए, कोई बटन दबाया गया.
आउटपुट रिपोर्ट ऐप्लिकेशन से डिवाइस पर भेजा गया डेटा. उदाहरण के लिए, कीबोर्ड की बैकलाइट चालू करने का अनुरोध.
सुविधाओं की रिपोर्ट वह डेटा जिसे दोनों दिशाओं में भेजा जा सकता है. यह फ़ॉर्मैट, डिवाइस के हिसाब से तय होता है.

रिपोर्ट डिस्क्रिप्टर, डिवाइस पर काम करने वाली रिपोर्ट के बाइनरी फ़ॉर्मैट के बारे में बताता है. इसका स्ट्रक्चर हैरारकी वाला होता है. साथ ही, टॉप-लेवल कलेक्शन में रिपोर्ट को अलग-अलग कलेक्शन के तौर पर ग्रुप किया जा सकता है. डिस्क्रिप्टर का फ़ॉर्मैट, एचआईडी स्पेसिफ़िकेशन से तय होता है.

एचआईडी का इस्तेमाल, एक संख्या होती है. यह स्टैंडर्ड इनपुट या आउटपुट को दिखाती है. इस्तेमाल की वैल्यू की मदद से, किसी डिवाइस की रिपोर्ट में डिवाइस के इस्तेमाल के मकसद और हर फ़ील्ड के मकसद के बारे में बताया जा सकता है. उदाहरण के लिए, माउस के बाएं बटन के लिए एक कोड तय किया गया है. इस्तेमाल को इस्तेमाल वाले पेजों में भी व्यवस्थित किया जाता है. इनसे डिवाइस या रिपोर्ट की हाई-लेवल कैटगरी का पता चलता है.

WebHID API का इस्तेमाल करना

फ़ीचर का पता लगाना

यह देखने के लिए कि WebHID API काम करता है या नहीं, इनका इस्तेमाल करें:

if ("hid" in navigator) {
  // The WebHID API is supported.
}

एचआईडी कनेक्शन खोलना

WebHID API, डिज़ाइन के हिसाब से असाइनक्रोनस है, ताकि वेबसाइट के यूज़र इंटरफ़ेस (यूआई) को इनपुट के इंतज़ार में ब्लॉक होने से रोका जा सके. यह ज़रूरी है, क्योंकि HID डेटा कभी भी मिल सकता है. इसलिए, इसे सुनने का तरीका होना चाहिए.

एचआईडी कनेक्शन खोलने के लिए, पहले HIDDevice ऑब्जेक्ट को ऐक्सेस करें. इसके लिए, navigator.hid.requestDevice() को कॉल करके उपयोगकर्ता को कोई डिवाइस चुनने के लिए कहा जा सकता है. इसके अलावा, navigator.hid.getDevices() से भी कोई डिवाइस चुना जा सकता है. इससे उन डिवाइसों की सूची दिखती है जिनका ऐक्सेस वेबसाइट को पहले दिया गया है.

navigator.hid.requestDevice() फ़ंक्शन में एक ज़रूरी ऑब्जेक्ट होता है, जो फ़िल्टर तय करता है. इनका इस्तेमाल, यूएसबी वेंडर आइडेंटिफ़ायर (vendorId), यूएसबी प्रॉडक्ट आइडेंटिफ़ायर (productId), इस्तेमाल की जानकारी वाले पेज की वैल्यू (usagePage), और इस्तेमाल की वैल्यू (usage) से कनेक्ट किए गए किसी भी डिवाइस से मैच करने के लिए किया जाता है. इन्हें यूएसबी आईडी रिपॉज़िटरी और एचआईडी के इस्तेमाल की जानकारी वाली टेबल के दस्तावेज़ से पाया जा सकता है.

इस फ़ंक्शन से मिले कई 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();
किसी वेबसाइट पर एचआईडी डिवाइस के प्रॉम्प्ट का स्क्रीनशॉट.
Nintendo Switch Joy-Con चुनने के लिए, उपयोगकर्ता को दिया जाने वाला प्रॉम्प्ट.

navigator.hid.requestDevice() में मौजूद exclusionFilters बटन का इस्तेमाल करके भी, ब्राउज़र पिकर से कुछ डिवाइसों को हटाया जा सकता है. उदाहरण के लिए, ऐसे डिवाइस जिनमें ब्राउज़र ठीक से काम नहीं कर रहा है.

// 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 ऑब्जेक्ट में, डिवाइस की पहचान करने के लिए यूएसबी वेंडर और प्रॉडक्ट आइडेंटिफ़ायर होते हैं. इसका 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 डिवाइसों को डिफ़ॉल्ट रूप से "बंद" स्थिति में लौटाया जाता है. डेटा भेजने या पाने से पहले, open() को कॉल करके उन्हें खोलना ज़रूरी है.

// Wait for the HID connection to open before sending/receiving data.
await device.open();

इनपुट रिपोर्ट पाना

एचआईडी कनेक्शन बन जाने के बाद, डिवाइस से "inputreport" इवेंट सुनकर, इनपुट की आने वाली रिपोर्ट मैनेज की जा सकती हैं. उन इवेंट में, एचआईडी डेटा को DataView ऑब्जेक्ट (data) के तौर पर शामिल किया जाता है. साथ ही, उस एचआईडी डिवाइस (device) और इनपुट रिपोर्ट (reportId) से जुड़ा 8-बिट रिपोर्ट आईडी भी शामिल होता है.

लाल और नीले रंग के Nintendo Switch की फ़ोटो.
Nintendo Switch Joy-Con डिवाइसों पर.

पिछले उदाहरण के आधार पर, नीचे दिए गए कोड से पता चलता है कि उपयोगकर्ता ने 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]}.`);
});

आउटपुट रिपोर्ट भेजना

किसी एचआईडी डिवाइस पर आउटपुट रिपोर्ट भेजने के लिए, आउटपुट रिपोर्ट (reportId) से जुड़ा 8-बिट रिपोर्ट आईडी और बाइट को BufferSource (data) के तौर पर device.sendReport() पर पास करें. रिपोर्ट भेजे जाने के बाद, रिटर्न किया गया प्रॉमिस रिज़ॉल्व हो जाता है. अगर एचआईडी डिवाइस, रिपोर्ट आईडी का इस्तेमाल नहीं करता है, तो 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));

सुविधा से जुड़ी रिपोर्ट भेजना और पाना

सुविधा रिपोर्ट, एचआईडी डेटा रिपोर्ट का एक ऐसा टाइप है जो दोनों दिशाओं में भेजी जा सकती है. इनकी मदद से, एचआईडी डिवाइसों और ऐप्लिकेशन के बीच, स्टैंडर्ड के मुताबिक न होने वाला एचआईडी डेटा शेयर किया जा सकता है. इनपुट और आउटपुट रिपोर्ट के उलट, ऐप्लिकेशन नियमित तौर पर सुविधा रिपोर्ट को न तो भेजता है और न ही पाता है.

ब्लैक और सिल्वर रंग के लैपटॉप कंप्यूटर की फ़ोटो.
लैपटॉप कीबोर्ड

किसी एचआईडी डिवाइस पर सुविधा की रिपोर्ट भेजने के लिए, सुविधा की रिपोर्ट (reportId) से जुड़ा 8-बिट रिपोर्ट आईडी और बाइट को BufferSource (data) के तौर पर device.sendFeatureReport() पर पास करें. रिपोर्ट भेजे जाने के बाद, रिटर्न किया गया प्रॉमिस रिज़ॉल्व हो जाता है. अगर एचआईडी डिवाइस, रिपोर्ट आईडी का इस्तेमाल नहीं करता है, तो 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);
}

किसी एचआईडी डिवाइस से सुविधाओं की रिपोर्ट पाने के लिए, सुविधाओं की रिपोर्ट (reportId) से जुड़ा 8-बिट रिपोर्ट आईडी, device.receiveFeatureReport() को भेजें. रिटर्न किया गया प्रॉमिस, DataView ऑब्जेक्ट के साथ रिज़ॉल्व होता है. इसमें सुविधा की रिपोर्ट का कॉन्टेंट होता है. अगर एचआईडी डिवाइस, रिपोर्ट आईडी का इस्तेमाल नहीं करता है, तो reportId को 0 पर सेट करें.

// Request feature report.
const dataView = await device.receiveFeatureReport(/* reportId= */ 1);

// Read feature report contents with dataView.getInt8(), getUint8(), etc...

कनेक्ट और डिसकनेक्ट होने की जानकारी सुनना

जब वेबसाइट को एचआईडी डिवाइस को ऐक्सेस करने की अनुमति मिल जाती है, तो वह "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.
});

किसी एचआईडी डिवाइस का ऐक्सेस रद्द करना

वेबसाइट, HIDDevice इंस्टेंस पर forget() को कॉल करके, किसी ऐसे एचआईडी डिवाइस को ऐक्सेस करने की अनुमतियों को हटा सकती है जिसे अब उसे ऐक्सेस नहीं करना है. उदाहरण के लिए, कई डिवाइसों के साथ शेयर किए गए कंप्यूटर पर इस्तेमाल किए जाने वाले किसी शिक्षा से जुड़े वेब ऐप्लिकेशन के लिए, उपयोगकर्ता से मिली अनुमतियों की बड़ी संख्या से उपयोगकर्ता अनुभव खराब हो जाता है.

किसी एक HIDDevice इंस्टेंस पर forget() को कॉल करने से, उसी फ़िज़िकल डिवाइस पर मौजूद सभी एचआईडी इंटरफ़ेस का ऐक्सेस रद्द हो जाएगा.

// Voluntarily revoke access to this HID device.
await device.forget();

forget(), Chrome 100 या उसके बाद के वर्शन में उपलब्ध है. इसलिए, देखें कि यह सुविधा इनके साथ काम करती है या नहीं:

if ("hid" in navigator && "forget" in HIDDevice.prototype) {
  // forget() is supported.
}

डेवलपर के लिए सलाह

Chrome में एचआईडी को डीबग करना आसान है. इसके लिए, इंटरनल पेज about://device-log का इस्तेमाल करें. यहां आपको एचआईडी और यूएसबी डिवाइस से जुड़े सभी इवेंट एक ही जगह पर दिखेंगे.

HID को डीबग करने के लिए, इंटरनल पेज का स्क्रीनशॉट.
एचआईडी को डीबग करने के लिए, Chrome का इंटरनल पेज.

एचआईडी डिवाइस की जानकारी को, मनुष्य के पढ़ने लायक फ़ॉर्मैट में डंप करने के लिए, एचआईडी एक्सप्लोरर देखें. यह हर HID इस्तेमाल के लिए, इस्तेमाल की वैल्यू से नामों पर मैप करता है.

ज़्यादातर Linux सिस्टम पर, एचआईडी डिवाइसों को डिफ़ॉल्ट रूप से सिर्फ़ पढ़ने की अनुमतियों के साथ मैप किया जाता है. Chrome को एचआईडी डिवाइस खोलने की अनुमति देने के लिए, आपको एक नया udev rule जोड़ना होगा. /etc/udev/rules.d/50-yourdevicename.rules पर, यहां दिए गए कॉन्टेंट वाली फ़ाइल बनाएं:

KERNEL=="hidraw*", ATTRS{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"

ऊपर दी गई लाइन में, [yourdevicevendor] 057e है. उदाहरण के लिए, अगर आपका डिवाइस Nintendo Switch Joy-Con है. ज़्यादा सटीक नियम के लिए, ATTRS{idProduct} को भी जोड़ा जा सकता है. पक्का करें कि आपका user, plugdev ग्रुप का सदस्य हो. इसके बाद, अपने डिवाइस को फिर से कनेक्ट करें.

ब्राउज़र समर्थन

WebHID API, Chrome 89 में सभी डेस्कटॉप प्लैटफ़ॉर्म (ChromeOS, Linux, macOS, और Windows) पर उपलब्ध है.

डेमो

WebHID के कुछ डेमो web.dev/hid-examples पर दिए गए हैं. इस पर एक नज़र डालें!

सुरक्षा और निजता

स्पेसिफ़िकेशन के लेखकों ने वेब प्लैटफ़ॉर्म की बेहतर सुविधाओं के ऐक्सेस को कंट्रोल करना में बताए गए मुख्य सिद्धांतों का इस्तेमाल करके, WebHID API को डिज़ाइन और लागू किया है. इन सिद्धांतों में, उपयोगकर्ता कंट्रोल, पारदर्शिता, और काम करने के तरीके शामिल हैं. इस एपीआई का इस्तेमाल करने की अनुमति, मुख्य रूप से अनुमति मॉडल के हिसाब से दी जाती है. यह मॉडल, एक समय में सिर्फ़ एक एचआईडी डिवाइस का ऐक्सेस देता है. उपयोगकर्ता के प्रॉम्प्ट के जवाब में, उपयोगकर्ता को किसी खास एचआईडी डिवाइस को चुनने के लिए, सक्रिय कार्रवाई करनी होगी.

सुरक्षा से जुड़े समझौते को समझने के लिए, WebHID स्पेसिफ़िकेशन का सुरक्षा और निजता से जुड़ी बातें सेक्शन देखें.

इसके अलावा, Chrome हर टॉप-लेवल कलेक्शन के इस्तेमाल की जांच करता है. अगर किसी टॉप-लेवल कलेक्शन का इस्तेमाल सुरक्षित है, जैसे कि सामान्य कीबोर्ड, माउस वगैरह, तो कोई वेबसाइट उस कलेक्शन में बताई गई किसी भी रिपोर्ट को भेज और पा नहीं सकती. सुरक्षित इस्तेमाल की पूरी सूची सार्वजनिक तौर पर उपलब्ध है.

ध्यान दें कि Chrome में सुरक्षा से जुड़े एचआईडी डिवाइस भी ब्लॉक किए जाते हैं. जैसे, पुष्टि करने के बेहतर तरीके के लिए इस्तेमाल किए जाने वाले एफ़आईडीओ एचआईडी डिवाइस. यूएसबी ब्लॉकलिस्ट और एचआईडी ब्लॉकलिस्ट फ़ाइलें देखें.

सुझाव/राय दें या शिकायत करें

Chrome की टीम को WebHID API के बारे में आपके विचार और अनुभव जानने में दिलचस्पी होगी.

हमें एपीआई के डिज़ाइन के बारे में बताएं

क्या एपीआई में कोई ऐसी चीज़ है जो उम्मीद के मुताबिक काम नहीं करती? क्या आपके आइडिया को लागू करने के लिए, कोई ऐसा तरीका या प्रॉपर्टी मौजूद नहीं है?

WebHID API के GitHub रिपॉज़िटरी पर, खास जानकारी से जुड़ी कोई समस्या दर्ज करें या किसी मौजूदा समस्या के बारे में अपनी राय दें.

लागू करने से जुड़ी समस्या की शिकायत करना

क्या आपको Chrome में इस सुविधा को लागू करने में कोई गड़बड़ी मिली? या क्या इसे लागू करने का तरीका, स्पेसिफ़िकेशन से अलग है?

WebHID से जुड़ी गड़बड़ियों की शिकायत करने का तरीका जानें. ज़्यादा से ज़्यादा जानकारी शामिल करें. गड़बड़ी को दोहराने के लिए आसान निर्देश दें. साथ ही, कॉम्पोनेंट को Blink>HID पर सेट करें. Glitch, समस्या को जल्दी और आसानी से शेयर करने के लिए बहुत अच्छा है.

क्रिएटर के लिए अपना सपोर्ट दिखाना

क्या आपको WebHID API का इस्तेमाल करना है? सार्वजनिक तौर पर सहायता पाने से, Chrome टीम को सुविधाओं को प्राथमिकता देने में मदद मिलती है. साथ ही, इससे ब्राउज़र के अन्य वेंडर को यह पता चलता है कि इन सुविधाओं को उपलब्ध कराना कितना ज़रूरी है.

#WebHID हैशटैग का इस्तेमाल करके, @ChromiumDev को ट्वीट करें. साथ ही, हमें बताएं कि इसका इस्तेमाल कहां और कैसे किया जा रहा है.

मदद के लिए लिंक

आभार

इस लेख की समीक्षा करने के लिए, मैट रेनॉल्ड्स और जो मेडली का धन्यवाद. Unsplash पर Sara Kurfeß की ओर से ली गई, लाल और नीले रंग के Nintendo Switch की फ़ोटो. साथ ही, Athul Cyriac Ajay की ओर से ली गई, काले और सिल्वर रंग के लैपटॉप की फ़ोटो.