WebHID API

커뮤니티 그룹 초안 보고서

최신 발행 버전:
없음
최신 에디터 초안:
https://wicg.github.io/webhid/
에디터:
Matt Reynolds (Google)
피드백:
GitHub WICG/webhid (풀 리퀘스트, 이슈 등록, 오픈 이슈)

개요

본 문서는 Human Interface Device (HID) 프로토콜을 지원하는 장치에 접근할 수 있도록 하는 API에 대해 설명합니다.

이 문서의 상태

이 명세는 Web Platform Incubator Community Group에서 발행하였습니다. W3C 표준이 아니며, W3C 표준 트랙에도 포함되어 있지 않습니다. W3C Community Contributor License Agreement (CLA)에 따라 일부 옵트아웃이 제한적으로 가능하며, 추가 조건이 적용될 수 있습니다. W3C 커뮤니티 및 비즈니스 그룹에 대해 더 알아보세요.

본 명세에 대한 논의는 GitHub Issues를 우선적으로 이용해 주세요.

1. 소개

이 절은 비규범적(참고용)입니다.

HID(Human Interface Device, 휴먼 인터페이스 디바이스)는 사람에게 입력을 받거나 출력을 제공하는 장치 유형입니다. 또한 HID 프로토콜은 호스트와 장치 간의 양방향 통신을 표준화하여 설치 과정을 단순화하기 위해 설계된 표준을 의미하기도 합니다. HID 프로토콜은 원래 USB 기기용으로 개발되었으나, 이후 Bluetooth를 비롯한 다양한 프로토콜에서도 구현되었습니다.

웹 플랫폼은 이미 다양한 HID 장치의 입력을 지원합니다. 키보드, 포인팅 장치, 게임패드는 모두 일반적으로 HID 프로토콜로 구현됩니다. 그러나 이러한 지원은 운영 체제의 HID 드라이버가 HID 입력을 고수준 입력 API로 변환하는 데 의존합니다. 호스트의 HID 드라이버로 잘 지원되지 않는 장치는 웹페이지에서 접근할 수 없는 경우가 많습니다. 마찬가지로, 대부분의 장치에서 호스트의 HID 드라이버가 지원하지 않는 출력도 접근할 수 없습니다.

관련 문서로 설명서(Explainer)도 참고하세요.

2. 적용 동기

이 절은 비규범적(참고용)입니다.

2.1 특수 장치

가장 일반적인 HID 입력 장치 유형들은 기존 고수준 입력 API를 통해 이미 웹 플랫폼에서 잘 지원됩니다. 예를 들어, 마우스 입력은 PointerEvent로, 키보드 입력은 KeyboardEvent로 접근할 수 있습니다. 이러한 장치의 입력은 호스트의 기본 HID 드라이버를 사용하여 처리되며, 일반적으로 장치별 드라이버나 별도의 설정 없이 정상 작동합니다. WebHID는 이미 고수준 입력 API로 잘 지원되는 이러한 장치들을 위한 것이 아닙니다.

일부 HID 장치에 대해서는 웹 플랫폼이 장치의 일부 기능만 지원하고 다른 기능의 접근은 제한될 수 있습니다. 예를 들어, [GAMEPAD]는 대부분의 게임 컨트롤러의 입력 기능만 지원하며, LED 표시등이나 오디오와 같은 비교적 드문 기능은 지원하지 않습니다. 이런 기능들은 호스트 API에서 잘 지원되지 않으며, 사용자 에이전트에서 직접 지원을 추가하면 큰 복잡성이 초래될 수 있습니다. WebHID는 고수준 API가 완전한 기능을 제공하지 못할 경우, 애플리케이션에 대안이 될 수 있습니다.

많은 HID 장치는 어떤 웹 플랫폼 API로도 지원받지 못합니다. HID 명세에서는 가상현실 컨트롤러, 플라이트 시뮬레이터, 의료 장비 등 HID로 구현 가능하지만 지원되지 않는 매우 다양한 장치들을 기술하고 있습니다. WebHID를 통해서는 별도의 드라이버나 사용자 에이전트 수정 없이도 이러한 장치들을 사용할 수 있습니다.

2.2 프로토타이핑, 취미 및 교육용 장치

HID는 호스트마다 개별 드라이버가 필요하지 않고 호스트의 범용 HID 드라이버를 사용할 수 있기 때문에 프로토타이핑과 취미용 애플리케이션에 매력적입니다. 단순화된 설치 절차는 또한 교사가 각 호스트의 시스템 설정을 변경하지 않고도 학생들이 수업 시간에 장치를 손쉽게 사용할 수 있게 해 줍니다. 웹 플랫폼을 통해 HID 장치 접근을 제공하면 특별 앱이나 드라이버가 필요한 장치도 설치 요구사항을 더 줄일 수 있습니다.

3. 보안 및 개인정보 보호 고려사항

이 절은 비규범적(참고용)입니다.

3.1 장치 접근 권한 남용

HID 주변기기는 페이지에서 사용자의 명시적 동의 없이 접근해서는 안 되는 강력한 기능을 제공할 수 있습니다. 예를 들어, HID 주변기기는 환경 정보를 수집하는 센서를 탑재할 수 있습니다. 장치에 공개되거나 덮어써서는 안 되는 민감한 정보가 저장되어 있을 수 있습니다. 많은 장치는 펌웨어를 업그레이드할 수 있는 기능을 제공합니다. 운영 체제는 일반적으로 응용 프로그램의 HID 장치 접근을 제한하지 않기 때문에, 이러한 접근이 남용되면 장치가 손상되거나 장치에 저장된 데이터가 파손될 위험이 있습니다.

어떤 경우에는 장치가 페이지에서 완전히 접근할 수 없어야 하는 기능을 제공할 수 있습니다. 특정 장치는 vendor IDproduct ID로 식별하여, 열거 과정에서 해당 장치를 숨길 수 있습니다. 리포트 디스크립터는 장치가 스스로 지원 기능을 기술할 수 있도록 하며, 이 정보는 미리 알 수 없는 경우에도 특정 장치 유형 전체를 차단하는 데 사용될 수 있습니다. 예를 들어, 리포트 디스크립터 안의 HID usage 값을 검사하여, 키보드와 같은 기기는 최상위 컬렉션에 해당하는 HID usage가 포함되어 있다면 접근을 거부할 수 있습니다.

남용 방지를 위해서는, 사용자가 명시적으로 접근을 허용하기 전까지 페이지에서 장치 사용을 금지해야 합니다. 페이지는 먼저 접근을 요청해야 하며, 사용자가 기기 선택 대화 상자에서 장치를 선택한 경우에만 접근이 허용됩니다. 접근이 허용된 경우 장치가 사용 중임을 알리는 표식이 표시됩니다.

3.2 장치 공격

HID 프로토콜은 매우 유연해서, 이 유연성을 활용한 다양한 장치가 존재합니다. 그 결과, 장치에 접근할 수 있으면 악성 페이지가 실제 장치에 피해를 줄 수 있는 다양한 가능성이 생깁니다. HID 주변기기에서 커스텀 HID 리포트를 통해 펌웨어 업데이트가 가능한 경우도 많습니다. 제조사는 펌웨어 업그레이드가 정품 이진 파일임을 검증하도록 설계하고, 다운그레이드로 인해 보안성이 저하되지 않도록 보호해야 합니다. 신뢰할 수 없는 업그레이드를 허용하면 장치에 신규 기능이 추가되거나 전혀 다른 기기로 가장하도록 만들 수 있습니다.

예상 범위를 벗어난 입력이 제공되면 손상될 수 있는 장치도 있습니다. 예를 들어 게임패드의 진동 기능(rumble)은 페이지가 유효하지 않은 진동 명령을 보낼 경우 손상될 수 있습니다.

대체로 이러한 공격은 장치에 따라 다르므로, API 차원에서 방지할 수 없습니다.

3.3 호스트 공격

악성 페이지가 장치에 접근하면, 경우에 따라 이 접근 권한을 이용해 호스트를 공격할 수도 있습니다. 특히 장치가 신뢰된 입력 이벤트를 생성할 수 있는지 여부가 중요한 문제입니다. 이런 이벤트는 사용자 의도를 대변하고, 더 강력한 웹 플랫폼 기능에 접근하는데 사용될 수 있습니다.

