From 8cd20fafcbada9c8f44f17c2b5a3179c07939180 Mon Sep 17 00:00:00 2001 From: Brandon Jones Date: Thu, 28 Sep 2017 13:48:15 -0700 Subject: [PATCH 1/6] First pass at refactoring getDevices into requestDevice Need to add a section about how to use the filters. --- explainer.md | 57 +++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/explainer.md b/explainer.md index c7fdb222..71acff0d 100644 --- a/explainer.md +++ b/explainer.md @@ -42,43 +42,35 @@ VR provides an interesting canvas for artists looking to explore the possibiliti The basic steps any WebVR application will go through are: - 1. Request a list of the available VR devices. - 2. Checks to see if the desired device supports the presentation modes the application needs. - 3. If so, application advertises VR functionality to the user. - 4. User performs an action that indicates they want to enter VR mode. - 5. Request a VR session to present VR content with. - 6. Begin a render loop that produces graphical frames to be displayed on the VR device. - 7. Continue producing frames until the user indicates that they wish to exit VR mode. - 8. End the VR session. + 1. Request a VR device that supports the presentation modes the application needs. + 1. If a device is available, application advertises VR functionality to the user. + 1. User performs an action that indicates they want to enter VR mode. + 1. Request a VR session from the device to present VR content with. + 1. Begin a render loop that produces graphical frames to be displayed on the VR device. + 1. Continue producing frames until the user indicates that they wish to exit VR mode. + 1. End the VR session. -### Device enumeration +### Acquiring a Device -The first thing that any VR-enabled page will want to do is enumerate the available VR hardware and, if present, advertise VR functionality to the user. +The first thing that any VR-enabled page will want to do is request a `VRDevice` and, if present, advertise VR functionality to the user. -`navigator.vr.getDevices` returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to a list of available devices. Each `VRDevice` represents a physical unit of VR hardware that can present imagery to the user somehow, referred to here as a "VR hardware device". On desktop clients this will usually be a headset peripheral; on mobile clients it may represent the mobile device itself in conjunction with a viewer harness (e.g., Google Cardboard or Samsung Gear VR). It may also represent devices without stereo presentation capabilities but more advanced tracking, such as Tango devices. +`navigator.vr.requestDevice` returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to an available device which matches the given filter criteria. A `VRDevice` represents a physical unit of VR hardware that can present imagery to the user somehow, referred to here as a "VR hardware device". On desktop clients this will usually be a headset peripheral; on mobile clients it may represent the mobile device itself in conjunction with a viewer harness (e.g., Google Cardboard or Samsung Gear VR). It may also represent devices without stereo presentation capabilities but more advanced tracking, such as Tango devices. ```js let vrDevice = null; -navigator.vr.getDevices().then(devices => { - if (devices.length > 0) { - // Use the first device in the array if one is available. If multiple - // devices are present, you may want to provide the user a way of choosing - // which device to use. - vrDevice = devices[0]; - onVRAvailable(); - } else { - // Could not find any VR hardware connected. - } -}, err => { - // An error occurred querying VR hardware. May be the result of blocked - // permissions by a parent frame. +navigator.vr.requestDevice().then((device) => { + vrDevice = device; + onVRAvailable(); +}, (err) => { + // Could not find any available VR hardware or an error occurred querying VR + // hardware. }); ``` ### Sessions -A `VRDevice` indicates the presence of a VR hardware device but provides very little information about it outside of a name that could be used to select it from a list. In order to do anything that involves the hardware's presentation or tracking capabilities the application will need to request a `VRSession` from the `VRDevice`. +A `VRDevice` indicates the presence of a VR hardware device but provides very little information about it. In order to do anything that involves the hardware's presentation or tracking capabilities the application will need to request a `VRSession` from the `VRDevice`. Sessions can be created with one of two levels of access: @@ -622,11 +614,17 @@ partial interface Navigator { readonly attribute VR vr; }; -[SecureContext, Exposed=Window] interface VR : EventTarget { - attribute EventHandler ondeviceconnect; - attribute EventHandler ondevicedisconnect; +dictionary VRDeviceFilter { + boolean exclusive = false; +}; + +dictionary VRDeviceRequestOptions { + required sequence filters; +}; - Promise> getDevices(); +[SecureContext, Exposed=Window] interface VR : EventTarget { + attribute EventHandler ondeviceschanged; + Promise requestDevice(optional VRDeviceRequestOptions options); }; // @@ -634,7 +632,6 @@ partial interface Navigator { // [SecureContext, Exposed=Window] interface VRDevice : EventTarget { - readonly attribute DOMString deviceName; readonly attribute boolean isExternal; Promise supportsSession(optional VRSessionCreationOptions parameters); From d4df9c0b4e42c4e4efc91a198d83be6d3c95cfbc Mon Sep 17 00:00:00 2001 From: Brandon Jones Date: Wed, 18 Oct 2017 09:10:07 -0700 Subject: [PATCH 2/6] Addressing feedback from @cvan and implementers call. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removing filters for the moment, since they’re easy to add in after the fact and we’re still not clear on what we want to allow developers to filter on. --- explainer.md | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/explainer.md b/explainer.md index 71acff0d..31c81510 100644 --- a/explainer.md +++ b/explainer.md @@ -54,20 +54,21 @@ The basic steps any WebVR application will go through are: The first thing that any VR-enabled page will want to do is request a `VRDevice` and, if present, advertise VR functionality to the user. -`navigator.vr.requestDevice` returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to an available device which matches the given filter criteria. A `VRDevice` represents a physical unit of VR hardware that can present imagery to the user somehow, referred to here as a "VR hardware device". On desktop clients this will usually be a headset peripheral; on mobile clients it may represent the mobile device itself in conjunction with a viewer harness (e.g., Google Cardboard or Samsung Gear VR). It may also represent devices without stereo presentation capabilities but more advanced tracking, such as Tango devices. +`navigator.vr.requestDevice` returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to a `VRDevice` if one is available. A `VRDevice` represents a physical unit of VR hardware that can present imagery to the user somehow, referred to here as a "VR hardware device". On desktop clients this will usually be a headset peripheral; on mobile clients it may represent the mobile device itself in conjunction with a viewer harness (e.g., Google Cardboard or Samsung Gear VR). It may also represent devices without stereo presentation capabilities but more advanced tracking, such as ARCore/ARKit enabled devices. ```js -let vrDevice = null; - -navigator.vr.requestDevice().then((device) => { - vrDevice = device; - onVRAvailable(); +navigator.vr.requestDevice().then(device => { + onVRAvailable(device); }, (err) => { // Could not find any available VR hardware or an error occurred querying VR // hardware. }); ``` +If there are multiple VR hardware devices available the UA will need to pick which one to return. The UA is allowed to use any criteria it wishes to select which device is returned, including settings UI that allows users to manage device priority. Calling `requestDevice` should not trigger device selection UI, however, as this would cause many sites to display VR-specific dialogs early in the page lifetime when the user has not made any indication that they wish to use VR features. + +Future iterations of the API may add filter criteria to `requestDevice`. + ### Sessions A `VRDevice` indicates the presence of a VR hardware device but provides very little information about it. In order to do anything that involves the hardware's presentation or tracking capabilities the application will need to request a `VRSession` from the `VRDevice`. @@ -85,7 +86,11 @@ If a `VRDevice` is available and able to create an exclusive session, the applic In the following examples we will focus on using exclusive sessions, and cover non-exclusive session use in the [`Advanced Functionality`](#non-exclusive-sessions-magic-windows) section. With that in mind, we ask here if the `VRDevice` supports sessions with `exclusive` access (the default), since we want the ability to display imagery on the headset. ```js -async function onVRAvailable() { +let vrDevice = null; + +async function onVRAvailable(device) { + vrDevice = device; + // Most (but not all) VRDevices are capable of granting exclusive access to // the device, which is necessary to show imagery in a headset. If the device // has that capability the page will want to add an "Enter VR" button (similar @@ -614,17 +619,9 @@ partial interface Navigator { readonly attribute VR vr; }; -dictionary VRDeviceFilter { - boolean exclusive = false; -}; - -dictionary VRDeviceRequestOptions { - required sequence filters; -}; - [SecureContext, Exposed=Window] interface VR : EventTarget { - attribute EventHandler ondeviceschanged; - Promise requestDevice(optional VRDeviceRequestOptions options); + attribute EventHandler ondevicechanged; + Promise requestDevice(); }; // From fb2af73b8c1da3dee091808a437b319bc9ad3543 Mon Sep 17 00:00:00 2001 From: Brandon Jones Date: Wed, 18 Oct 2017 22:19:28 -0700 Subject: [PATCH 3/6] Addressing more of @cvan's feedback. --- explainer.md | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/explainer.md b/explainer.md index 31c81510..4e32449b 100644 --- a/explainer.md +++ b/explainer.md @@ -42,36 +42,47 @@ VR provides an interesting canvas for artists looking to explore the possibiliti The basic steps any WebVR application will go through are: - 1. Request a VR device that supports the presentation modes the application needs. + 1. Request a VR device. 1. If a device is available, application advertises VR functionality to the user. - 1. User performs an action that indicates they want to enter VR mode. - 1. Request a VR session from the device to present VR content with. - 1. Begin a render loop that produces graphical frames to be displayed on the VR device. + 1. Request a VR session from the device in response to a user activation event. + 1. Use the session to run a render loop that produces graphical frames to be displayed on the VR device. 1. Continue producing frames until the user indicates that they wish to exit VR mode. 1. End the VR session. ### Acquiring a Device -The first thing that any VR-enabled page will want to do is request a `VRDevice` and, if present, advertise VR functionality to the user. +The first thing that any VR-enabled page will want to do is request a `VRDevice` and, if one is available, advertise VR functionality to the user. (For example, by adding a button to the DOM that the user can click to start VR content.) -`navigator.vr.requestDevice` returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to a `VRDevice` if one is available. A `VRDevice` represents a physical unit of VR hardware that can present imagery to the user somehow, referred to here as a "VR hardware device". On desktop clients this will usually be a headset peripheral; on mobile clients it may represent the mobile device itself in conjunction with a viewer harness (e.g., Google Cardboard or Samsung Gear VR). It may also represent devices without stereo presentation capabilities but more advanced tracking, such as ARCore/ARKit enabled devices. +`navigator.vr.requestDevice` returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to a `VRDevice` if one is available. In no `VRDevice` is available it will resolve to null. The promise will be rejected if an error occurs, such as the the page not having the appropriate permissions to access VR capabilities. + +A `VRDevice` represents a physical unit of VR hardware that can present imagery to the user somehow, referred to here as a "VR hardware device". On desktop clients this will usually be a headset peripheral; on mobile clients it may represent the mobile device itself in conjunction with a viewer harness (e.g., Google Cardboard/Daydream or Samsung GearVR). It may also represent devices without stereo-presentation capabilities but with more advanced tracking, such as ARCore/ARKit-compatible devices. ```js -navigator.vr.requestDevice().then(device => { - onVRAvailable(device); -}, (err) => { - // Could not find any available VR hardware or an error occurred querying VR - // hardware. -}); +function checkForVR() { + navigator.vr.requestDevice().then(device => { + if (device) { + onVRAvailable(device); + } + }, err => { + // An error occurred while requesting a VRDevice. + console.error('Unable to request a VR device.'); + }); +} ``` -If there are multiple VR hardware devices available the UA will need to pick which one to return. The UA is allowed to use any criteria it wishes to select which device is returned, including settings UI that allows users to manage device priority. Calling `requestDevice` should not trigger device selection UI, however, as this would cause many sites to display VR-specific dialogs early in the page lifetime when the user has not made any indication that they wish to use VR features. +Future revisions of the API may add filter criteria to `navigator.vr.requestDevice`. -Future iterations of the API may add filter criteria to `requestDevice`. +> **Non-normative Note:** If there are multiple VR devices available, the UA will need to pick which one to return. The UA is allowed to use any criteria it wishes to select which device is returned, including settings UI that allows users to manage device priority. Calling `navigator.vr.requestDevice` should not trigger device selection UI, however, as this would cause many sites to display VR-specific dialogs early in the document lifecycle without and user activation. + +It's possible that even if no VR device is available initially one may become available while the application is running, or that a previously available device becomes unavailable. This will be most common with PC peripherals that can be connected at disconnected at any time. To respond to these changes pages can listen to the `devicechange` event on the `navigator.vr` object. + +```js +navigator.vr.addEventListener('devicechange', checkForVR); +``` ### Sessions -A `VRDevice` indicates the presence of a VR hardware device but provides very little information about it. In order to do anything that involves the hardware's presentation or tracking capabilities the application will need to request a `VRSession` from the `VRDevice`. +A `VRDevice` only indicates the availabilty of a VR device. In order to do anything that involves the device's presentation or tracking capabilities, the application will need to request a `VRSession` from the `VRDevice`. Sessions can be created with one of two levels of access: @@ -620,7 +631,7 @@ partial interface Navigator { }; [SecureContext, Exposed=Window] interface VR : EventTarget { - attribute EventHandler ondevicechanged; + attribute EventHandler ondevicechange; Promise requestDevice(); }; From c44dcaa3edeebb84df915674d93539dad24b0d9b Mon Sep 17 00:00:00 2001 From: Brandon Jones Date: Thu, 19 Oct 2017 09:33:00 -0700 Subject: [PATCH 4/6] A few more @cvan tweaks. Thanks for iterating on the text with me! --- explainer.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/explainer.md b/explainer.md index 4e32449b..d2900254 100644 --- a/explainer.md +++ b/explainer.md @@ -44,16 +44,16 @@ The basic steps any WebVR application will go through are: 1. Request a VR device. 1. If a device is available, application advertises VR functionality to the user. - 1. Request a VR session from the device in response to a user activation event. + 1. Request a VR session from the device in response to a [user-activation event](https://html.spec.whatwg.org/multipage/interaction.html#activation). 1. Use the session to run a render loop that produces graphical frames to be displayed on the VR device. 1. Continue producing frames until the user indicates that they wish to exit VR mode. 1. End the VR session. ### Acquiring a Device -The first thing that any VR-enabled page will want to do is request a `VRDevice` and, if one is available, advertise VR functionality to the user. (For example, by adding a button to the DOM that the user can click to start VR content.) +The first thing that any VR-enabled page will want to do is request a `VRDevice` and, if one is available, advertise VR functionality to the user. (For example, by adding a button to the page that the user can click to start VR content.) -`navigator.vr.requestDevice` returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to a `VRDevice` if one is available. In no `VRDevice` is available it will resolve to null. The promise will be rejected if an error occurs, such as the the page not having the appropriate permissions to access VR capabilities. +`navigator.vr.requestDevice` returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to a `VRDevice` if one is available. If no `VRDevice` is available, it will resolve to null. The promise will be rejected if an error occurs, such as the the page not having the appropriate permissions to access VR capabilities. A `VRDevice` represents a physical unit of VR hardware that can present imagery to the user somehow, referred to here as a "VR hardware device". On desktop clients this will usually be a headset peripheral; on mobile clients it may represent the mobile device itself in conjunction with a viewer harness (e.g., Google Cardboard/Daydream or Samsung GearVR). It may also represent devices without stereo-presentation capabilities but with more advanced tracking, such as ARCore/ARKit-compatible devices. @@ -65,7 +65,7 @@ function checkForVR() { } }, err => { // An error occurred while requesting a VRDevice. - console.error('Unable to request a VR device.'); + console.error('Unable to request a VR device:', err); }); } ``` @@ -74,7 +74,7 @@ Future revisions of the API may add filter criteria to `navigator.vr.requestDevi > **Non-normative Note:** If there are multiple VR devices available, the UA will need to pick which one to return. The UA is allowed to use any criteria it wishes to select which device is returned, including settings UI that allows users to manage device priority. Calling `navigator.vr.requestDevice` should not trigger device selection UI, however, as this would cause many sites to display VR-specific dialogs early in the document lifecycle without and user activation. -It's possible that even if no VR device is available initially one may become available while the application is running, or that a previously available device becomes unavailable. This will be most common with PC peripherals that can be connected at disconnected at any time. To respond to these changes pages can listen to the `devicechange` event on the `navigator.vr` object. +It's possible that even if no VR device is available initially, one may become available while the application is running, or that a previously available device becomes unavailable. This will be most common with PC peripherals that can be connected or disconnected at any time. Pages can listen to the `devicechange` event emitted on `navigator.vr` to respond to changes in device availability after the page loads. (VR devices already available when the page loads will not cause a `devicechange` event to be fired.) ```js navigator.vr.addEventListener('devicechange', checkForVR); @@ -82,7 +82,7 @@ navigator.vr.addEventListener('devicechange', checkForVR); ### Sessions -A `VRDevice` only indicates the availabilty of a VR device. In order to do anything that involves the device's presentation or tracking capabilities, the application will need to request a `VRSession` from the `VRDevice`. +A `VRDevice` indicates only the availability of a VR device. In order to do anything that involves the device's presentation or tracking capabilities, the application will need to request a `VRSession` from the `VRDevice`. Sessions can be created with one of two levels of access: From 66dde82b93fbedf9cb64ed771f1465c75bffe249 Mon Sep 17 00:00:00 2001 From: Brandon Jones Date: Thu, 19 Oct 2017 15:45:44 -0700 Subject: [PATCH 5/6] A few finishing touches for the requestDevice change. --- explainer.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/explainer.md b/explainer.md index d2900254..9942736d 100644 --- a/explainer.md +++ b/explainer.md @@ -44,7 +44,7 @@ The basic steps any WebVR application will go through are: 1. Request a VR device. 1. If a device is available, application advertises VR functionality to the user. - 1. Request a VR session from the device in response to a [user-activation event](https://html.spec.whatwg.org/multipage/interaction.html#activation). + 1. Request an exclusive VR session from the device in response to a [user-activation event](https://html.spec.whatwg.org/multipage/interaction.html#activation). 1. Use the session to run a render loop that produces graphical frames to be displayed on the VR device. 1. Continue producing frames until the user indicates that they wish to exit VR mode. 1. End the VR session. @@ -55,7 +55,7 @@ The first thing that any VR-enabled page will want to do is request a `VRDevice` `navigator.vr.requestDevice` returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to a `VRDevice` if one is available. If no `VRDevice` is available, it will resolve to null. The promise will be rejected if an error occurs, such as the the page not having the appropriate permissions to access VR capabilities. -A `VRDevice` represents a physical unit of VR hardware that can present imagery to the user somehow, referred to here as a "VR hardware device". On desktop clients this will usually be a headset peripheral; on mobile clients it may represent the mobile device itself in conjunction with a viewer harness (e.g., Google Cardboard/Daydream or Samsung GearVR). It may also represent devices without stereo-presentation capabilities but with more advanced tracking, such as ARCore/ARKit-compatible devices. +A `VRDevice` represents a physical unit of VR hardware that can present imagery to the user somehow, referred to here as a "VR hardware device". On desktop clients this will usually be a headset peripheral; on mobile clients it may represent the mobile device itself in conjunction with a viewer harness (e.g., Google Cardboard/Daydream or Samsung Gear VR). It may also represent devices without stereo-presentation capabilities but with more advanced tracking, such as ARCore/ARKit-compatible devices. ```js function checkForVR() { @@ -72,7 +72,7 @@ function checkForVR() { Future revisions of the API may add filter criteria to `navigator.vr.requestDevice`. -> **Non-normative Note:** If there are multiple VR devices available, the UA will need to pick which one to return. The UA is allowed to use any criteria it wishes to select which device is returned, including settings UI that allows users to manage device priority. Calling `navigator.vr.requestDevice` should not trigger device selection UI, however, as this would cause many sites to display VR-specific dialogs early in the document lifecycle without and user activation. +> **Non-normative Note:** If there are multiple VR devices available, the UA will need to pick which one to return. The UA is allowed to use any criteria it wishes to select which device is returned, including settings UI that allows users to manage device priority. Calling `navigator.vr.requestDevice` should not trigger device-selection UI, however, as this would cause many sites to display VR-specific dialogs early in the document lifecycle without and user activation. It's possible that even if no VR device is available initially, one may become available while the application is running, or that a previously available device becomes unavailable. This will be most common with PC peripherals that can be connected or disconnected at any time. Pages can listen to the `devicechange` event emitted on `navigator.vr` to respond to changes in device availability after the page loads. (VR devices already available when the page loads will not cause a `devicechange` event to be fired.) From 433b0a404c3ed82ff63fd3e0f918b64e7ebf7ebf Mon Sep 17 00:00:00 2001 From: Brandon Jones Date: Thu, 19 Oct 2017 20:41:04 -0700 Subject: [PATCH 6/6] Die, 'and', die! --- explainer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/explainer.md b/explainer.md index 9942736d..9ab68017 100644 --- a/explainer.md +++ b/explainer.md @@ -40,7 +40,7 @@ VR provides an interesting canvas for artists looking to explore the possibiliti ## Lifetime of a VR web app -The basic steps any WebVR application will go through are: +The basic steps most WebVR applications will go through are: 1. Request a VR device. 1. If a device is available, application advertises VR functionality to the user. @@ -72,7 +72,7 @@ function checkForVR() { Future revisions of the API may add filter criteria to `navigator.vr.requestDevice`. -> **Non-normative Note:** If there are multiple VR devices available, the UA will need to pick which one to return. The UA is allowed to use any criteria it wishes to select which device is returned, including settings UI that allows users to manage device priority. Calling `navigator.vr.requestDevice` should not trigger device-selection UI, however, as this would cause many sites to display VR-specific dialogs early in the document lifecycle without and user activation. +> **Non-normative Note:** If there are multiple VR devices available, the UA will need to pick which one to return. The UA is allowed to use any criteria it wishes to select which device is returned, including settings UI that allows users to manage device priority. Calling `navigator.vr.requestDevice` should not trigger device-selection UI, however, as this would cause many sites to display VR-specific dialogs early in the document lifecycle without user activation. It's possible that even if no VR device is available initially, one may become available while the application is running, or that a previously available device becomes unavailable. This will be most common with PC peripherals that can be connected or disconnected at any time. Pages can listen to the `devicechange` event emitted on `navigator.vr` to respond to changes in device availability after the page loads. (VR devices already available when the page loads will not cause a `devicechange` event to be fired.)