Skip to content
Permalink
Browse files

Do not allow XR session on non user-activated events

  • Loading branch information...
paulrouget committed Sep 13, 2019
1 parent 9138d1d commit ea7b58153723f7ef6a6fa2a9b73c71c3bf3295e0
@@ -23,6 +23,7 @@ use crate::dom::vrdisplay::VRDisplay;
use crate::dom::vrdisplayevent::VRDisplayEvent;
use crate::dom::xrsession::XRSession;
use crate::dom::xrtest::XRTest;
use crate::script_thread::ScriptThread;
use crate::task_source::TaskSource;
use dom_struct::dom_struct;
use ipc_channel::ipc::IpcSender;
@@ -157,6 +158,11 @@ impl XRMethods for XR {
) -> Rc<Promise> {
let promise = Promise::new_in_current_compartment(&self.global(), comp);

if !ScriptThread::is_user_interacting() {
promise.reject_error(Error::Security);
return promise;
}

if self.pending_or_active_session() {
promise.reject_error(Error::InvalidState);
return promise;
@@ -18,6 +18,7 @@ use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::fakexrdevice::{get_origin, get_views, FakeXRDevice};
use crate::dom::globalscope::GlobalScope;
use crate::dom::promise::Promise;
use crate::script_thread::ScriptThread;
use crate::task_source::TaskSource;
use dom_struct::dom_struct;
use euclid::RigidTransform3D;
@@ -159,8 +160,9 @@ impl XRTestMethods for XRTest {

/// https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md
fn SimulateUserActivation(&self, f: Rc<Function>) {
// XXXManishearth actually check for activation in XRSession
ScriptThread::set_user_interacting(true);
let _ = f.Call__(vec![], ExceptionHandling::Rethrow);
ScriptThread::set_user_interacting(false);
}

/// https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md
@@ -690,6 +690,9 @@ pub struct ScriptThread {

/// A set of all nodes ever created in this script thread
node_ids: DomRefCell<HashSet<String>>,

/// Code is running as a consequence of a user interaction
is_user_interacting: Cell<bool>,
}

/// In the event of thread panic, all data on the stack runs its destructor. However, there
@@ -1030,6 +1033,24 @@ impl ScriptThread {
})
}

pub fn set_user_interacting(interacting: bool) {
SCRIPT_THREAD_ROOT.with(|root| {
if let Some(script_thread) = root.get() {
let script_thread = unsafe { &*script_thread };
script_thread.is_user_interacting.set(interacting);
}
});
}

pub fn is_user_interacting() -> bool {
SCRIPT_THREAD_ROOT.with(|root| {
root.get().map_or(false, |script_thread| {
let script_thread = unsafe { &*script_thread };
script_thread.is_user_interacting.get()
})
})
}

pub fn get_fully_active_document_ids() -> HashSet<PipelineId> {
SCRIPT_THREAD_ROOT.with(|root| {
root.get().map_or(HashSet::new(), |script_thread| {
@@ -1339,6 +1360,7 @@ impl ScriptThread {
event_loop_waker: state.event_loop_waker,

node_ids: Default::default(),
is_user_interacting: Cell::new(false),
}
}

@@ -3356,6 +3378,9 @@ impl ScriptThread {
///
/// TODO: Actually perform DOM event dispatch.
fn handle_event(&self, pipeline_id: PipelineId, event: CompositorEvent) {
// Assuming all CompositionEvent are generated by user interactions.
ScriptThread::set_user_interacting(true);

match event {
ResizeEvent(new_size, size_type) => {
self.handle_resize_event(pipeline_id, new_size, size_type);
@@ -3489,6 +3514,8 @@ impl ScriptThread {
document.dispatch_composition_event(composition_event);
},
}

ScriptThread::set_user_interacting(false);
}

fn handle_mouse_event(
"testharness"
],
"webxr/xrWebGLLayer_constructor.https.html": [
"0584da79c12def757f951ec53c4c048f18c39b8c",
"7e57f4286c66ea9f8380791840dada3d82b611fe",
"testharness"
],
"webxr/xrWebGLLayer_framebuffer_draw.https.html": [

This file was deleted.

@@ -7658,9 +7658,6 @@
]
]
},
"stub": {
"css/blockify_inline_element.html": []
},
"support": {
".gitignore": [
[]
@@ -19747,11 +19744,11 @@
"testharness"
],
"webxr/create_session.html": [
"e68ea81893a65793094f9086cdd6d73800ee1c14",
"af76c5a812d7d05a0158194560933def3fbdb9f9",
"testharness"
],
"webxr/obtain_frame.html": [
"39698805b476c7e469548d25ece59560a596604d",
"74fda5bad43e8ea95552e65380e83952680e8469",
"testharness"
],
"webxr/resources/webxr-util.js": [
@@ -12,7 +12,11 @@
views: TEST_VIEWS,
viewerOrigin: {position: [0.5, 0.1, 0.1], orientation: [1, 0, 0, 1] }
}).then((m) => {
return navigator.xr.requestSession("immersive-vr")
let sessionPromise;
navigator.xr.test.simulateUserActivation(() => {
sessionPromise = navigator.xr.requestSession("immersive-vr")
});
return sessionPromise;
}).then(() => t.done());
});
</script>
@@ -16,7 +16,11 @@
views: TEST_VIEWS,
viewerOrigin: {position: [0.5, 0.1, 0.1], orientation: [1, 0, 0, 1] }
});
let session = await navigator.xr.requestSession("immersive-vr");
let sessionPromise;
navigator.xr.test.simulateUserActivation(() => {
sessionPromise = navigator.xr.requestSession("immersive-vr");
});
let session = await sessionPromise;
await session.updateRenderState({"baseLayer": new XRWebGLLayer(session, gl, {})});
let resolve;
@@ -17,8 +17,11 @@
let gl = webglCanvas.getContext('webgl', glAttributes);
return navigator.xr.test.simulateDeviceConnection(TRACKED_IMMERSIVE_DEVICE)
.then(() => {
return navigator.xr.requestSession('inline')
.then((session) => {
let sessionPromise;
navigator.xr.test.simulateUserActivation(function() {
sessionPromise = navigator.xr.requestSession('inline');
});
return sessionPromise.then((session) => {
try {
let webglLayerIncompatible = new XRWebGLLayer(session, gl);
} catch (err) {

0 comments on commit ea7b581

Please sign in to comment.
You can’t perform that action at this time.