마우스와 키보드는 일반적으로 HID 주변기기로 구현되어 있으며, 신뢰된 입력을 생성할 수도 있습니다. HID 키보드나 마우스에는 시퀀스를 저장하여 나중에 동작을 재생할 수 있도록 하는 프로그래머블 매크로와 같은 고급 기능이 있을 수 있습니다. 제조사는 악성 앱이 예상치 못한 입력 시퀀스으로 장치를 재프로그램하지 못하도록, 매크로 재생이 사용자의 명시적 동의 없이 실행되지 않도록 신중하게 기능을 설계해야 합니다.

3.4 대응 방안

보안 및 개인정보 보호 위험을 줄이기 위해, 사용자가 장치 접근을 요청할 때 반드시 선택 대화상자가 표시되는 플로우를 구현할 것을 권장합니다. 페이지가 HID 장치 접근을 요청하면 사용자 에이전트는 페이지가 장치 접근을 요청함을 알리고, 현재 연결되어 있는 HID 장치 목록을 보여주며, 사용자가 페이지에 노출할 장치를 선택할 것을 요구하는 대화상자를 보여주어야 합니다. 실수로 잘못 클릭할 가능성을 줄이기 위해 대화상자는 한 번의 상호작용으로 장치 목록에서 장치를 선택하고, 두 번째 상호작용으로 선택을 확정 및 대화상자를 닫도록 설계해야 합니다.

4. Navigator 인터페이스 확장

WebIDL[SecureContext] partial interface Navigator {
    [SameObject] readonly attribute HID hid;
};

4.1 hid 속성

hid 속성을 get할 때마다 항상 동일한 HID 객체 인스턴스를 반환합니다.

5. WorkerNavigator 인터페이스 확장

WebIDL[Exposed=(DedicatedWorker,ServiceWorker), SecureContext]
partial interface WorkerNavigator {
    [SameObject] readonly attribute HID hid;
};

5.1 hid 속성

hid 속성을 get할 때마다 항상 동일한 HID 객체 인스턴스를 반환합니다.

6. HID 인터페이스

WebIDL[Exposed=(DedicatedWorker,ServiceWorker,Window), SecureContext]
interface HID : EventTarget {
    attribute EventHandler onconnect;
    attribute EventHandler ondisconnect;
    Promise<sequence<HIDDevice>> getDevices();
    [Exposed=Window] Promise<sequence<HIDDevice>> requestDevice(
        HIDDeviceRequestOptions options);
};
참고

사용자 에이전트의 구현은 hid 속성을 조건부로 노출하도록 선택할 수 있으며, 이는 Navigator관련 전역 객체ServiceWorkerGlobalScope인 경우에 해당합니다. 예를 들어 [browserext]의 브라우저 확장 컨텍스트에서 그렇습니다.

HID 인스턴스는 다음 표에 설명된 내부 슬롯과 함께 생성됩니다:

내부 슬롯 초기값 설명(비규범적)
[[devices]] 비어 있는 순서 있는 집합 시스템에서 현재 사용 가능한 HID 인터페이스를 나타내는 순서 있는 집합HIDDevice 인스턴스입니다
onconnect 속성
onconnect이벤트 핸들러 IDL 속성으로, connect 이벤트 유형에 해당합니다.
ondisconnect 속성
ondisconnect이벤트 핸들러 IDL 속성으로, disconnect 이벤트 유형에 해당합니다.

시스템에서 HID 인터페이스가 사용 가능해지면 다음 단계를 수행합니다:

참고

HID 인터페이스는 HID 프로토콜을 통해 장치와 통신하는 데 사용할 수 있는 논리적 인터페이스입니다. 각 HID 인터페이스는 해당 인터페이스가 지원하는 리포트 집합을 설명하는 정확히 하나의 리포트 서술자(report descriptor)를 가집니다. 하나의 물리적 장치는 둘 이상의 HID 인터페이스를 노출할 수 있습니다. 여러 HID 인터페이스를 가진 장치는 각 인터페이스마다 이 단계를 한 번씩 실행합니다.

예를 들어 USB 장치는 여러 인터페이스의 모음으로 구현되며, 각 인터페이스는 인터페이스 클래스를 지정할 수 있습니다. HID 클래스를 사용하는 여러 USB 인터페이스가 있는 경우, 각 인터페이스는 별도의 HID 인터페이스로 열거됩니다.

  1. deviceHIDDevice로 둔다.
  2. device.[[vendorId]]를 해당 인터페이스를 노출한 장치의 vendor ID로 설정한다.
  3. device.[[productId]]를 해당 인터페이스를 노출한 장치의 product ID로 설정한다.
  4. device.[[productName]]을 해당 인터페이스를 노출한 장치의 product name으로 설정한다.
  5. device.[[collections]]리포트 서술자 파싱의 결과로 설정한다.
  6. hid를 다음과 같이 정한다. 만약 device관련 전역 객체Window 객체라면 그 객체의 hid getter를 호출한 결과로 하고, 그렇지 않으면 WorkerNavigator 객체의 hid getter를 호출한 결과로 한다.
  7. 추가한다: devicehid.[[devices]]에.
  8. 이전에 requestDevice() 호출 결과로 사용자가 사이트가 device에 접근하는 것을 허용했다면, 관련 전역 객체 상에서 HID device task source를 사용해 글로벌 태스크를 큐잉하고, 이벤트를 발행한다. 이벤트 이름은 connect이며 대상은 hid이다. 이때 HIDConnectionEvent를 사용하고, 그 device 속성은 device로 초기화한다.

리포트 서술자를 파싱하려면 다음 단계를 수행한다:

참고

시스템은 일반적으로 장치가 처음 연결될 때 각 HID 인터페이스에 대한 리포트 서술자 바이트 시퀀스를 읽고 값을 시스템 레지스트리에 캐시합니다. 리포트 서술자를 사용할 수 없더라도, 시스템이 각 리포트의 레이아웃을 재구성하는 데 사용할 수 있는 정보를 제공하는 경우, 사용자 에이전트는 리포트 서술자를 파싱하는 대신 대체 알고리즘을 사용할 수 있습니다.

리포트 서술자 형식은 [USBIF-HID-CLASS]의 6.2.2 절에 설명되어 있습니다. 아래 알고리즘은 해당 절에 설명된 동일한 파싱 알고리즘을 구현하기 위한 것입니다.

리포트 서술자에는 세 가지 범주의 아이템이 있습니다. 메인 아이템(Main items)은 데이터 필드를 정의하고 그룹화하는 데 사용됩니다. 글로벌 아이템(Global items)로컬 아이템(Local items)은 데이터 필드를 설명합니다. 로컬 아이템은 다음 메인 아이템에만 적용되는 특성을 정의하며, 글로벌 아이템은 이후에 정의되는 모든 메인 아이템에 영향을 미치는 특성을 정의합니다.

각 아이템에는 0, 1, 2 또는 4 바이트의 해당 데이터가 들어 있는 item data field와, item data field를 저장하는 데 사용되는 바이트 수를 설명하는 bSize field가 있습니다. 또한 각 아이템에는 타입을 식별하는 태그가 있습니다.

  1. items리포트 서술자 바이트 시퀀스리스트로 변환한 결과로 둔다. 이 리스트에는 메인 아이템, 글로벌 아이템, 로컬 아이템이 포함된다.
  2. collectionsHIDCollectionInfo의 빈 sequence로 초기화한다.
  3. ancestors를 빈 리스트로 초기화한다.
  4. localState를 빈 ordered map으로 초기화한다.
  5. usagesunsigned long의 빈 sequence로 초기화한다.
  6. stringIndices를 빈 리스트로 초기화한다.
  7. globalStack을 빈 스택으로 초기화한다.
  8. initialGlobalState를 빈 ordered map으로 초기화한다.
  9. reportId를 0으로 초기화한다.
  10. initialGlobalState["unitSystem"]을 "none"으로 설정한다.
  11. initialGlobalState["unitExponent"]을 0으로 설정한다.
  12. initialGlobalState["unitFactorLengthExponent"]을 0으로 설정한다.
  13. initialGlobalState["unitFactorMassExponent"]을 0으로 설정한다.
  14. initialGlobalState["unitFactorTimeExponent"]을 0으로 설정한다.
  15. initialGlobalState["unitFactorTemperatureExponent"]을 0으로 설정한다.
  16. initialGlobalState["unitFactorCurrentExponent"]을 0으로 설정한다.
  17. initialGlobalState["unitFactorLuminousIntensityExponent"]을 0으로 설정한다.
  18. initialGlobalState["logicalMinimum"]을 0으로 설정한다.
  19. initialGlobalState["logicalMaximum"]을 0으로 설정한다.
  20. initialGlobalState["physicalMinimum"]을 0으로 설정한다.
  21. initialGlobalState["physicalMaximum"]을 0으로 설정한다.
  22. 푸시한다: initialGlobalStateglobalStack에.
  23. 각각에 대해: itemsitem마다:
    참고

    메인 아이템은 [USBIF-HID-CLASS] 6.2.2.4~6.2.2.6 절에 설명되어 있습니다. Input tag, Output tag, Feature tag가 있는 아이템은 입력/출력/피처 리포트 내의 필드를 정의합니다. 메인 아이템item data fieldInput tag, Output tag, Feature tag 중 하나인 경우, 데이터 필드를 설명하는 여러 불리언 파라미터를 담은 비트 필드입니다. Collection tag가 있는 아이템은 현재 컬렉션 내부에 새 컬렉션을 정의하거나, 현재 컬렉션이 없을 때는 새 최상위 컬렉션을 정의합니다. 메인 아이템Collection tagitem data field에는 컬렉션 타입이 들어 있습니다. End Collection tag가 있는 아이템은 현재 컬렉션을 닫습니다.

