diff --git a/index.bs b/index.bs index 80bacb6..1f05354 100644 --- a/index.bs +++ b/index.bs @@ -621,6 +621,9 @@ The {{USB/ondisconnect}} attribute is an Event handler IDL attribute for the The {{USB/getDevices()}} method, when invoked, MUST return a new {{Promise}} and run the following steps in parallel: + 1. Let |document| be this's [=relevant global object=]'s + [=associated Document=], or null if there is no associated + {{Document}}. 1. Let |storage| be: 1. The {{USBPermissionStorage}} object in the script execution environment of the associated [=service worker client=], if [=this=]'s [=relevant @@ -631,7 +634,7 @@ run the following steps in parallel: |enumerationResult|. 2. Let |devices| be a new empty {{Array}}. 3. For each |device| in |enumerationResult|: - 1. If |device| is [=blocklisted=], [=iteration/continue=]. + 1. If |device| is [=blocklisted=] for |document|, [=iteration/continue=]. 1. If this is the first call to this method, check permissions for |device| with |storage|. 2. Search for an element |allowedDevice| in @@ -658,10 +661,10 @@ The {{USB/requestDevice()}} method, when invoked, MUST run the following steps: throw a {{NotFoundError}} and abort these steps. 2. Return |result|.{{USBPermissionResult/devices}}[0]. -To request the "usb" permission, given a {{USBPermissionStorage}} -|storage|, a {{USBPermissionDescriptor}} |options| and a {{USBPermissionResult}} -|status|, the UA MUST return a new {{Promise}} |promise| and run the following -steps in parallel: +To request the "usb" permission, given a {{Document}} |document|, a +{{USBPermissionStorage}} |storage|, a {{USBPermissionDescriptor}} |options| and +a {{USBPermissionResult}} |status|, the UA MUST return a new {{Promise}} +|promise| and run the following steps in parallel: 1. For each |filter| in |options|.{{USBPermissionDescriptor/filters}} if |filter| @@ -677,7 +680,8 @@ steps in parallel: 4. Set |status|.{{PermissionStatus/state}} to "ask". 5. Enumerate all devices attached to the system. Let this result be |enumerationResult|. - 1. Remove devices from |enumerationResult| if they are [=blocklisted=]. + 1. Remove devices from |enumerationResult| if they are [=blocklisted=] for + |document|. 6. Remove devices from |enumerationResult| if they do not match a device filter in |options|.{{USBPermissionDescriptor/filters}}. 7. Remove devices from |enumerationResult| if they match a device filter @@ -1309,8 +1313,15 @@ All USB devices MUST have a default control pipe which is with a {{NotFoundError}} and abort these steps. 1. If this.{{USBDevice/[[claimedInterface]]}}[|interfaceIndex|] is true, resolve |promise| and abort these steps. - 1. If |interfaces|[|interfaceIndex|].{{USBInterface/[[isProtectedClass]]}} is true, - [=reject=] |promise| with a {{SecurityError}} and abort these steps. + 1. Let |unrestricted| be false. + 1. Let |document| be this's [=relevant global object=]'s [=associated Document=], or + null if there is no associated {{Document}}. + 1. If |document| is not null and |document| is [=allowed to use=] the + [=policy-controlled feature=] named "usb-unrestricted", set |unrestricted| to + true. + 1. If |interfaces|[|interfaceIndex|].{{USBInterface/[[isProtectedClass]]}} is true + and |unrestricted| is false, [=reject=] |promise| with a {{SecurityError}} and + abort these steps. 1. Perform the necessary platform-specific steps to request exclusive control over |interfaces|[|interfaceIndex|] for the current execution context. If this fails, reject |promise| with a {{NetworkError}} and abort these steps. @@ -2349,9 +2360,12 @@ The USB blocklist is the result of [=parsing the blocklist=] at The UA should re-fetch the blocklist periodically, but it’s unspecified how often. -A {{USBDevice}} |device| is blocklisted if the following steps return -"blocked": +A {{USBDevice}} |device| is blocklisted for a {{Document}} |document| +if the following steps return "blocked": + 1. If |document| is not null and |document| is [=allowed to use=] + the [=policy-controlled feature=] named "usb-unrestricted", + return "not blocked". 1. [=list/For each=] |entry| of the [=USB blocklist=]: 1. If |device|.{{USBDevice/vendorId}} is not equal to |entry|.{{USBBlocklistEntry/idVendor}}, [=iteration/continue=]. @@ -2374,6 +2388,18 @@ is exposed on the {{Navigator}} object. The default allowlist for this feature is ["self"]. +This specification defines a second policy-controlled feature, identified +by the token "usb-unrestricted", that controls whether blocklisted +USB devices and device interfaces with protected classes can be accessed. This +feature MUST only be enabled for Isolated Web Apps +that declare the feature in the Web Application Manifest [[APPMANIFEST]]. + +The default allowlist for this feature is ["self"]. +Typically this would imply that the feature is allowed in {{Document}}s in +[=top-level traversables=] by default. However, due to the requirement that this +feature is only enabled for Isolated Web Apps with the feature declared in the +manifest, the effective default allowlist is ["none"]. + ## Permission API ## {#permission-api} The [[permissions]] API provides a uniform way for websites to request