Skip to content
Merged
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ all: index.html
index.html: index.bs
curl https://api.csswg.org/bikeshed/ -F [email protected] -F output=err
curl https://api.csswg.org/bikeshed/ -F [email protected] -F force=1 > index.html | tee

local:
bikeshed spec index.bs
89 changes: 74 additions & 15 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ spec:webidl;
type:dfn; text:new
spec:webxr-ar-module-1;
type:dfn; text:first-person observer view
spec:html; type:interface; text:Navigator
</pre>

<pre class="anchors">
Expand Down Expand Up @@ -333,36 +334,91 @@ When this method is invoked, it MUST run the following steps:
1. Let |promise| be [=a new Promise=] in the [=relevant realm=] of this {{XRSystem}}.
1. If |mode| is {{XRSessionMode/"inline"}}, [=/resolve=] |promise| with `true` and return it.
1. If the requesting document's origin is not allowed to use the "xr-spatial-tracking" [[#permissions-policy|permissions policy]], [=reject=] |promise| with a "{{SecurityError}}" {{DOMException}} and return it.
1. Run the following steps [=in parallel=]:
1. Let |device| be the result of [=ensure an immersive XR device is selected|ensuring an immersive XR device is selected=].
1. If |device| is `null`, [=/resolve=] |promise| with `false` and abort these steps.
1. If |device|'s [=list of supported modes=] does not [=list/contain=] |mode|, [=queue a task=] to [=/resolve=] |promise| with `false` and abort these steps.
1. [=queue a task=] to [=/resolve=] |promise| with `true`.
1. Check whether the session |mode| is supported as follows:
<dl class="switch">
: If the user agent and system are known to [=never support=] |mode| sessions
:: [=/Resolve=] |promise| with `false`.

: If the user agent and system are is known to [=usually support=] |mode| sessions
:: |promise| MAY be [=/resolved=] with `true` provided that all instances of this user agent [=indistinguishable by user-agent string=] produce the same result here.

: Otherwise
:: Run the following steps [=in parallel=]:
1. Let |device| be the result of [=ensure an immersive XR device is selected|ensuring an immersive XR device is selected=].
1. If |device| is null, [=/resolve=] |promise| with `false` and abort these steps.
1. If |device|'s [=list of supported modes=] does not [=list/contain=] |mode|, [=queue a task=] to [=/resolve=] |promise| with `false` and abort these steps.
1. [=request permission to use=] the [=powerful feature=] {{PermissionName/"xr-session-supported"}} with {{XRSessionSupportedPermissionDescriptor}} with {{XRSessionSupportedPermissionDescriptor/mode}} equal to |mode|. If it returns {{PermissionState/"denied"}} [=queue a task=] to [=/resolve=] |promise| with `false` and abort these steps.
1. [=queue a task=] to [=/resolve=] |promise| with `true`.

</dl>
1. Return |promise|.

</div>

Calling {{XRSystem/isSessionSupported()}} MUST NOT trigger device-selection UI as this would cause many sites to display XR-specific dialogs early in the document lifecycle without user activation. Additionally, calling {{XRSystem/isSessionSupported()}} MUST NOT interfere with any running XR applications on the system, and MUST NOT cause XR-related applications to launch such as system trays or storefronts.
<p class="note">
Note: The purpose of {{XRSystem/isSessionSupported()}} is not to report with perfect accuracy the user agent's ability to create an {{XRSession}}, but to inform the page whether or not advertising the ability to create sessions of the given mode is advised. A certain level of false-positives are expected, even when user agent checks for the presence of the necessary hardware/software prior to resolving the method. (For example, even if the appropriate hardware is present it may have given exclusive access to another application at the time a session is requested.)
</p>

It is expected that most pages with XR content will call {{XRSystem/isSessionSupported()}} early in the document lifecycle. As such, calling {{XRSystem/isSessionSupported()}} SHOULD avoid displaying any modal or otherwise intrusive UI. Calling {{XRSystem/isSessionSupported()}} MUST NOT trigger device-selection UI, MUST NOT interfere with any running XR applications on the system, and MUST NOT cause XR-related applications to launch such as system trays or storefronts.

<div class="example">
The following code checks to see if {{immersive-vr}} sessions are supported.