item, localState, globalState, usages, stringIndicesHID 리포트 아이템을 생성하려면 다음 단계를 수행한다:

  1. reportItem새로운 HIDReportItem 딕셔너리로 둔다.
  2. valueitem data fieldunsigned long으로 해석한 값으로 둔다.
  3. bitfieldvalue의 각 비트를 낮은 비트부터 나타내는 boolean 값들의 리스트로 둔다.
  4. reportItem["isConstant"]를 bitfield[0]으로 설정한다.
  5. reportItem["isArray"]를 !bitfield[1]로 설정한다.
  6. reportItem["isAbsolute"]를 !bitfield[2]로 설정한다.
  7. reportItem["wrap"]을 bitfield[3]으로 설정한다.
  8. reportItem["isLinear"]를 !bitfield[4]로 설정한다.
  9. reportItem["hasPreferredState"]를 bitfield[5]로 설정한다.
  10. reportItem["hasNull"]을 bitfield[6]으로 설정한다.
  11. reportItem["isVolatile"]을 bitfield[7]로 설정한다.
  12. reportItem["isBufferedBytes"]를 bitfield[8]로 설정한다.
  13. reportItem["usages"]를 usages로 설정한다.
  14. reportItem["reportSize"]를 globalState["reportSize"]로 설정한다.
  15. reportItem["reportCount"]를 globalState["reportCount"]로 설정한다.
  16. reportItem["unitExponent"]를 globalState["unitExponent"]로 설정한다.
  17. reportItem["unitSystem"]을 globalState["unitSystem"]로 설정한다.
  18. reportItem["unitFactorLengthExponent"]을 globalState["unitFactorLengthExponent"]로 설정한다.
  19. reportItem["unitFactorMassExponent"]를 globalState["unitFactorMassExponent"]로 설정한다.
  20. reportItem["unitFactorTimeExponent"]를 globalState["unitFactorTimeExponent"]로 설정한다.
  21. reportItem["unitFactorTemperatureExponent"]를 globalState["unitFactorTemperatureExponent"]로 설정한다.
  22. reportItem["unitFactorCurrentExponent"]를 globalState["unitFactorCurrentExponent"]로 설정한다.
  23. reportItem["unitFactorLuminousIntensityExponent"]를 globalState["unitFactorLuminousIntensityExponent"]로 설정한다.
  24. reportItem["logicalMinimum"]을 globalState["logicalMinimum"]로 설정한다.
  25. reportItem["logicalMaximum"]을 globalState["logicalMaximum"]로 설정한다.
  26. "usageMinimum"이 localState에 있으면 reportItem["usageMinimum"]을 localState["usageMinimum"]로 설정한다.

  27. "usageMaximum"이 localState에 있으면 reportItem["usageMaximum"]을 localState["usageMaximum"]로 설정한다.

  28. reportItem["isRange"]를 reportItem["usageMinimum"]이 reportItem["usageMaximum"]보다 작은 경우 true로, 그렇지 않으면 false로 설정한다.
  29. "stringMinimum""stringMaximum"localState에 모두 있으면:
    1. 추가한다: 범위 아이템들을, 즉 localState["stringMinimum"]부터 localState["stringMaximum"]까지를 stringIndices에.
  30. 각각에 대해: stringIndicesstringIndex마다
    1. string을 index stringIndex의 문자열 서술자를 읽은 결과로 둔다.
    2. 추가한다: stringreportItem["strings"]에.
  31. reportItem을 반환한다.

시스템에서 HID 인터페이스가 사용 불가능해지면 다음 단계를 수행한다:

  1. devicehid.[[devices]]에서 해당 인터페이스를 나타내는 HIDDevice로 둔다.
  2. hid를 다음과 같이 둔다: device관련 전역 객체Window 객체라면 그 객체의 hid getter를 호출한 결과로 하고, 그렇지 않으면 WorkerNavigator 객체의 hid getter를 호출한 결과로 한다.
  3. 제거한다: devicehid.[[devices]]에서.
  4. 이전에 requestDevice() 호출 결과로 사용자가 사이트가 device에 접근하는 것을 허용했다면, hid관련 전역 객체에서 HID device task source를 사용해 글로벌 태스크를 큐잉하고, 이벤트를 발행한다. 이벤트 이름은 disconnect이며 대상은 hid이다. 이때 HIDConnectionEvent를 사용하고, 그 device 속성은 device로 초기화한다.

6.1 getDevices() 메서드

getDevices() 메서드의 단계는 다음과 같습니다:

  1. promise새 promise로 둡니다.
  2. documentnull로 둡니다.
  3. this관련 글로벌 객체DedicatedWorkerGlobalScope 이거나 window 객체이면, documentthis관련 글로벌 객체연결된 Document로 설정합니다.
  4. this관련 글로벌 객체ServiceWorkerGlobalScope 객체이고, 연결된 service worker clientwindow client라면, document를 연결된 service worker clientglobal object에 연결된 associated Document로 설정합니다.
  5. documentnull이거나 document가 이름이 "hid"policy-controlled featureallowed to use가 아니면, reject promise를 "SecurityError" DOMException으로 하고 promise를 반환합니다.
  6. 다음 단계를 병렬로 실행합니다:
    1. devices를 빈 sequence(요소 타입은 HIDDevice)로 둡니다.
    2. For each device of this.[[devices]]:
      1. 사용자가 이전의 requestDevice() 호출 결과로 사이트가 device에 접근하도록 허용했고, device.[[state]]"forgotten"이 아니면, append devicedevices에 추가합니다.
    3. Queue a global task관련 글로벌 객체에서 HID device task source를 사용해 resolve 대상인 promisedevices로 하도록 큐잉합니다.
  7. promise를 반환합니다.

6.2 requestDevice() 메서드

참고

requestDevice() 권한 대화상자는 연결된 장치 목록을 표시하고 사용자에게 하나를 선택하도록 요청합니다.

어떤 장치에 여러 개의 HID interfaces가 있는 경우, 대화상자는 모든 인터페이스를 대표하는 단일 항목만 MAY 표시할 수 있습니다. 사용자가 여러 HID interfaces를 대표하는 항목을 선택하면, 사용자 에이전트는 해당 장치가 노출하는 모든 HID interfaces에 대한 접근을 MUST 허용해야 합니다.

