aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/script/dom/webidls/XR.webidl4
-rw-r--r--components/script/dom/webidls/XRTest.webidl3
-rw-r--r--components/script/dom/xr.rs56
-rw-r--r--components/script/dom/xrtest.rs11
-rw-r--r--tests/wpt/metadata/webxr/xrDevice_requestSession_immersive_unsupported.https.html.ini4
-rw-r--r--tests/wpt/metadata/webxr/xrSession_features_deviceSupport.https.html.ini3
6 files changed, 66 insertions, 15 deletions
diff --git a/components/script/dom/webidls/XR.webidl b/components/script/dom/webidls/XR.webidl
index 2bee5c07cd8..8b0311f0c3f 100644
--- a/components/script/dom/webidls/XR.webidl
+++ b/components/script/dom/webidls/XR.webidl
@@ -25,8 +25,8 @@ enum XRSessionMode {
};
dictionary XRSessionInit {
- sequence<DOMString> requiredFeatures;
- sequence<DOMString> optionalFeatures;
+ sequence<any> requiredFeatures;
+ sequence<any> optionalFeatures;
};
partial interface XR {
diff --git a/components/script/dom/webidls/XRTest.webidl b/components/script/dom/webidls/XRTest.webidl
index a190fd75472..914bcb2d54d 100644
--- a/components/script/dom/webidls/XRTest.webidl
+++ b/components/script/dom/webidls/XRTest.webidl
@@ -23,6 +23,9 @@ dictionary FakeXRDeviceInit {
required boolean supportsImmersive;
required sequence<FakeXRViewInit> views;
+ // this is actually sequence<any>, but we don't support
+ // non-string features anyway
+ sequence<DOMString> supportedFeatures;
boolean supportsUnbounded = false;
// Whether the space supports tracking in inline sessions
boolean supportsTrackingInInline = true;
diff --git a/components/script/dom/xr.rs b/components/script/dom/xr.rs
index 5804918a532..a2c4fd059f0 100644
--- a/components/script/dom/xr.rs
+++ b/components/script/dom/xr.rs
@@ -8,11 +8,13 @@ use crate::dom::bindings::codegen::Bindings::VRDisplayBinding::VRDisplayMethods;
use crate::dom::bindings::codegen::Bindings::XRBinding;
use crate::dom::bindings::codegen::Bindings::XRBinding::XRSessionInit;
use crate::dom::bindings::codegen::Bindings::XRBinding::{XRMethods, XRSessionMode};
+use crate::dom::bindings::conversions::{ConversionResult, FromJSValConvertible};
use crate::dom::bindings::error::Error;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
+use crate::dom::bindings::trace::RootedTraceableBox;
use crate::dom::event::Event;
use crate::dom::eventtarget::EventTarget;
use crate::dom::gamepad::Gamepad;
@@ -33,7 +35,7 @@ use std::cell::Cell;
use std::rc::Rc;
use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVREvent, WebVRMsg};
use webvr_traits::{WebVRGamepadData, WebVRGamepadEvent, WebVRGamepadState};
-use webxr_api::{Error as XRError, Frame, Session, SessionMode};
+use webxr_api::{Error as XRError, Frame, Session, SessionInit, SessionMode};
#[dom_struct]
pub struct XR {
@@ -154,13 +156,16 @@ impl XRMethods for XR {
}
/// https://immersive-web.github.io/webxr/#dom-xr-requestsession
+ #[allow(unsafe_code)]
fn RequestSession(
&self,
mode: XRSessionMode,
- _: &XRSessionInit,
+ init: RootedTraceableBox<XRSessionInit>,
comp: InCompartment,
) -> Rc<Promise> {
- let promise = Promise::new_in_current_compartment(&self.global(), comp);
+ let global = self.global();
+ let window = global.as_window();
+ let promise = Promise::new_in_current_compartment(&global, comp);
if mode != XRSessionMode::Inline {
if !ScriptThread::is_user_interacting() {
@@ -176,11 +181,48 @@ impl XRMethods for XR {
self.set_pending();
}
+ let mut required_features = vec![];
+ let mut optional_features = vec![];
+ let cx = global.get_cx();
+
+ if let Some(ref r) = init.requiredFeatures {
+ for feature in r {
+ unsafe {
+ if let Ok(ConversionResult::Success(s)) =
+ String::from_jsval(*cx, feature.handle(), ())
+ {
+ required_features.push(s)
+ } else {
+ warn!("Unable to convert required feature to string");
+ promise.reject_error(Error::NotSupported);
+ return promise;
+ }
+ }
+ }
+ }
+
+ if let Some(ref o) = init.optionalFeatures {
+ for feature in o {
+ unsafe {
+ if let Ok(ConversionResult::Success(s)) =
+ String::from_jsval(*cx, feature.handle(), ())
+ {
+ optional_features.push(s)
+ } else {
+ warn!("Unable to convert optional feature to string");
+ }
+ }
+ }
+ }
+
+ let init = SessionInit {
+ required_features,
+ optional_features,
+ };
+
let promise = Promise::new_in_current_compartment(&self.global(), comp);
let mut trusted = Some(TrustedPromise::new(promise.clone()));
let this = Trusted::new(self);
- let global = self.global();
- let window = global.as_window();
let (task_source, canceller) = window
.task_manager()
.dom_manipulation_task_source_with_canceller();
@@ -210,7 +252,7 @@ impl XRMethods for XR {
);
window
.webxr_registry()
- .request_session(mode.into(), sender, frame_sender);
+ .request_session(mode.into(), init, sender, frame_sender);
promise
}
@@ -232,7 +274,7 @@ impl XR {
let session = match response {
Ok(session) => session,
Err(_) => {
- promise.reject_native(&());
+ promise.reject_error(Error::NotSupported);
return;
},
};
diff --git a/components/script/dom/xrtest.rs b/components/script/dom/xrtest.rs
index b00a69b8fca..4c6852fc121 100644
--- a/components/script/dom/xrtest.rs
+++ b/components/script/dom/xrtest.rs
@@ -69,8 +69,10 @@ impl XRTest {
impl XRTestMethods for XRTest {
/// https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md
+ #[allow(unsafe_code)]
fn SimulateDeviceConnection(&self, init: &FakeXRDeviceInit) -> Rc<Promise> {
- let p = Promise::new(&self.global());
+ let global = self.global();
+ let p = Promise::new(&global);
let origin = if let Some(ref o) = init.viewerOrigin {
match get_origin(&o) {
@@ -104,12 +106,19 @@ impl XRTestMethods for XRTest {
},
};
+ let supported_features = if let Some(ref s) = init.supportedFeatures {
+ s.iter().cloned().map(String::from).collect()
+ } else {
+ vec![]
+ };
+
let init = MockDeviceInit {
viewer_origin: origin,
views,
supports_immersive: init.supportsImmersive,
supports_unbounded: init.supportsUnbounded,
floor_origin,
+ supported_features,
};
let global = self.global();
diff --git a/tests/wpt/metadata/webxr/xrDevice_requestSession_immersive_unsupported.https.html.ini b/tests/wpt/metadata/webxr/xrDevice_requestSession_immersive_unsupported.https.html.ini
deleted file mode 100644
index 58db0b825f9..00000000000
--- a/tests/wpt/metadata/webxr/xrDevice_requestSession_immersive_unsupported.https.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[xrDevice_requestSession_immersive_unsupported.https.html]
- [Requesting an immersive session when unsupported rejects]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/webxr/xrSession_features_deviceSupport.https.html.ini b/tests/wpt/metadata/webxr/xrSession_features_deviceSupport.https.html.ini
index c2051682335..7bd0c101858 100644
--- a/tests/wpt/metadata/webxr/xrSession_features_deviceSupport.https.html.ini
+++ b/tests/wpt/metadata/webxr/xrSession_features_deviceSupport.https.html.ini
@@ -1,4 +1,5 @@
[xrSession_features_deviceSupport.https.html]
+ expected: ERROR
[Immersive XRSession requests with no supported device should reject]
- expected: FAIL
+ expected: TIMEOUT