<pre highlight="js">
const supported = await navigator.xr.isSessionSupported('immersive-vr');
if (supported) {
// 'immersive-vr' sessions are supported.
// 'immersive-vr' sessions may be supported.
// Page should advertise support to the user.
} else {
// 'immersive-vr' sessions are not supported.
}
</pre>
</div>

<p class="note">
Note: The purpose of {{XRSystem/isSessionSupported()}} is not to report with perfect accuracy the user agent's ability to create an {{XRSession}}, but to inform the page whether or not advertising the ability to create sessions of the given mode is advised. A certain level of false-positives are expected, even when user agent checks for the presence of the necessary hardware/software prior to resolving the method. (For example, even if the appropriate hardware is present it may have given exclusive access to another application at the time a session is requested.)
<br/><br/>
Because {{XRSystem/isSessionSupported()}} can be called without user activation and without triggering any consent dialogs, it may be used as a fingerprinting vector despite the limited amount of information it reports. User agents that wish to minimize all fingerprinting while still enabling XR content may wish to have {{XRSystem/isSessionSupported()}} always report `true` for platforms which have any possibility of running the specified mode of XR content, regardless of whether or not the appropriate hardware or software is present. This comes at the cost of user ergonomics, as it will cause pages to advertise XR content to users that cannot view it.
</p>
### Fingerprinting considerations ### {#issessionsupported-fingerprinting}

Because {{XRSystem/isSessionSupported()}} can be called without user activation it may be used as a fingerprinting vector despite the limited amount of information it reports.

<dfn enum-value for="PermissionName">"xr-session-supported"</dfn> [=powerful feature=] gates access to the {{XRSystem/isSessionSupported()}} API in cases where there are fingerprinting concerns.

The {{PermissionName/"xr-session-supported"}}’s permission-related algorithms and types are defined as follows:


<dl>
<dt>[=permission descriptor type=]</dt>
<dd>

<pre class="idl">
dictionary XRSessionSupportedPermissionDescriptor: PermissionDescriptor {
XRSessionMode mode;
};
</pre>

{{PermissionDescriptor/name}} for {{XRPermissionDescriptor}} is {{PermissionName/"xr-session-supported"}}.


{{PermissionName/"xr-session-supported"}} may be granted automatically for some systems based on the criteria below.

A set of user agents is <dfn>indistinguishable by user-agent string</dfn> if they all report the same {{NavigatorID/userAgent}} and {{NavigatorID/appVersion}}. Such classes are typically identified by the browser version and platform/device being run on, but cannot be distinguished by the status of any connected external device. We can use the concept of user agents that are [=indistinguishable by user-agent string=] to properly assess fingerprinting risk.

Some user agents [=indistinguishable by user-agent string=] will <dfn>never support</dfn> sessions of a given {{XRSessionMode}}. <span class='note'>For example: User agents running on a model of phone that is known to not meet requirements for mobile AR support.</span> In these cases there is little fingerprinting risk in {{XRSystem/isSessionSupported()}} always reporting the {{XRSessionMode}} is not supported because every such device will consistently report the same value and it's assumed that device type and model can be inferred in other ways, such as through {{NavigatorID/userAgent}}. Thus, on such systems, the user-agent SHOULD automatically deny {{PermissionName/"xr-session-supported"}} for the relevant {{XRSessionMode}}.

Other user agents will [=indistinguishable by user-agent string=] <dfn>usually support</dfn> sessions of a given {{XRSessionMode}}. <span class='note'>For example: User agents known to support WebXR that run exclusively within VR headsets are likely to support {{XRSessionMode/"immersive-vr"}} sessions unless specifically blocked by the user.</span> In these cases reporting that the {{XRSessionMode}} is not supported, while accurate, would offer more uniquely identifying information about the user. As such reporting that the {{XRSessionMode}} is always available and allowing {{XRSystem/requestSession()}} to fail is more privacy-preserving while likely not being a source of confusion for the user. On such systems, the user-agent SHOULD automatically grant {{PermissionName/"xr-session-supported"}} for the relevant {{XRSessionMode}}.

User agents [=indistinguishable by user-agent string=] for which availability of XR capabilities is highly variable, such as desktop systems which support XR peripherals, present the highest fingerprinting risk. User agents on such devices SHOULD NOT automatically grant {{PermissionName/"xr-session-supported"}} in a way that allows the {{isSessionSupported()}} API to provide additional fingerprinting bits.