requestDevice() 메서드의 단계는 다음과 같습니다:

  1. promise새 promise로 둡니다.
  2. this관련 글로벌 객체연결된 Document가 이름이 "hid"policy-controlled featureallowed to use가 아니면, reject promise를 "SecurityError" DOMException으로 하고 promise를 반환합니다.
  3. 관련 글로벌 객체window가 아니면, reject promise를 "NotSupportedError" DOMException으로 하고 promise를 반환합니다.
  4. 관련 글로벌 객체transient activation이 없으면, reject promise를 "SecurityError" DOMException으로 하고 promise를 반환합니다.
  5. options["filters"]가 존재하면, 다음 단계를 for each filter of options["filters"]에 대해 실행합니다:
    1. filtera valid filter가 아니면, reject promiseTypeError로 하고 promise를 반환합니다.
  6. options["exclusionFilters"]가 존재하면, 다음 단계를 실행합니다:
    1. options["exclusionFilters"]가 비어 있으면, reject promiseTypeError로 하고 promise를 반환합니다.
    2. For each exclusionFilter of options["exclusionFilters"]:
      1. exclusionFiltera valid filter가 아니면, reject promiseTypeError로 하고 promise를 반환합니다.
  7. 다음 단계를 병렬로 실행합니다:
    1. availableDevices를 빈 list로 초기화합니다.
    2. For each device of this.[[devices]]:
      1. deviceoptions["filters"]의 matches any filter이고, deviceoptions["exclusionFilters"]의 어떤 필터와도 match any filter가 아니면, append deviceavailableDevices에 추가합니다.
    3. 사용자에게 availableDevices의 장치 목록을 표시하여 HID 장치 접근 권한을 부여할지 요청합니다.
      참고
      사용자 에이전트는 목록을 사용자에게 보여 주기 전에 수정할 수 있습니다. 예를 들어, 여러 HID interfaces를 가진 장치는 단일 항목으로 SHOULD 표시되어, 해당 항목을 선택하면 장치가 노출하는 모든 인터페이스에 대한 접근이 허용되도록 해야 합니다. 장치가 단일 인터페이스인지 여러 인터페이스의 모음으로 구현되었는지는 사용자가 알지 못할 수 있는 구현 세부사항이며, 장치 접근 권한 판단과 관련된 고려 사항이 되어서는 안 됩니다.
    4. devices를 빈 sequence(요소 타입은 HIDDevice)로 둡니다.
    5. 사용자가 장치를 선택하지 않으면, queue a global task관련 글로벌 객체에서 HID device task source를 사용해 resolve 대상으로 promisedevices로 하고, 이후 단계를 중단합니다.
    6. For each device of this.[[devices]]:
      1. device가 사용자가 선택한 장치가 노출하는 HID interface를 나타내면, device.[[state]]"closed"로 설정하고, append devicedevices에 추가합니다.
    7. Queue a global task관련 글로벌 객체에서 device에 대해 HID device task source를 사용하여 큐잉하고 resolve 대상으로 promisedevices로 설정합니다.
  8. promise를 반환합니다.

6.2.1 HIDDeviceRequestOptions 딕셔너리

WebIDLdictionary HIDDeviceRequestOptions {
    required sequence<HIDDeviceFilter> filters;
    sequence<HIDDeviceFilter> exclusionFilters;
};
filters 멤버
HID 장치에 대한 필터입니다.
exclusionFilters 멤버
HID 장치에 대한 제외 필터입니다.

6.2.2 HIDDeviceFilter 딕셔너리

WebIDLdictionary HIDDeviceFilter {
    unsigned long vendorId;
    unsigned short productId;
    unsigned short usagePage;
    unsigned short usage;
};
vendorId 멤버
일치시킬 vendor ID입니다.
productId 멤버
일치시킬 product ID입니다. vendorId 멤버가 없으면 productId는 무시됩니다.
usagePage 멤버
일치시킬 top-level collectionusage page입니다.
usage 멤버
일치시킬 top-level collectionusage ID입니다. usagePage 멤버가 없으면 usage는 무시됩니다.
참고

장치 필터는 requestDevice()가 생성하는 선택 대화상자에서 사용자에게 표시되는 장치 목록을 좁히는 데 사용됩니다. 필터가 제공되지 않으면 제외 필터에 일치하지 않는 모든 연결된 장치가 포함됩니다. 하나 이상의 필터가 제공되면, 임의의 필터에 일치하고 어떤 제외 필터에도 일치하지 않는 장치가 포함됩니다.

모든 HIDDeviceFilter 멤버는 선택 사항입니다. 각 멤버는 하나의 규칙을 지정합니다. 어떤 HIDDeviceFilter와 일치하려면 모든 규칙이 충족되어야 합니다. 비어 있는 HIDDeviceFilter는 모든 장치와 일치합니다.

장치 ID 규칙은 vendor IDproduct ID로 장치를 선택하는 데 사용됩니다. 이는 애플리케이션이 특정 장치에서만 동작하거나 벤더 전용 기능에 의존하는 경우 유용합니다. vendorId 규칙을 포함하면 지정된 vendor ID를 가진 장치에만 일치합니다. productId 규칙도 포함되면, 지정된 vendor IDproduct ID를 모두 가진 장치에만 일치합니다. productIdvendorId 규칙 없이 지정되면 무시됩니다.

사용 규칙은 장치의 HID usages가 할당된 top-level collections로 장치를 선택하는 데 사용됩니다. 이는 표준 장치 클래스와 동작하도록 설계된 애플리케이션에서 유용합니다. 장치와 일치하려면 장치의 컬렉션 중 적어도 하나가 모든 사용 규칙과 일치해야 합니다. usagePage 규칙을 포함하면, 장치에 지정된 usage page를 가진 컬렉션이 있는 경우에만 일치합니다. usage 규칙도 포함되면, 지정된 usage pageusage ID를 모두 가진 장치에만 일치합니다. usageusagePage 규칙 없이 지정되면 무시됩니다.

장치 ID 규칙과 사용 규칙은 함께 사용할 수 있습니다. 예를 들어, 특정 벤더의 장치 중에서도 특정 장치 클래스를 구현한 장치만 일치시키고자 할 수 있습니다.

exclusionFilters 옵션을 사용하면, 특정 장치 클래스를 구현했음에도 예상대로 동작하지 않는 것으로 알려진 장치를 requestDevice()가 생성하는 선택 대화상자의 목록에서 제외할 수 있습니다.

HIDDeviceFilter filtera valid filter인지 여부는 다음 단계가 true를 반환하는지로 결정됩니다:

  1. filter가 비어 있으면 false를 반환합니다.
  2. filter["productId"]는 존재하는데 filter["vendorId"]가 존재하지 않으면, false를 반환합니다.
  3. filter["usage"]는 존재하는데 filter["usagePage"]가 존재하지 않으면, false를 반환합니다.
  4. true를 반환합니다.

HIDDevice devicesequence filtersHIDDeviceFilter에 대해 matches any filter인지 여부는 다음 단계가 true를 반환하는지로 결정됩니다:

  1. filters가 비어 있으면 true를 반환합니다.
  2. For each filter of filters:
    1. filterdevicematches the device IDs이며, 그리고 filterdevicematches any collection이면, true를 반환합니다.
  3. false를 반환합니다.

HIDDeviceFilter filterdevicematches the device IDs인지 여부는 다음 단계가 true를 반환하는지로 결정됩니다:

  1. "vendorId"가 filter에 있으면:
    1. filter["vendorId"]가 device.vendorId와 같지 않으면, false를 반환합니다.
    2. "productId"가 filter에 있고, filter["productId"]가 device.productId와 같지 않으면, false를 반환합니다.
  2. true를 반환합니다.

HIDDeviceFilter filterdevicematches any collection인지 여부는 다음 단계가 true를 반환하는지로 결정됩니다:

  1. For each collection of device.collections:
    1. filtermatches the collection collection이면 true를 반환합니다.
  2. false를 반환합니다.

HIDDeviceFilter filtercollection에 대해 matches the collection인지 여부는 다음 단계가 true를 반환하는지로 결정됩니다:

  1. "usagePage"가 filter에 있으면:
    1. filter["usagePage"]가 collection.usagePage와 같지 않으면, false를 반환합니다.
    2. "usage"가 filter에 있고, filter["usage"]가 collection.usage와 같지 않으면, false를 반환합니다.
  2. true를 반환합니다.

7. HIDDevice 인터페이스

WebIDL[Exposed=(DedicatedWorker,ServiceWorker,Window), SecureContext]
interface HIDDevice : EventTarget {
    attribute EventHandler oninputreport;
    readonly attribute boolean opened;
    readonly attribute unsigned short vendorId;
    readonly attribute unsigned short productId;
    readonly attribute DOMString productName;
    readonly attribute FrozenArray<HIDCollectionInfo> collections;
    Promise<undefined> open();
    Promise<undefined> close();
    Promise<undefined> forget();
    Promise<undefined> sendReport([EnforceRange] octet reportId, BufferSource data);
    Promise<undefined> sendFeatureReport(
        [EnforceRange] octet reportId,
        BufferSource data);
    Promise<DataView> receiveFeatureReport([EnforceRange] octet reportId);
};

이 인터페이스의 메서드들은 일반적으로 비동기적으로 완료되며, HID device task source에 작업을 큐잉합니다.

