blob: dc790ba725d87f75af1654beccc07826c927290c [file] [log] [blame]
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../external/wpt/webxr/resources/webxr_test_constants.js"></script>
<script src="../xr/resources/xr-internal-device-mocking.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
let testName = "Calling end during an input callback stops processing at the right time";
let fakeDeviceInitParams = { supportsImmersive:true };
let requestSessionModes = ['immersive-vr'];
function requestImmersiveSession() {
return new Promise((resolve, reject) => {
runWithUserGesture(() => {
navigator.xr.requestSession('immersive-vr').then((session) => {
resolve(session);
}, (err) => {
reject(err);
});
});
});
}
let testFunction = function(session, t, fakeDeviceController) {
// helper method to send a click and then request a dummy animation frame to
// ensure that the click propagates. We're doing everything in these tests
// from event watchers, we just need to trigger the add/click to make the
// event listeners callback.
function sendClick(session) {
let input_source = new MockXRInputSource();
input_source.primaryInputClicked = true;
fakeDeviceController.addInputSource(input_source);
session.requestAnimationFrame(() => {});
}
function sessionEndTest(endEvent, eventOrder) {
return requestImmersiveSession().then((session) => {
let eventWatcher = new EventWatcher(t, session,
["inputsourceschange", "selectstart", "select", "selectend", "end"]);
let eventPromise = eventWatcher.wait_for(eventOrder);
// Session must have a baseLayer or frame requests will be ignored.
session.updateRenderState({ baseLayer: new XRWebGLLayer(session, gl) });
session.addEventListener(endEvent, ()=> {
session.end();
}, false);
sendClick(session);
return eventPromise;
});
}
// Need to have a valid pose or input events don't process.
fakeDeviceController.setXRPresentationFrameData(VALID_POSE_MATRIX, [{
eye:"left",
projectionMatrix: VALID_PROJECTION_MATRIX,
viewMatrix: VALID_VIEW_MATRIX
}, {
eye:"right",
projectionMatrix: VALID_PROJECTION_MATRIX,
viewMatrix: VALID_VIEW_MATRIX
}]);
// End our first session, just for simplicity, then make end session calls
// during each of our input events, and ensure that events stop processing
// and no crashes occur from calling end inside the event callbacks.
return session.end().then(() => {
return sessionEndTest("inputsourceschange", ["inputsourceschange", "end"]);
}).then(() => {
return sessionEndTest("selectstart", ["inputsourceschange", "selectstart", "selectend", "end"]);
}).then(() => {
return sessionEndTest("select", ["inputsourceschange", "selectstart", "select", "selectend", "end"]);
}).then(() => {
return sessionEndTest("selectend", ["inputsourceschange", "selectstart", "select", "selectend", "end"]);
});
};
xr_session_promise_test(
testFunction, fakeDeviceInitParams, requestSessionModes, testName);
</script>