<div class=note>
Note: Some acceptable approaches to handle such cases are as follows:

- Always judging [=explicit consent=] for {{PermissionName/"xr-session-supported"}} (with a potentially cached permissions prompt or similar) when {{XRSystem/isSessionSupported()}} is called.
- Automatically granting {{PermissionName/"xr-session-supported"}} but having {{XRSystem/isSessionSupported()}} always report `true` even on platforms which do not consistently have XR capabilities available, regardless of whether or not the appropriate hardware or software is present. This comes at the cost of user ergonomics, as it will cause pages to advertise XR content to users that cannot view it.
- Have {{XRSystem/isSessionSupported()}} request [=explicit consent=] for {{PermissionName/"xr-session-supported"}} when the appropriate hardware is present, and when such hardware is _not_ present, return `false` after an appropriately random length of time. In such an implementation content must not be able to distinguish between cases where the user agent was not connected to XR hardware and cases where the user agent was connected to XR hardware but the user declined to provide [=explicit consent=].

</div>

Whatever the technique chosen, it MUST NOT reveal additional knowledge about connected XR hardware without [=explicit consent=].


The {{XRSystem}} object has a <dfn>pending immersive session</dfn> boolean, which MUST be initially `false`, an <dfn>active immersive session</dfn>, which MUST be initially `null`, and a <dfn>list of inline sessions</dfn>, which MUST be initially empty.

Expand Down Expand Up @@ -2406,7 +2462,9 @@ In the context of XR, <dfn>sensitive information</dfn> includes, but is not limi
User intention {#user-intention}
--------------

It is often necessary to be sure of <dfn>user intent</dfn> before exposing sensitive information or allowing actions with a significant effect on the user's experience. This intent may be communicated or observed in a number of ways.
<dfn>User intent</dfn> for a given action is a signal from the user that such an action was intentional and has their consent.

It is often necessary to be sure of [=user intent=] before exposing sensitive information or allowing actions with a significant effect on the user's experience. This intent may be communicated or observed in a number of ways.

Note: A common way of determining user intent is by [=transient activation=] of a UI control, typically an "enter VR" button. Since activation is transient,
the [=browsing context=] requesting an XR session must be an [=ancestor=] or a [=same origin-domain=] [=descendant=] of the context containing the UI control, and must recently
Expand All @@ -2419,9 +2477,10 @@ have been the [=active document=] of the browsing context.
In some environments a page may be presented as an application, installed with the express intent of running immersive content. In that case <dfn>launching a web application</dfn> MAY also serve as an indication of [=user intent=].

### Implicit and Explicit consent ### {#user-consent}
A user agent MAY use <dfn>implicit consent</dfn> based, for example, on the install status of a web application or frequency and recency of visits. Given the sensitivity of XR data, caution is strongly advised when relying on implicit signals.

It is often useful to get <dfn>explicit consent</dfn> from the user before exposing [=sensitive information=]. When gathering explicit user consent, user agents present an explanation of what is being requested and provide users the option to decline. Requests for user consent can be presented in many visual forms based on the features being protected and user agent choice.
<dfn>Implicit consent</dfn> is when the user agent makes a judgement on the consent of a user without explicitly asking for it, for example, based on the install status of a web application or frequency and recency of visits. Given the sensitivity of XR data, caution is strongly advised when relying on implicit signals.

<dfn>Explicit consent</dfn> is when the user agent makes a judgement on the consent of a user based on having explicitly asked for it. When gathering [=explicit consent=], user agents present an explanation of what is being requested and provide users the option to decline. Requests for user consent can be presented in many visual forms based on the features being protected and user agent choice. Install status of a web application MAY count as a signal of [=explicit consent=] provided some form of [=explicit consent=] is requested at install time.

### Duration of consent ### {#consent-duration}
It is recommended that once [=explicit consent=] is granted for a specific [=/origin=] that this consent persist until the [=/browsing context=] has ended. User agents may choose to lengthen or shorten this consent duration based upon implicit or explicit signals of [=user intent=], but implementations are advised to exercise caution when deviating from this recommendation, particularly when relying on implicit signals. For example, it may be appropriate for a web application installed with the express intent of running immersive content to persist the user's consent, but not for an installed web application where immersive content is a secondary feature.
Expand Down