HIDDevice의 인스턴스는 다음 표에 설명된 내부 슬롯과 함께 생성됩니다:

내부 슬롯 초기값 설명(비규범적)
[[state]] "closed" HIDDevice의 활성 상태를 추적합니다
[[vendorId]] 0 장치의 vendor ID
[[productId]] 0 장치의 product ID
[[productName]] "" 장치의 product name
[[collections]] HIDCollectionInfo의 빈 sequence report descriptor 파싱으로 생성된 top-level collections
[[pendingSendReportPromises]] list 보류 중인 sendReport() Promise
[[pendingSendFeatureReportPromises]] list 보류 중인 sendFeatureReport() Promise
[[pendingReceiveFeatureReportPromises]] list 보류 중인 receiveFeatureReport() Promise
oninputreport 속성
oninputreport이벤트 핸들러 IDL 속성으로, inputreport 이벤트 유형에 해당합니다.
opened 속성

HIDDevice가 데이터 전송을 할 준비가 되었음을 나타내는 플래그입니다.

opened getter 단계는 다음과 같습니다:

  1. this.[[state]]opened이면 true를 반환합니다.
  2. false를 반환합니다.
vendorId 속성

vendor ID는 장치 제조사를 식별하기 위해 vendor ID source가 할당하는 unsigned short 값입니다.

vendorId 속성은 장치의 vendor ID입니다. 장치에 vendor ID가 없거나 vendor ID에 접근할 수 없으면, 이 속성은 MUST 0이어야 합니다.

vendorId getter 단계는 다음과 같습니다:

  1. this.[[vendorId]]를 반환합니다.
productId 속성

product ID는 제조사가 제품을 식별하기 위해 할당하는 unsigned short 값입니다.

productId 속성은 장치의 product ID입니다. 장치에 product ID가 없거나 product ID에 접근할 수 없으면, 이 속성은 MUST 0이어야 합니다.

productId getter 단계는 다음과 같습니다:

  1. this.[[productId]]를 반환합니다.
productName 속성

제품을 식별하는 문자열입니다.

USB HID 장치의 경우, product name에는 장치 서술자(Device Descriptor)에 지정된 인덱스 iProduct의 문자열 서술자 값이 SHOULD 포함되어야 합니다. Bluetooth HID 장치의 경우, product name에는 Device Name 특성의 값이 SHOULD 포함되어야 합니다. 장치에 product name이 없거나 product name이 비어 있거나 접근할 수 없으면, 이 속성은 MUST 빈 문자열을 반환해야 합니다.

productName 문자열에는 일련 번호나 Bluetooth 장치 주소와 같이 장치를 고유하게 식별할 수 있는 식별자가 SHOULD NOT 포함되어야 합니다.

productName getter 단계는 다음과 같습니다:

  1. this.[[productName]]를 반환합니다.
collections 속성

sequenceHIDCollectionInfo로, report descriptortop-level collections을 나타냅니다.

collections getter 단계는 다음과 같습니다:

  1. this.[[collections]]를 반환합니다.
Note
Top-level collections는 장치 내에서 유사한 목적의 항목들을 그룹화합니다. 애플리케이션은 장치를 식별하기 위해 top-level collections에 적용된 HID usage를 확인합니다. 특정 유형의 장치에 대한 규약을 따르지 않으면 애플리케이션이 장치를 인식하지 못할 수 있습니다. 표준 HID 장치의 관례적 동작에 대한 자세한 내용은 [USBIF-HID-USAGE]를 참조하십시오.

device로부터 입력 리포트를 수신하면, 다음 단계를 수행합니다:

  1. 입력 리포트가 blocked report이면, 이 단계를 중단합니다.
  2. 이 리포트의 report ID를 reportId로 두고, HID interfaceuse report IDs를 사용하지 않으면 0으로 둡니다.
  3. 입력 리포트를 나타내는 byte sequence 위에 생성된 DataViewdata로 둡니다. HID interfaceuses report IDs를 사용하는 경우, 이 byte sequence에는 리포트 ID 바이트가 MUST NOT 포함되면 안 됩니다.
  4. Queue a global task관련 글로벌 객체에서 this에 대해 HID device task source를 사용하여 큐잉하고, fire an eventinputreport라는 이름의 이벤트를 device에서 발행합니다. 이때 HIDInputReportEvent를 사용하고, 그 device 속성은 device로, reportId 속성은 reportId로, data 속성은 data로 초기화합니다.

7.1 open() 메서드

open() 메서드의 단계는 다음과 같습니다:

  1. promise새 promise로 둡니다.
  2. this.[[state]]"closed"가 아니면, reject promise를 "InvalidStateError" DOMException으로 하고 promise를 반환합니다.
  3. this.[[state]]"opening"으로 설정합니다.
  4. 다음 단계를 병렬로 수행합니다:
    1. 운영체제에 HID 장치를 열도록 요청합니다.
    2. 어떠한 이유로든 실패하면, queue a global task관련 글로벌 객체에서 HID device task source를 사용해 큐잉하고, "NetworkError" DOMException으로 reject promise하고, 이후 단계를 중단합니다.
    3. this.[[state]]"opened"로 설정합니다.
    4. Queue a global task관련 글로벌 객체에서 HID device task source를 사용해 큐잉하고, resolve 대상으로 promiseundefined로 설정합니다.
  5. promise를 반환합니다.

7.2 close() 메서드

close() 메서드의 단계는 다음과 같습니다:

  1. promise새 promise로 둡니다.
  2. this.[[state]]"forgotten" 또는 "forgetting"이면, "InvalidStateError" DOMException으로 reject promise하고 promise를 반환합니다.
  3. this.[[state]]"closing"으로 설정합니다.
  4. For each pendingPromise of this.[[pendingSendReportPromises]]:
    1. Reject pendingPromise를 "AbortError" DOMException으로 거부합니다.
  5. Empty this.[[pendingSendReportPromises]].
  6. For each pendingPromise of this.[[pendingSendFeatureReportPromises]]:
    1. Reject pendingPromise를 "AbortError" DOMException으로 거부합니다.
  7. Empty this.[[pendingSendFeatureReportPromises]].
  8. For each pendingPromise of this.[[pendingReceiveFeatureReportPromises]]:
    1. Reject pendingPromise를 "AbortError" DOMException으로 거부합니다.
  9. Empty this.[[pendingReceiveFeatureReportPromises]].
  10. 다음 단계를 병렬로 수행합니다:
    1. 운영체제에 HID 장치를 닫고 관련 리소스를 해제하도록 요청합니다.
    2. this.[[state]]"closed"로 설정합니다.
    3. Queue a global task관련 글로벌 객체에서 HID device task source를 사용해 큐잉하고, resolve 대상으로 promiseundefined로 설정합니다.
  11. promise를 반환합니다.

7.3 forget() 메서드

Note

사용자 에이전트는 API 전반의 권한을 결합하기로 MAY 선택할 수 있습니다. 예를 들어, WebHID + WebUSB 장치 접근을 통합된 저수준 장치 접근 권한으로 추적할 수 있습니다. 이러한 이유로 이 메서드는 향후 추가적인(아직 지정되지 않은) 권한들도 철회할 수 있습니다.

forget() 메서드의 단계는 다음과 같습니다:

  1. promise새 promise로 둡니다.
  2. 다음 단계를 병렬로 수행합니다:
    1. For each device of this.[[devices]]:
      1. device가 HIDDevice와 장치 접근 권한을 공유하지 않으면, 다음 장치로 넘어갑니다.
      2. device.[[state]]"forgetting"으로 설정합니다.
      3. For each pendingPromise of device.[[pendingSendReportPromises]]:
        1. Reject pendingPromise를 "AbortError" DOMException으로 거부합니다.
      4. Empty device.[[pendingSendReportPromises]].
      5. For each pendingPromise of device.[[pendingSendFeatureReportPromises]]:
        1. Reject pendingPromise를 "AbortError" DOMException으로 거부합니다.
      6. Empty device.[[pendingSendFeatureReportPromises]].
      7. For each pendingPromise of device.[[pendingReceiveFeatureReportPromises]]:
        1. Reject pendingPromise를 "AbortError" DOMException으로 거부합니다.
      8. Empty device.[[pendingReceiveFeatureReportPromises]].
      9. 사용자 에이전트에 device가 노출하는 모든 HID interfaces에 대한 접근을 취소하도록 요청합니다.
      10. device.[[state]]"forgotten"으로 설정합니다.
    2. Queue a global task관련 글로벌 객체에서 HID device task source를 사용해 큐잉하고, resolve 대상으로 promiseundefined로 설정합니다.
  3. promise를 반환합니다.

