diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2020-01-21 23:19:40 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-21 23:19:40 -0500 |
commit | ee3fb92e53d08c34a41b748aa4e49ae336eaf611 (patch) | |
tree | 59c35028546b0be1d2931ea491399c301064ce7b | |
parent | 35eb6dd0748dd9cd47e4b754166107aac72e62db (diff) | |
parent | 9a04a37c1cdd0f6f5fe5feca45f9468701fa3799 (diff) | |
download | servo-ee3fb92e53d08c34a41b748aa4e49ae336eaf611.tar.gz servo-ee3fb92e53d08c34a41b748aa4e49ae336eaf611.zip |
Auto merge of #25504 - Manishearth:features, r=asajeffrey
Support features in webxr
Based on https://github.com/servo/webxr/pull/119
Todo:
- [x] gate reference space creation on feature presence
- [x] Fix the `features_deviceSupport` test to correctly use simulateUserActivation
Fixes #24196, #24270
r? @jdm @asajeffrey
26 files changed, 222 insertions, 93 deletions
diff --git a/Cargo.lock b/Cargo.lock index 883afe5ff4f..8e6dc6e6473 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6729,7 +6729,7 @@ dependencies = [ [[package]] name = "webxr" version = "0.0.1" -source = "git+https://github.com/servo/webxr#ed1ec1afadce730247401e60994b7f6ff226639d" +source = "git+https://github.com/servo/webxr#33072cbbb67ff14b5938e886ee11a13f4cf2bafc" dependencies = [ "bindgen", "euclid", @@ -6750,7 +6750,7 @@ dependencies = [ [[package]] name = "webxr-api" version = "0.0.1" -source = "git+https://github.com/servo/webxr#ed1ec1afadce730247401e60994b7f6ff226639d" +source = "git+https://github.com/servo/webxr#33072cbbb67ff14b5938e886ee11a13f4cf2bafc" dependencies = [ "euclid", "ipc-channel", diff --git a/components/script/dom/fakexrdevice.rs b/components/script/dom/fakexrdevice.rs index f43b0b1155b..dd599d4a3a4 100644 --- a/components/script/dom/fakexrdevice.rs +++ b/components/script/dom/fakexrdevice.rs @@ -205,13 +205,16 @@ impl FakeXRDeviceMethods for FakeXRDevice { None }; - // XXXManishearth deal with profiles, supportedButtons, selection* + let profiles = init.profiles.iter().cloned().map(String::from).collect(); + + // XXXManishearth deal with supportedButtons and selection* let source = InputSource { handedness, target_ray_mode, id, supports_grip: true, + profiles, }; let init = MockInputInit { diff --git a/components/script/dom/fakexrinputcontroller.rs b/components/script/dom/fakexrinputcontroller.rs index 67e6f72cf70..e93d328ff29 100644 --- a/components/script/dom/fakexrinputcontroller.rs +++ b/components/script/dom/fakexrinputcontroller.rs @@ -6,14 +6,20 @@ use crate::dom::bindings::codegen::Bindings::FakeXRDeviceBinding::FakeXRRigidTra use crate::dom::bindings::codegen::Bindings::FakeXRInputControllerBinding::{ self, FakeXRInputControllerMethods, }; +use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding::{ + XRHandedness, XRTargetRayMode, +}; use crate::dom::bindings::error::Fallible; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::str::DOMString; use crate::dom::fakexrdevice::get_origin; use crate::dom::globalscope::GlobalScope; use dom_struct::dom_struct; use ipc_channel::ipc::IpcSender; -use webxr_api::{InputId, MockDeviceMsg, MockInputMsg, SelectEvent, SelectKind}; +use webxr_api::{ + Handedness, InputId, MockDeviceMsg, MockInputMsg, SelectEvent, SelectKind, TargetRayMode, +}; #[dom_struct] pub struct FakeXRInputController { @@ -103,4 +109,30 @@ impl FakeXRInputControllerMethods for FakeXRInputController { SelectEvent::Select, )) } + + /// https://immersive-web.github.io/webxr-test-api/#dom-fakexrinputcontroller-sethandedness + fn SetHandedness(&self, handedness: XRHandedness) { + let h = match handedness { + XRHandedness::None => Handedness::None, + XRHandedness::Left => Handedness::Left, + XRHandedness::Right => Handedness::Right, + }; + let _ = self.send_message(MockInputMsg::SetHandedness(h)); + } + + /// https://immersive-web.github.io/webxr-test-api/#dom-fakexrinputcontroller-settargetraymode + fn SetTargetRayMode(&self, target_ray_mode: XRTargetRayMode) { + let t = match target_ray_mode { + XRTargetRayMode::Gaze => TargetRayMode::Gaze, + XRTargetRayMode::Tracked_pointer => TargetRayMode::TrackedPointer, + XRTargetRayMode::Screen => TargetRayMode::Screen, + }; + let _ = self.send_message(MockInputMsg::SetTargetRayMode(t)); + } + + /// https://immersive-web.github.io/webxr-test-api/#dom-fakexrinputcontroller-setprofiles + fn SetProfiles(&self, profiles: Vec<DOMString>) { + let t = profiles.into_iter().map(String::from).collect(); + let _ = self.send_message(MockInputMsg::SetProfiles(t)); + } } diff --git a/components/script/dom/webidls/FakeXRInputController.webidl b/components/script/dom/webidls/FakeXRInputController.webidl index a50950cdee3..b8faad1038a 100644 --- a/components/script/dom/webidls/FakeXRInputController.webidl +++ b/components/script/dom/webidls/FakeXRInputController.webidl @@ -6,9 +6,9 @@ [Exposed=Window, Pref="dom.webxr.test"] interface FakeXRInputController { - // void setHandedness(XRHandedness handedness); - // void setTargetRayMode(XRTargetRayMode targetRayMode); - // void setProfiles(sequence<DOMString> profiles); + void setHandedness(XRHandedness handedness); + void setTargetRayMode(XRTargetRayMode targetRayMode); + void setProfiles(sequence<DOMString> profiles); [Throws] void setGripOrigin(FakeXRRigidTransformInit gripOrigin, optional boolean emulatedPosition = false); void clearGripOrigin(); [Throws] void setPointerOrigin(FakeXRRigidTransformInit pointerOrigin, optional boolean emulatedPosition = false); 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/XRInputSource.webidl b/components/script/dom/webidls/XRInputSource.webidl index f07de183927..487c959859d 100644 --- a/components/script/dom/webidls/XRInputSource.webidl +++ b/components/script/dom/webidls/XRInputSource.webidl @@ -23,4 +23,5 @@ interface XRInputSource { [SameObject] readonly attribute XRSpace targetRaySpace; [SameObject] readonly attribute XRSpace? gripSpace; // [SameObject] readonly attribute Gamepad? gamepad; + /* [SameObject] */ readonly attribute /* FrozenArray<DOMString> */ any profiles; }; 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..46bcc46b090 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,52 @@ impl XRMethods for XR { self.set_pending(); } - let promise = Promise::new_in_current_compartment(&self.global(), comp); + let mut required_features = vec![]; + let mut optional_features = vec![]; + let cx = global.get_cx(); + + // We are supposed to include "viewer" and on immersive devices "local" + // by default here, but this is handled directly in requestReferenceSpace() + 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"); + if mode != XRSessionMode::Inline { + self.pending_immersive_session.set(false); + } + 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 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,8 +256,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 +277,10 @@ impl XR { let session = match response { Ok(session) => session, Err(_) => { - promise.reject_native(&()); + if mode != XRSessionMode::Inline { + self.pending_immersive_session.set(false); + } + promise.reject_error(Error::NotSupported); return; }, }; diff --git a/components/script/dom/xrinputsource.rs b/components/script/dom/xrinputsource.rs index fed76937d9c..e0da8bea550 100644 --- a/components/script/dom/xrinputsource.rs +++ b/components/script/dom/xrinputsource.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use crate::compartments::enter_realm; use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding; use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding::{ XRHandedness, XRInputSourceMethods, XRTargetRayMode, @@ -11,7 +12,11 @@ use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; use crate::dom::globalscope::GlobalScope; use crate::dom::xrsession::XRSession; use crate::dom::xrspace::XRSpace; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; +use js::conversions::ToJSValConvertible; +use js::jsapi::Heap; +use js::jsval::{JSVal, UndefinedValue}; use webxr_api::{Handedness, InputId, InputSource, TargetRayMode}; #[dom_struct] @@ -24,6 +29,8 @@ pub struct XRInputSource { target_ray_space: MutNullableDom<XRSpace>, #[ignore_malloc_size_of = "Defined in rust-webxr"] grip_space: MutNullableDom<XRSpace>, + #[ignore_malloc_size_of = "mozjs"] + profiles: Heap<JSVal>, } impl XRInputSource { @@ -34,19 +41,30 @@ impl XRInputSource { info, target_ray_space: Default::default(), grip_space: Default::default(), + profiles: Heap::default(), } } + #[allow(unsafe_code)] pub fn new( global: &GlobalScope, session: &XRSession, info: InputSource, ) -> DomRoot<XRInputSource> { - reflect_dom_object( + let source = reflect_dom_object( Box::new(XRInputSource::new_inherited(session, info)), global, XRInputSourceBinding::Wrap, - ) + ); + + let _ac = enter_realm(&*global); + let cx = global.get_cx(); + unsafe { + rooted!(in(*cx) let mut profiles = UndefinedValue()); + source.info.profiles.to_jsval(*cx, profiles.handle_mut()); + source.profiles.set(profiles.get()); + } + source } pub fn id(&self) -> InputId { @@ -92,4 +110,8 @@ impl XRInputSourceMethods for XRInputSource { None } } + // https://immersive-web.github.io/webxr/#dom-xrinputsource-profiles + fn Profiles(&self, _cx: JSContext) -> JSVal { + self.profiles.get() + } } diff --git a/components/script/dom/xrinputsourcearray.rs b/components/script/dom/xrinputsourcearray.rs index 45e0f2851e4..86a107bcd27 100644 --- a/components/script/dom/xrinputsourcearray.rs +++ b/components/script/dom/xrinputsourcearray.rs @@ -45,7 +45,7 @@ impl XRInputSourceArray { for info in sess.initial_inputs() { // XXXManishearth we should be able to listen for updates // to the input sources - let input = XRInputSource::new(&global, &session, *info); + let input = XRInputSource::new(&global, &session, info.clone()); input_sources.push(Dom::from_ref(&input)); } }); @@ -54,11 +54,11 @@ impl XRInputSourceArray { pub fn add_input_source(&self, session: &XRSession, info: InputSource) { let mut input_sources = self.input_sources.borrow_mut(); let global = self.global(); - let input = XRInputSource::new(&global, &session, info); debug_assert!( input_sources.iter().find(|i| i.id() == info.id).is_none(), "Should never add a duplicate input id!" ); + let input = XRInputSource::new(&global, &session, info); input_sources.push(Dom::from_ref(&input)); let added = [input]; @@ -101,6 +101,37 @@ impl XRInputSourceArray { event.upcast::<Event>().fire(session.upcast()); } + pub fn add_remove_input_source(&self, session: &XRSession, id: InputId, info: InputSource) { + let mut input_sources = self.input_sources.borrow_mut(); + let global = self.global(); + let root; + let removed = if let Some(i) = input_sources.iter().find(|i| i.id() == id) { + root = [DomRoot::from_ref(&**i)]; + &root as &[_] + } else { + warn!("Could not find removed input source with id {:?}", id); + &[] + }; + input_sources.retain(|i| i.id() != id); + let input = XRInputSource::new(&global, &session, info); + input_sources.push(Dom::from_ref(&input)); + + let added = [input]; + + let event = XRInputSourcesChangeEvent::new( + &global, + atom!("inputsourceschange"), + false, + true, + session, + &added, + removed, + ); + // release the refcell guard + drop(input_sources); + event.upcast::<Event>().fire(session.upcast()); + } + pub fn find(&self, id: InputId) -> Option<DomRoot<XRInputSource>> { self.input_sources .borrow() diff --git a/components/script/dom/xrinputsourceschangeevent.rs b/components/script/dom/xrinputsourceschangeevent.rs index 3b68a3b8d2a..b3275cd800c 100644 --- a/components/script/dom/xrinputsourceschangeevent.rs +++ b/components/script/dom/xrinputsourceschangeevent.rs @@ -71,7 +71,7 @@ impl XRInputSourcesChangeEvent { changeevent.added.set(added_val.get()); rooted!(in(*cx) let mut removed_val = UndefinedValue()); removed.to_jsval(*cx, removed_val.handle_mut()); - changeevent.added.set(removed_val.get()); + changeevent.removed.set(removed_val.get()); } changeevent diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 4979835fc42..3f7f09baa9c 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -295,6 +295,9 @@ impl XRSession { XREvent::RemoveInput(id) => { self.input_sources.remove_input_source(self, id); }, + XREvent::UpdateInput(id, source) => { + self.input_sources.add_remove_input_source(self, id, source); + }, } } @@ -556,10 +559,25 @@ impl XRSessionMethods for XRSession { p.reject_error(Error::NotSupported) }, ty => { + if ty != XRReferenceSpaceType::Viewer && + (!self.is_immersive() || ty != XRReferenceSpaceType::Local) + { + let s = ty.as_str(); + if self + .session + .borrow() + .granted_features() + .iter() + .find(|f| &**f == s) + .is_none() + { + p.reject_error(Error::NotSupported); + return p; + } + } p.resolve_native(&XRReferenceSpace::new(&self.global(), self, ty)); }, } - p } 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/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 9fbf4e053ad..d3622831fda 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -735150,7 +735150,7 @@ "support" ], "webxr/resources/webxr_util.js": [ - "5f66dc9573d37630d588265f20e5b57a8175766f", + "dbe1585929f50089bb3e26a981b9c12b30e9fa1f", "support" ], "webxr/webGLCanvasContext_create_xrcompatible.https.html": [ @@ -735302,7 +735302,7 @@ "testharness" ], "webxr/xrSession_features_deviceSupport.https.html": [ - "d8858bd4be689bf8e4f3a3795e13fad2a2057019", + "1ee63bae047bd196233f5e4253baec94b6a576a9", "testharness" ], "webxr/xrSession_input_events_end.https.html": [ @@ -735342,7 +735342,7 @@ "testharness" ], "webxr/xrSession_viewer_availability.https.html": [ - "c509e5f1a2a992b9329fd55e591e37fcea2b6e91", + "f28a07ad8bd0f8529b791048840bf60495186a7e", "testharness" ], "webxr/xrSession_viewer_referenceSpace.https.html": [ diff --git a/tests/wpt/metadata/webxr/events_input_source_recreation.https.html.ini b/tests/wpt/metadata/webxr/events_input_source_recreation.https.html.ini deleted file mode 100644 index 82ce39a5108..00000000000 --- a/tests/wpt/metadata/webxr/events_input_source_recreation.https.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[events_input_source_recreation.https.html] - expected: ERROR - [Input sources are re-created when handedness or target ray mode changes] - expected: FAIL - diff --git a/tests/wpt/metadata/webxr/getInputPose_handedness.https.html.ini b/tests/wpt/metadata/webxr/getInputPose_handedness.https.html.ini deleted file mode 100644 index f10131010ef..00000000000 --- a/tests/wpt/metadata/webxr/getInputPose_handedness.https.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[getInputPose_handedness.https.html] - expected: ERROR - [XRInputSources properly communicate their handedness] - expected: TIMEOUT - diff --git a/tests/wpt/metadata/webxr/idlharness.https.window.js.ini b/tests/wpt/metadata/webxr/idlharness.https.window.js.ini index 1b47a7ad858..df4d0eabbcd 100644 --- a/tests/wpt/metadata/webxr/idlharness.https.window.js.ini +++ b/tests/wpt/metadata/webxr/idlharness.https.window.js.ini @@ -95,9 +95,6 @@ [XRReferenceSpaceEvent interface: existence and properties of interface prototype object's "constructor" property] expected: FAIL - [XRInputSource interface: attribute profiles] - expected: FAIL - [XR interface: operation requestSession(XRSessionMode, XRSessionInit)] expected: FAIL 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/xrInputSource_profiles.https.html.ini b/tests/wpt/metadata/webxr/xrInputSource_profiles.https.html.ini deleted file mode 100644 index 3e2806dfae7..00000000000 --- a/tests/wpt/metadata/webxr/xrInputSource_profiles.https.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[xrInputSource_profiles.https.html] - [WebXR InputSource's profiles list can be set] - 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 deleted file mode 100644 index c2051682335..00000000000 --- a/tests/wpt/metadata/webxr/xrSession_features_deviceSupport.https.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[xrSession_features_deviceSupport.https.html] - [Immersive XRSession requests with no supported device should reject] - expected: FAIL - diff --git a/tests/wpt/metadata/webxr/xrSession_input_events_end.https.html.ini b/tests/wpt/metadata/webxr/xrSession_input_events_end.https.html.ini index 1d6cd17924d..1c2f8518d1a 100644 --- a/tests/wpt/metadata/webxr/xrSession_input_events_end.https.html.ini +++ b/tests/wpt/metadata/webxr/xrSession_input_events_end.https.html.ini @@ -1,5 +1,5 @@ [xrSession_input_events_end.https.html] expected: TIMEOUT [Calling end during an input callback stops processing at the right time] - expected: TIMEOUT + expected: FAIL diff --git a/tests/wpt/metadata/webxr/xrSession_requestReferenceSpace_features.https.html.ini b/tests/wpt/metadata/webxr/xrSession_requestReferenceSpace_features.https.html.ini deleted file mode 100644 index 42ddb3aa092..00000000000 --- a/tests/wpt/metadata/webxr/xrSession_requestReferenceSpace_features.https.html.ini +++ /dev/null @@ -1,7 +0,0 @@ -[xrSession_requestReferenceSpace_features.https.html] - [Immersive session rejects local-floor space if not requested] - expected: FAIL - - [Non-immersive session rejects local space if not requested] - expected: FAIL - diff --git a/tests/wpt/metadata/webxr/xrSession_sameObject.https.html.ini b/tests/wpt/metadata/webxr/xrSession_sameObject.https.html.ini deleted file mode 100644 index 0013dc7b4cc..00000000000 --- a/tests/wpt/metadata/webxr/xrSession_sameObject.https.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[xrSession_sameObject.https.html] - expected: ERROR - [XRSession attributes meet [SameObject\] requirement] - expected: TIMEOUT - diff --git a/tests/wpt/web-platform-tests/webxr/resources/webxr_util.js b/tests/wpt/web-platform-tests/webxr/resources/webxr_util.js index 5f66dc9573d..dbe1585929f 100644 --- a/tests/wpt/web-platform-tests/webxr/resources/webxr_util.js +++ b/tests/wpt/web-platform-tests/webxr/resources/webxr_util.js @@ -101,6 +101,18 @@ function xr_session_promise_test( properties); } + +// This function wraps the provided function in a +// simulateUserActivation() call, and resolves the promise with the +// result of func(), or an error if one is thrown +function promise_simulate_user_activation(func) { + return new Promise((resolve, reject) => { + navigator.xr.test.simulateUserActivation(() => { + try { let a = func(); resolve(a); } catch(e) { reject(e); } + }); + }); +} + // This functions calls a callback with each API object as specified // by https://immersive-web.github.io/webxr/spec/latest/, allowing // checks to be made on all ojects. diff --git a/tests/wpt/web-platform-tests/webxr/xrSession_features_deviceSupport.https.html b/tests/wpt/web-platform-tests/webxr/xrSession_features_deviceSupport.https.html index d8858bd4be6..1ee63bae047 100644 --- a/tests/wpt/web-platform-tests/webxr/xrSession_features_deviceSupport.https.html +++ b/tests/wpt/web-platform-tests/webxr/xrSession_features_deviceSupport.https.html @@ -21,6 +21,7 @@ "local-floor"] }; + xr_promise_test(testName, (t) => { function session_resolves(sessionMode, sessionInit) { @@ -31,34 +32,28 @@ } return navigator.xr.test.simulateDeviceConnection(fakeDeviceInitParams) - .then((controller) => new Promise((resolve, reject) => { - navigator.xr.test.simulateUserActivation(() => { + .then((controller) => + promise_simulate_user_activation(() => { // Attempting to request required features that aren't supported by // the device should reject. - promise_rejects(t, "NotSupportedError", + + return promise_rejects(t, "NotSupportedError", navigator.xr.requestSession("immersive-vr", { requiredFeatures: ['bounded-floor'] })) - .then(() => { + }).then(() => promise_simulate_user_activation(() => { // Attempting to request with an unsupported feature as optional // should succeed return session_resolves("immersive-vr", { optionalFeatures: ['bounded-floor'] }); + })).then(() => promise_simulate_user_activation(() => { + // Attempting to request with supported features only should succeed. + return session_resolves("immersive-vr", { + requiredFeatures: ['local', 'local-floor'] }) - .then(() => { - // Attempting to request with supported features only should succeed. - return session_resolves("immersive-vr", { - requiredFeatures: ['local', 'local-floor'] - }) - .then(() => { - resolve(); - }).catch((err) => { - reject(err); - });; - }); - }); - })); + })) + ); }); </script> diff --git a/tests/wpt/web-platform-tests/webxr/xrSession_viewer_availability.https.html b/tests/wpt/web-platform-tests/webxr/xrSession_viewer_availability.https.html index c509e5f1a2a..f28a07ad8bd 100644 --- a/tests/wpt/web-platform-tests/webxr/xrSession_viewer_availability.https.html +++ b/tests/wpt/web-platform-tests/webxr/xrSession_viewer_availability.https.html @@ -24,14 +24,6 @@ .then(session => session.end())); } - function simulate_user_activation(func) { - return new Promise((resolve, reject) => { - navigator.xr.test.simulateUserActivation(() => { - try { resolve(func()); } catch(e) { reject(e); } - }); - }); - } - return session_resolves('inline', { // RequestSession with 'viewer' as a required featre should succeed, even // without user activation. @@ -62,14 +54,14 @@ optionalFeatures: ['local'] }); }) - .then(() => simulate_user_activation(() => { + .then(() => promise_simulate_user_activation(() => { // RequestSession with unsupported optional features should succeed. return session_resolves('inline', { requiredFeatures: ['viewer'], optionalFeatures: ['local'] }) })) - .then(() => simulate_user_activation(() => { + .then(() => promise_simulate_user_activation(() => { // Request with unsupported required features should reject. return session_rejects("NotSupportedError", 'inline', { requiredFeatures: ['local'] |