7.4 sendReport() 메서드

Note

sendReport() 메서드는 지정된 reportIddata를 사용해 출력 리포트를 전송하는 데 사용됩니다. HID interfaceuse report IDs를 사용하지 않으면, 리포트 ID 대신 0을 전달하십시오.

HID interfacesuse report IDs를 사용하는 경우, 리포트 ID 값 0은 예약되어 있으며 사용하지 않아야 합니다.

sendReport() 메서드의 단계는 다음과 같습니다:

  1. promise새 promise로 둡니다.
  2. this.[[state]]"opened"가 아니면, "InvalidStateError" DOMException으로 reject promise하고 promise를 반환합니다.
  3. reportId가 0인데 HID interfaceuses report IDs를 사용하거나, reportId가 0이 아닌데 인터페이스가 use report IDs를 사용하지 않으면, "TypeError" DOMException으로 reject promise하고 promise를 반환합니다.
  4. Append promisethis.[[pendingSendReportPromises]]에 추가합니다.
  5. 다음 단계를 병렬로 수행합니다:
    1. 이 리포트가 blocked report이면, queue a global task관련 글로벌 객체에서 HID device task source를 사용해 큐잉하고, "NotAllowedError" DOMException으로 reject promise하고 이후 단계를 중단합니다.
    2. 운영체제에 지정된 reportIddata로 출력 리포트를 전송하도록 요청합니다.
    3. 어떠한 이유로든 실패하면, queue a global task관련 글로벌 객체에서 HID device task source를 사용해 큐잉하고, "NetworkError" DOMException으로 reject promise하고 이후 단계를 중단합니다.
    4. Queue a global task관련 글로벌 객체에서 HID device task source를 사용해 큐잉하고, resolve 대상으로 promiseundefined로 설정합니다.
  6. promise를 반환합니다.

7.5 sendFeatureReport() 메서드

Note

sendFeatureReport() 메서드는 지정된 reportIddata로 feature 리포트를 전송하는 데 사용됩니다. HID interfaceuse report IDs를 사용하지 않으면, 리포트 ID 대신 0을 전달하십시오.

HID interfacesuse report IDs를 사용하는 경우, 리포트 ID 값 0은 예약되어 있으며 사용하지 않아야 합니다.

sendFeatureReport() 메서드의 단계는 다음과 같습니다:

  1. promise새 promise로 둡니다.
  2. this.[[state]]"opened"가 아니면, "InvalidStateError" DOMException으로 reject promise하고 promise를 반환합니다.
  3. reportId가 0인데 HID interfaceuses report IDs를 사용하거나, reportId가 0이 아닌데 인터페이스가 use report IDs를 사용하지 않으면, "TypeError" DOMException으로 reject promise하고 promise를 반환합니다.
  4. Append promisethis.[[pendingSendFeatureReportPromises]]에 추가합니다.
  5. 다음 단계를 병렬로 수행합니다:
    1. 이 리포트가 blocked report이면, queue a global task관련 글로벌 객체에서 HID device task source를 사용해 큐잉하고, "NotAllowedError" DOMException으로 reject promise하고 이후 단계를 중단합니다.
    2. 운영체제에 지정된 reportIddata로 feature 리포트를 전송하도록 요청합니다.
    3. 어떠한 이유로든 실패하면, queue a global task관련 글로벌 객체에서 HID device task source를 사용해 큐잉하고, "NetworkError" DOMException으로 reject promise하고 이후 단계를 중단합니다.
    4. Queue a global task관련 글로벌 객체에서 HID device task source를 사용해 큐잉하고, resolve 대상으로 promiseundefined로 설정합니다.
  6. promise를 반환합니다.

7.6 receiveFeatureReport() 메서드

Note

receiveFeatureReport() 메서드는 지정된 reportId의 feature 리포트를 요청하는 데 사용됩니다. HID interfaceuse report IDs를 사용하지 않으면, 리포트 ID 대신 0을 전달하십시오.

HID interfacesuse report IDs를 사용하는 경우, 리포트 ID 값 0은 예약되어 있으며 사용하지 않아야 합니다.

receiveFeatureReport() 메서드의 단계는 다음과 같습니다:

  1. promise새 promise로 둡니다.
  2. this.[[state]]"opened"가 아니면, "InvalidStateError" DOMException으로 reject promise하고 promise를 반환합니다.
  3. reportId가 0인데 HID interfaceuses report IDs를 사용하거나, reportId가 0이 아닌데 인터페이스가 use report IDs를 사용하지 않으면, "TypeError" DOMException으로 reject promise하고 promise를 반환합니다.
  4. Append promisethis.[[pendingReceiveFeatureReportPromises]]에 추가합니다.
  5. 다음 단계를 병렬로 수행합니다:
    1. 이 리포트가 blocked report이면, queue a global task관련 글로벌 객체에서 HID device task source를 사용해 큐잉하고, "NotAllowedError" DOMException으로 reject promise하고 이후 단계를 중단합니다.
    2. data를 다음으로 둡니다: 지정된 reportId의 feature 리포트를 읽도록 운영체제를 호출한 결과를 나타내는 byte sequence 위에 생성된 DataView.
      Note
      data에는 운영체제로부터 수신된 리포트 데이터가 포함됩니다. 장치가 use report IDs를 사용하는 경우 첫 번째 바이트가 리포트 ID일 수 있습니다. 이 바이트가 포함되는 이유는 장치가 리포트 ID 대신 다른 데이터를 응답할 수 있기 때문입니다.
    3. feature 리포트 읽기가 어떠한 이유로든 실패하면, queue a global task관련 글로벌 객체에서 HID device task source를 사용해 큐잉하고, "NetworkError" DOMException으로 reject promise하고 이후 단계를 중단합니다.
    4. Queue a global task관련 글로벌 객체에서 HID device task source를 사용해 큐잉하고, resolve 대상으로 promisedata로 설정합니다.
  6. promise를 반환합니다.

8. HIDConnectionEvent 인터페이스

WebIDL[Exposed=(DedicatedWorker,ServiceWorker,Window), SecureContext]
interface HIDConnectionEvent : Event {
    constructor(DOMString type, HIDConnectionEventInit eventInitDict);
    [SameObject] readonly attribute HIDDevice device;
};
device 속성
연결되었거나 연결이 해제된 장치를 나타내는 HIDDevice 인스턴스입니다.

8.1 HIDConnectionEventInit 딕셔너리

WebIDLdictionary HIDConnectionEventInit : EventInit {
    required HIDDevice device;
};
device 멤버
이벤트와 연관된 장치입니다.

9. HIDInputReportEvent 인터페이스

WebIDL[Exposed=(DedicatedWorker,ServiceWorker,Window), SecureContext]
interface HIDInputReportEvent : Event {
    constructor(DOMString type, HIDInputReportEventInit eventInitDict);
    [SameObject] readonly attribute HIDDevice device;
    readonly attribute octet reportId;
    readonly attribute DataView data;
};
device 속성
입력 리포트를 보낸 HID 인터페이스를 나타내는 HIDDevice 인스턴스입니다.
reportId 속성
이 리포트의 1바이트 식별 접두사이며, HID 인터페이스report ID를 사용하지 않으면 0입니다.
data 속성
입력 리포트에서 가져온 데이터를 포함하는 DataView입니다. HID 인터페이스report ID를 사용한다면 reportId 바이트는 제외됩니다.

9.1 HIDInputReportEventInit 딕셔너리

WebIDLdictionary HIDInputReportEventInit : EventInit {
    required HIDDevice device;
    required octet reportId;
    required DataView data;
};
device 멤버
이벤트와 연관된 장치입니다.
reportId 멤버
입력 리포트의 리포트 ID입니다.
data 멤버
입력 리포트의 데이터입니다.

10. HIDCollectionInfo 딕셔너리

WebIDLdictionary HIDCollectionInfo {
    unsigned short usagePage;
    unsigned short usage;
    octet type;
    sequence<HIDCollectionInfo> children;
    sequence<HIDReportInfo> inputReports;
    sequence<HIDReportInfo> outputReports;
    sequence<HIDReportInfo> featureReports;
};

장치가 시스템에 처음 연결되면, 시스템은 장치가 노출하는 각 HID 인터페이스에 대한 리포트 디스크립터MUST 가져와야 합니다. Report descriptor는 각 리포트의 레이아웃을 설명하는 계층적 데이터 구조로 확장될 수 있는 바이트 시퀀스입니다. 이 데이터 구조의 요소를 항목(items)이라 하며, 관계를 공유하는 항목들의 그룹을 컬렉션(collections)이라 합니다.

HIDCollectionInfo 객체는 리포트 디스크립터 내의 단일 컬렉션을 나타냅니다. 컬렉션이 중첩된 컬렉션을 포함하는 경우, 중첩된 컬렉션은 children의 요소로 포함됩니다.

inputReports, outputReports, featureReports 속성에는 이 컬렉션에 설명된 각 리포트에 대한 정보를 제공하는 시퀀스HIDReportInfo가 포함됩니다. 최상위(top-level) 컬렉션의 경우, HIDReportInfo는 리포트를 구성하는 모든 항목의 평탄화된 뷰를 나타냅니다. 평탄화된 뷰는 중첩된 컬렉션 내 항목과 최상위 컬렉션 내 항목을 교차 배치합니다. 중첩 컬렉션의 경우 HIDReportInfo에는 해당 컬렉션과 그 중첩 컬렉션에 포함된 항목만 포함됩니다.

usagePage 멤버

이 컬렉션과 연관된 HID usageusage page 구성요소입니다.

HID usages는 애플리케이션이 항목이나 컬렉션의 목적과 의미를 식별하는 데 사용할 수 있는 상수입니다. HID usage는 상위 비트의 unsigned short usage page와 하위 비트의 unsigned short usage ID로 구성된 unsigned long 값입니다. 표준 HID usage 값은 [USBIF-HID-CLASS] 및 USB Implementers Forum이 발행한 다른 문서에 설명되어 있습니다.

장치가 노출하는 최상위 컬렉션HID usage는 일반적인 장치 유형을 식별하는 데 사용됩니다.

usage 멤버

이 컬렉션과 연관된 HID usageusage ID 구성요소입니다.

usage IDusage page에서 개별 HID usage를 선택하는 데 사용됩니다. 관례적으로 usage ID 0x01~0x1F는 최상위 컬렉션을 위해 예약되어 있습니다.

type 멤버

컬렉션 타입을 나타내는 값입니다.

컬렉션 타입
물리(Physical) 0x00
애플리케이션(Application) 0x01
논리(Logical) 0x02
리포트(Report) 0x03
명명된 배열(Named Array) 0x04
사용 전환(Usage Switch) 0x05
사용 수정됨(Usage Modified) 0x06
향후 사용을 위해 예약(Reserved for future use) 0x07 to 0x7F
벤더 정의(Vendor-defined) 0x80 to 0xFF

컬렉션 타입은 그룹화된 항목 간의 서로 다른 관계를 설명합니다. USBIF-HID-CLASS의 6.2.2.6 절을 참고하여 컬렉션 타입에 대해 더 알아볼 수 있습니다.

children 멤버
이 컬렉션 내에 중첩된 컬렉션을 나타내는 시퀀스HIDCollectionInfo입니다.
inputReports 멤버
이 컬렉션에 설명된 입력 리포트를 나타내는 시퀀스HIDReportInfo입니다.
outputReports 멤버
이 컬렉션에 설명된 출력 리포트를 나타내는 시퀀스HIDReportInfo입니다.
featureReports 멤버
이 컬렉션에 설명된 기능(feature) 리포트를 나타내는 시퀀스HIDReportInfo입니다.

11. HIDReportInfo 딕셔너리

WebIDLdictionary HIDReportInfo {
    octet reportId;
    sequence<HIDReportItem> items;
};

HIDReportInfo리포트 디스크립터 내의 하나의 입력, 출력 또는 기능 리포트를 나타냅니다.

reportId 멤버
HID 인터페이스가 각 리포트 전송에 1바이트 식별 접두사를 앞에 붙이면 report ID를 사용합니다. 인터페이스가 report ID를 사용하는 경우 reportId 멤버는 이 리포트의 접두사이며, 그렇지 않으면 0입니다.
items 멤버
이 리포트의 필드를 나타내는 시퀀스HIDReportItem입니다.

12. HIDReportItem 딕셔너리

WebIDLdictionary HIDReportItem {
    boolean isAbsolute;
    boolean isArray;
    boolean isBufferedBytes;
    boolean isConstant;
    boolean isLinear;
    boolean isRange;
    boolean isVolatile;
    boolean hasNull;
    boolean hasPreferredState;
    boolean wrap;
    sequence<unsigned long> usages;
    unsigned long usageMinimum;
    unsigned long usageMaximum;
    unsigned short reportSize;
    unsigned short reportCount;
    byte unitExponent;
    HIDUnitSystem unitSystem;
    byte unitFactorLengthExponent;
    byte unitFactorMassExponent;
    byte unitFactorTimeExponent;
    byte unitFactorTemperatureExponent;
    byte unitFactorCurrentExponent;
    byte unitFactorLuminousIntensityExponent;
    long logicalMinimum;
    long logicalMaximum;
    long physicalMinimum;
    long physicalMaximum;
    sequence<DOMString> strings;
};
isAbsolute 멤버
데이터가 고정 원점에 기반한 절대값이면 true, 마지막 리포트로부터의 값 변화를 나타내는 상대값이면 false입니다.
isArray 멤버
각 데이터 필드에 눌린 버튼이나 키에 해당하는 인덱스를 포함하는 배열 데이터 필드를 리포트에 생성하면 true, 각 데이터 필드가 값을 포함하는 변수 데이터 필드를 리포트에 생성하면 false입니다.
isBufferedBytes 멤버
항목이 고정 크기의 바이트 스트림을 내보내면 true, 항목이 수치형 값이면 false입니다.
isConstant 멤버
항목이 수정할 수 없는 정적 읽기 전용 필드이면 true, 수정 가능한 장치 데이터를 포함하는 리포트 필드를 정의하면 false입니다.
isLinear 멤버
항목이 측정값과 보고값 사이의 선형 관계를 나타내면 true, 데이터가 어떤 방식으로든 처리되었으면 false입니다.
isRange 멤버
항목이 HID usage 범위에서 usageMinimumusageMaximum으로 정의된 사용값을 할당하면 true, 항목에 시퀀스HID usage 값이 usages에 있으면 false입니다.
isVolatile 멤버

호스트의 상호작용 없이 항목 값이 변경될 수 있으면 true, 항목 값이 오직 호스트에 의해서만 변경되어야 하면 false입니다.

기능(Feature) 및 출력(Output) 항목에만 사용됩니다.

hasNull 멤버
항목에 의미 있는 데이터를 보내지 않는 널(null) 상태가 있으면 true, 없으면 false입니다. 널 상태에서는 항목이 지정된 logicalMinimumlogicalMaximum 범위를 벗어난 값을 보고합니다.
hasPreferredState 멤버
사용자가 컨트롤을 물리적으로 조작하지 않을 때 항목이 돌아갈 선호 상태가 있으면 true, 없으면 false입니다.
wrap 멤버
항목 값이 최대 또는 최소 극값에 도달했을 때 롤오버되면 true, 롤오버되지 않으면 false입니다.
usages 멤버

isRangetrue이거나 이 항목에 연관된 HID usage 값이 없다면, usagesMUST 미정의(undefined)여야 합니다.

isRangefalse이면 usages는 이 항목과 연관된 HID usage 값의 시퀀스입니다.

usageMinimum 멤버

isRangetrue이면 usageMinimum에는 이 항목과 연관된 사용 범위의 최소 HID usage 값이 포함됩니다.

isRangefalse이면 usageMinimumMUST 미정의(undefined)여야 합니다.

usageMaximum 멤버

isRangetrue이면 usageMaximum에는 이 항목과 연관된 사용 범위의 최대 HID usage 값이 포함됩니다.

isRangefalse이면 usageMaximumMUST 미정의(undefined)여야 합니다.

reportSize 멤버
각 리포트 데이터 필드의 크기(비트)입니다. reportSizeMUST 0보다 커야 합니다.
reportCount 멤버
이 항목에 대해 리포트에 포함되는 필드의 개수입니다. reportCountMUST 0보다 커야 합니다.
unitExponent 멤버
단위 지수 값입니다. 항목에 단위 정의가 없으면 0입니다.
unitSystem 멤버
단위 정의의 단위계를 지정하는 HIDUnitSystem 열거값이며, 항목에 단위 정의가 없으면 "none"입니다.
unitFactorLengthExponent 멤버
단위 정의에서 길이 단위(센티미터, 라디안, 인치, 도)의 지수 값이며, 항목에 단위 정의가 없으면 0입니다.
unitFactorMassExponent 멤버
단위 정의에서 질량 단위(그램 또는 슬러그)의 지수 값이며, 항목에 단위 정의가 없으면 0입니다.
unitFactorTimeExponent 멤버
단위 정의에서 시간 단위(초)의 지수 값이며, 항목에 단위 정의가 없으면 0입니다.
unitFactorTemperatureExponent 멤버
단위 정의에서 온도 단위(켈빈 또는 화씨)의 지수 값이며, 항목에 단위 정의가 없으면 0입니다.
unitFactorCurrentExponent 멤버
단위 정의에서 전류 단위(암페어)의 지수 값이며, 항목에 단위 정의가 없으면 0입니다.
unitFactorLuminousIntensityExponent 멤버
단위 정의에서 광도 단위(칸델라)의 지수 값이며, 항목에 단위 정의가 없으면 0입니다.
logicalMinimum 멤버
논리 단위에서 이 항목의 최소 범위입니다. 변수 또는 배열 항목이 보고할 최소값입니다.
logicalMaximum 멤버
논리 단위에서 이 항목의 최대 범위입니다. 변수 또는 배열 항목이 보고할 최대값입니다.
physicalMinimum 멤버
이 항목의 물리적 범위에 대한 최소값입니다. 이는 단위를 적용한 logicalMinimum을 의미합니다.
physicalMaximum 멤버
이 항목의 물리적 범위에 대한 최대값입니다. 이는 단위를 적용한 logicalMaximum을 의미합니다.
strings 멤버
이 항목과 연관된 문자열이며, 연관된 문자열이 없으면 빈 시퀀스입니다.

13. HIDUnitSystem 열거형

[USBIF-HID-CLASS] 6.2.2.7 절은 네 가지 표준 단위계를 정의합니다: SI 선형, SI 회전, 영국식 선형, 영국식 회전. 각 항목은 이 네 가지 단위계 중 하나, 벤더 정의 단위계, 또는 단위계 없음 중 하나를 사용합니다.

WebIDLenum HIDUnitSystem {
    "none", "si-linear", "si-rotation", "english-linear",
    "english-rotation", "vendor-defined", "reserved"
};
"none"
단위계 없음. 항목에 단위 정의가 없음을 나타냅니다.
"si-linear"
SI 선형 단위계는 센티미터, 그램, 초, 켈빈, 암페어, 칸델라를 사용합니다.
"si-rotation"
SI 회전 단위계는 라디안, 그램, 초, 켈빈, 암페어, 칸델라를 사용합니다.
"english-linear"
영국식 선형 단위계는 인치, 슬러그, 초, 화씨 도, 암페어, 칸델라를 사용합니다.
"english-rotation"
영국식 회전 단위계는 도, 슬러그, 초, 화씨 도, 암페어, 칸델라를 사용합니다.
"vendor-defined"
벤더 정의 단위계입니다.
"reserved"
장치가 단위계에 대해 예약된 값을 사용했음을 나타냅니다.

14. 사용 예시

15. HID 차단 목록

이 명세는 웹사이트가 접근할 수 있는 HID 장치 집합을 제한하기 위해 https://github.com/WICG/webhid 리포지토리의 차단 목록 파일에 의존합니다.

url에서 차단 목록을 파싱한 결과는 시퀀스의 딕셔너리 객체로, url을 가져와서 그 내용을 JSON으로 파싱함으로써 생성됩니다.

HID 차단 목록차단 목록을 파싱한 결과이며, 위치는 https://github.com/WICG/webhid/blob/main/blocklist.txt 입니다.

다음 단계가 true를 반환하면, 리포트는 차단된 리포트입니다:

  1. 각각의 HID 차단 목록rule에 대해:
    1. 리포트가 rule에 의해 차단 목록 규칙에 의해 차단된다면 true를 반환합니다.
  2. false를 반환합니다.

다음 단계가 true를 반환하면, 리포트는 rule에 의해 차단 목록 규칙에 의해 차단됩니다:

  1. 리포트의 리포트 ID를 reportId로 두고, HID 인터페이스report ID를 사용하지 않으면 0으로 둡니다.
  2. 리포트가 입력 리포트이면 reportType"input"으로, 출력 리포트이면 "output"으로, 기능 리포트이면 "feature"로 둡니다.
  3. 리포트를 포함하는 최상위 컬렉션collection으로 둡니다.
  4. rule"vendor"가 포함되어 있고 rule["vendor"]가 device.vendorId와 다르면 false를 반환합니다.
  5. rule"product"가 포함되어 있고 rule["product"]가 device.productId와 다르면 false를 반환합니다.
  6. rule"reportId"가 포함되어 있고 rule["reportId"]가 reportId와 다르면 false를 반환합니다.
  7. rule"reportType"가 포함되어 있고 rule["reportType"]가 reportType과 다르면 false를 반환합니다.
  8. rule"usagePage"가 포함되어 있고 rule["usagePage"]가 collection["usagePage"]와 다르면 false를 반환합니다.
  9. rule"usage"가 포함되어 있고 rule.["usage"]가 collection["usage"]와 다르면 false를 반환합니다.
  10. true를 반환합니다.

16. 통합

16.1 권한 정책

이 명세는 hid 속성이 Navigator 객체에 노출되는지를 제어하는 기능을 정의합니다.

이 기능의 기능 이름은 "hid"입니다.

이 기능의 기본 허용 목록'self'입니다.

17. 적합성

비규범적(non-normative)으로 표시된 절뿐만 아니라, 이 명세의 모든 작성 지침, 다이어그램, 예제, 주석은 비규범적입니다. 그 외 이 명세의 모든 내용은 규범적입니다.

이 문서의 MAY, MUST, MUST NOT, SHOULD, SHOULD NOT 키워드는 BCP 14 [RFC2119] [RFC8174] 에서 설명된 대로, 그리고 오직 여기에서처럼 모두 대문자로 나타날 때에만 해석되어야 합니다.

A. 감사의 말

다음 분들이 이 문서의 개발에 기여했습니다.

B. 참고 문헌

B.1 규범 참고 문헌

[dom]
DOM 표준. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[html]
HTML 표준. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[infra]
Infra 표준. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[permissions-policy]
Permissions Policy. Ian Clelland. W3C. 2024년 7월 24일. W3C Working Draft. URL: https://www.w3.org/TR/permissions-policy-1/
[RFC2119]
RFC에서 요구 수준을 나타내는 키워드 사용. S. Bradner. IETF. 1997년 3월. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
RFC 2119 키워드 대소문자 모호성. B. Leiba. IETF. 2017년 5월. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[service-workers]
Service Workers. Jake Archibald; Marijn Kruisselbrink. W3C. 2022년 7월 12일. W3C Candidate Recommendation. URL: https://www.w3.org/TR/service-workers/
[USBIF-HID-CLASS]
휴먼 인터페이스 장치(HID) 버전 1.11의 디바이스 클래스 정의. Mike Bergman 외. USB Implementers Forum. 2001년 5월 27일. Specification. URL: https://www.usb.org/document-library/device-class-definition-hid-111
[WEBIDL]
Web IDL 표준. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/

B.2 비규범 참고 문헌

[browserext]
브라우저 확장. Mike Pietraszak. W3C. 2016년 10월. Draft Community Group Report. URL: https://browserext.github.io/browserext/
[GAMEPAD]
Gamepad. Steve Agoston; Matthew Reynolds. W3C. 2024년 8월 9일. W3C Working Draft. URL: https://www.w3.org/TR/gamepad/
[pointerevents]
포인터 이벤트. Jacob Rossi; Matt Brubeck. W3C. 2019년 4월 4일. W3C Recommendation. URL: https://www.w3.org/TR/pointerevents/
[uievents]
UI 이벤트. Gary Kacmarcik; Travis Leithead. W3C. 2024년 9월 7일. W3C Working Draft. URL: https://www.w3.org/TR/uievents/
[USBIF-HID-USAGE]
Universal Serial Bus (USB) 버전 1.22의 HID Usage Tables. David Abzarian 외. USB Implementers Forum. 2021년 4월 6일. Specification. URL: https://www.usb.org/document-library/hid-usage-tables-122