Commit e702470c authored by bsheedy's avatar bsheedy Committed by Commit Bot

Reland "Add WebXR non-exclusive session tests"

This is a reland of f308efb9.

Original change's description:
> Add WebXR non-exclusive session tests
>
> Ports existing WebVR tests that use magic window to WebXR now that
> non-exclusive sessions are supported. Also adds two new WebXR-only tests
> involving non-exclusive sessions.
>
> Bug: 804043
> Change-Id: I283438d2206e2563636188b5f2a6537d56f2c10e
> Reviewed-on: https://chromium-review.googlesource.com/916728
> Reviewed-by: Brandon Jones <bajones@chromium.org>
> Reviewed-by: Michael Thiessen <mthiesse@chromium.org>
> Commit-Queue: Brian Sheedy <bsheedy@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#537975}

TBR=mthiesse@chromium.org,bajones@chromium.org

Bug: 804043
Change-Id: I24dd7e2327f10d11c39d0dee4eb49f2e7bd42e3a
Reviewed-on: https://chromium-review.googlesource.com/929522
Commit-Queue: Brian Sheedy <bsheedy@chromium.org>
Reviewed-by: default avatarBrian Sheedy <bsheedy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#544188}
parent 68664907
...@@ -47,17 +47,19 @@ public class WebVrDeviceTest { ...@@ -47,17 +47,19 @@ public class WebVrDeviceTest {
@Rule @Rule
public RuleChain mRuleChain; public RuleChain mRuleChain;
private ChromeActivityTestRule mVrTestRule; private ChromeActivityTestRule mTestRule;
private VrTestFramework mVrTestFramework; private VrTestFramework mVrTestFramework;
private XrTestFramework mXrTestFramework;
public WebVrDeviceTest(Callable<ChromeActivityTestRule> callable) throws Exception { public WebVrDeviceTest(Callable<ChromeActivityTestRule> callable) throws Exception {
mVrTestRule = callable.call(); mTestRule = callable.call();
mRuleChain = VrTestRuleUtils.wrapRuleInVrActivityRestrictionRule(mVrTestRule); mRuleChain = VrTestRuleUtils.wrapRuleInVrActivityRestrictionRule(mTestRule);
} }
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
mVrTestFramework = new VrTestFramework(mVrTestRule); mVrTestFramework = new VrTestFramework(mTestRule);
mXrTestFramework = new XrTestFramework(mTestRule);
} }
/** /**
...@@ -97,4 +99,20 @@ public class WebVrDeviceTest { ...@@ -97,4 +99,20 @@ public class WebVrDeviceTest {
mVrTestFramework.getFirstTabWebContents()); mVrTestFramework.getFirstTabWebContents());
VrTestFramework.endTest(mVrTestFramework.getFirstTabWebContents()); VrTestFramework.endTest(mVrTestFramework.getFirstTabWebContents());
} }
/**
* Tests that reported WebXR capabilities match expectations.
*/
@Test
@MediumTest
@CommandLineFlags.Remove({"enable-webvr"})
@CommandLineFlags.Add({"enable-features=WebXR"})
@VrActivityRestriction({VrActivityRestriction.SupportedActivity.ALL})
public void testWebXrCapabilities() throws InterruptedException {
mXrTestFramework.loadUrlAndAwaitInitialization(
XrTestFramework.getHtmlTestFile("test_webxr_capabilities"), PAGE_LOAD_TIMEOUT_S);
XrTestFramework.executeStepAndWait(
"stepCheckCapabilities('Daydream')", mXrTestFramework.getFirstTabWebContents());
XrTestFramework.endTest(mXrTestFramework.getFirstTabWebContents());
}
} }
...@@ -43,17 +43,19 @@ public class WebVrTabTest { ...@@ -43,17 +43,19 @@ public class WebVrTabTest {
@Rule @Rule
public RuleChain mRuleChain; public RuleChain mRuleChain;
private ChromeActivityTestRule mVrTestRule; private ChromeActivityTestRule mTestRule;
private VrTestFramework mVrTestFramework; private VrTestFramework mVrTestFramework;
private XrTestFramework mXrTestFramework;
public WebVrTabTest(Callable<ChromeActivityTestRule> callable) throws Exception { public WebVrTabTest(Callable<ChromeActivityTestRule> callable) throws Exception {
mVrTestRule = callable.call(); mTestRule = callable.call();
mRuleChain = VrTestRuleUtils.wrapRuleInVrActivityRestrictionRule(mVrTestRule); mRuleChain = VrTestRuleUtils.wrapRuleInVrActivityRestrictionRule(mTestRule);
} }
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
mVrTestFramework = new VrTestFramework(mVrTestRule); mVrTestFramework = new VrTestFramework(mTestRule);
mXrTestFramework = new XrTestFramework(mTestRule);
} }
/** /**
...@@ -62,16 +64,33 @@ public class WebVrTabTest { ...@@ -62,16 +64,33 @@ public class WebVrTabTest {
@Test @Test
@MediumTest @MediumTest
public void testPoseDataUnfocusedTab() throws InterruptedException { public void testPoseDataUnfocusedTab() throws InterruptedException {
mVrTestFramework.loadUrlAndAwaitInitialization( testPoseDataUnfocusedTabImpl(
VrTestFramework.getHtmlTestFile("test_pose_data_unfocused_tab"), VrTestFramework.getHtmlTestFile("test_pose_data_unfocused_tab"), mVrTestFramework);
PAGE_LOAD_TIMEOUT_S); }
VrTestFramework.executeStepAndWait(
"stepCheckFrameDataWhileFocusedTab()", mVrTestFramework.getFirstTabWebContents()); /**
* Tests that non-focused tabs don't get WebXR rAFs called.
*/
@Test
@MediumTest
@CommandLineFlags.Remove({"enable-webvr"})
@CommandLineFlags.Add({"enable-features=WebXR"})
public void testPoseDataUnfocusedTab_WebXr() throws InterruptedException {
testPoseDataUnfocusedTabImpl(
XrTestFramework.getHtmlTestFile("webxr_test_pose_data_unfocused_tab"),
mXrTestFramework);
}
private void testPoseDataUnfocusedTabImpl(String url, TestFramework framework)
throws InterruptedException {
framework.loadUrlAndAwaitInitialization(url, PAGE_LOAD_TIMEOUT_S);
TestFramework.executeStepAndWait(
"stepCheckFrameDataWhileFocusedTab()", framework.getFirstTabWebContents());
mVrTestRule.loadUrlInNewTab("about:blank"); mTestRule.loadUrlInNewTab("about:blank");
VrTestFramework.executeStepAndWait("stepCheckFrameDataWhileNonFocusedTab()", TestFramework.executeStepAndWait(
mVrTestFramework.getFirstTabWebContents()); "stepCheckFrameDataWhileNonFocusedTab()", framework.getFirstTabWebContents());
VrTestFramework.endTest(mVrTestFramework.getFirstTabWebContents()); TestFramework.endTest(framework.getFirstTabWebContents());
} }
} }
...@@ -473,4 +473,45 @@ public class WebVrTransitionTest { ...@@ -473,4 +473,45 @@ public class WebVrTransitionTest {
framework.simulateRendererKilled(); framework.simulateRendererKilled();
Assert.assertTrue("Browser is in VR", VrShellDelegate.isInVr()); Assert.assertTrue("Browser is in VR", VrShellDelegate.isInVr());
} }
/**
* Tests that window.rAF continues to fire when we have a non-exclusive session.
*/
@Test
@MediumTest
@CommandLineFlags.Remove({"enable-webvr"})
@CommandLineFlags.Add({"enable-features=WebXR"})
@VrActivityRestriction({VrActivityRestriction.SupportedActivity.ALL})
public void testWindowRafFiresDuringNonExclusiveSession() throws InterruptedException {
mXrTestFramework.loadUrlAndAwaitInitialization(
XrTestFramework.getHtmlTestFile(
"test_window_raf_fires_during_non_exclusive_session"),
PAGE_LOAD_TIMEOUT_S);
XrTestFramework.waitOnJavaScriptStep(mXrTestFramework.getFirstTabWebContents());
XrTestFramework.endTest(mXrTestFramework.getFirstTabWebContents());
}
/**
* Tests that non-exclusive sessions stop receiving rAFs during an exclusive session, but resume
* once the exclusive session ends.
*/
@Test
@MediumTest
@CommandLineFlags.Remove({"enable-webvr"})
@CommandLineFlags.Add({"enable-features=WebXR"})
@VrActivityRestriction({VrActivityRestriction.SupportedActivity.ALL})
public void testNonExclusiveStopsDuringExclusive() throws InterruptedException {
mXrTestFramework.loadUrlAndAwaitInitialization(
XrTestFramework.getHtmlTestFile("test_non_exclusive_stops_during_exclusive"),
PAGE_LOAD_TIMEOUT_S);
XrTestFramework.executeStepAndWait(
"stepBeforeExclusive()", mXrTestFramework.getFirstTabWebContents());
TransitionUtils.enterPresentationOrFail(mXrTestFramework);
XrTestFramework.executeStepAndWait(
"stepDuringExclusive()", mXrTestFramework.getFirstTabWebContents());
TransitionUtils.forceExitVr();
XrTestFramework.executeStepAndWait(
"stepAfterExclusive()", mXrTestFramework.getFirstTabWebContents());
XrTestFramework.endTest(mXrTestFramework.getFirstTabWebContents());
}
} }
<!doctype html>
<!--
Tests that a non-exclusive session's rAF stops firing when an exclusive session
is active, but resumes afterwards.
-->
<html>
<head>
<link rel="stylesheet" type="text/css" href="../resources/webxr_e2e.css">
</head>
<body>
<canvas id="webgl-canvas"></canvas>
<script src="../../../../../../third_party/WebKit/LayoutTests/resources/testharness.js"></script>
<script src="../resources/webxr_e2e.js"></script>
<script src="../resources/webxr_boilerplate.js"></script>
<script>
var t = async_test("Non-exclusive rAF stops during exclusive session");
let counter = 0;
function stepBeforeExclusive() {
onMagicWindowXRFrameCallback = function() {
// Verify that we call a rAF once, then make sure any subsequent calls
// are not done while there is an exclusive session.
onMagicWindowXRFrameCallback = function() {
if (exclusiveSession !== null) {
t.step( () => {
assert_unreached(
"Non-exclusive rAF called during exclusive session");
});
}
}
finishJavaScriptStep();
};
}
function stepDuringExclusive() {
// Let the exclusive session run for a bit so the non-exclusive rAF
// can fire if it's going to.
onExclusiveXRFrameCallback = function() {
if (counter < 10) {
counter++;
return;
}
onExclusiveXRFrameCallback = null;
finishJavaScriptStep();
};
}
function stepAfterExclusive() {
// Make sure we fire at least once after exiting the exclusive session
onMagicWindowXRFrameCallback = function() {
t.done();
};
}
</script>
</body>
</html>
<!doctype html>
<!--
Tests that the provided WebXR device has the expected capabilities
-->
<html>
<head>
<link rel="stylesheet" type="text/css" href="../resources/webxr_e2e.css">
</head>
<body>
<canvas id="webgl-canvas"></canvas>
<script src="../../../../../../third_party/WebKit/LayoutTests/resources/testharness.js"></script>
<script src="../resources/webxr_e2e.js"></script>
<script src="../resources/webxr_boilerplate.js"></script>
<script>
var expectations = {
"Daydream": {
"exclusive": true,
"non-exclusive": true,
}
};
var t = async_test("XRDevice capabilities match expectations");
function stepCheckCapabilities(device) {
if (!(device in expectations)) {
t.step_func_done( () => {
assert_unreached("Given device " + device + " not in expectations");
})();
return;
}
let expected = expectations[device];
var supportsNonExclusive;
var supportsExclusive;
var ctx = webglCanvas.getContext("xrpresent");
xrDevice.supportsSession(
{exclusive: false, outputContext: ctx}).then( () => {
supportsNonExclusive = true;
}, () => {
supportsNonExclusive = false;
}).then( () => {
xrDevice.supportsSession({exclusive: true}).then( () => {
supportsExclusive = true;
}, () => {
supportsExclusive = false;
}).then( () => {
t.step( () => {
assert_equals(supportsNonExclusive, expected["non-exclusive"],
'Device supports non-exclusive sessions');
assert_equals(supportsExclusive, expected["exclusive"],
'Device supports exclusive sessions');
});
t.done();
});
});
}
</script>
</body>
</html>
<!doctype html>
<!--
Tests that window.rAF continues to fire during a non-exclusive session.
-->
<html>
<head>
<link rel="stylesheet" type="text/css" href="../resources/webxr_e2e.css">
</head>
<body>
<canvas id="webgl-canvas"></canvas>
<script src="../../../../../../third_party/WebKit/LayoutTests/resources/testharness.js"></script>
<script src="../resources/webxr_e2e.js"></script>
<script src="../resources/webxr_boilerplate.js"></script>
<script>
var t = async_test("window.rAF fires during a non-exclusive session");
onMagicWindowXRFrameCallback = function() {
window.requestAnimationFrame( () => {
t.done();
});
}
</script>
</body>
</html>
<!doctype html>
<!--
Tests that WebXR doesn't update frame data when the tab is not focused
-->
<html>
<head>
<link rel="stylesheet" type="text/css" href="../resources/webxr_e2e.css">
</head>
<body>
<canvas id="webgl-canvas"></canvas>
<script src="../../../../../../third_party/WebKit/LayoutTests/resources/testharness.js"></script>
<script src="../resources/webxr_e2e.js"></script>
<script src="../resources/webxr_boilerplate.js"></script>
<script>
var t = async_test("Test pose data in unfocused tab");
var pose = null;
let counter = 0;
function stepCheckFrameDataWhileFocusedTab() {
function onAnimationFrame(session, frame) {
// TODO(bsheedy): This is a workaround for crbug.com/787196. Either
// remove the workaround once fixed or remove this todo.
// Let several animation frames get triggered so we're sure to have a
// pose
if (counter <= 2) {
counter++;
return;
}
onMagicWindowXRFrameCallback = null;
pose = frame.getDevicePose(magicWindowFrameOfRef);
t.step( () => {
assert_true(pose != null,
"getDevicePose returned a non-null object");
assert_true(pose instanceof XRDevicePose,
"getDevicePose returned an XRDevicePose")
});
finishJavaScriptStep();
}
// Make sure at least one rAF call has happened so we get valid data
onMagicWindowXRFrameCallback = onAnimationFrame;
}
function stepCheckFrameDataWhileNonFocusedTab() {
// Unlike WebVR, WebXR doesn't fire rAFs when in a different tab
onMagicWindowXRFrameCallback = function() {
t.step( () => {
assert_unreached("Magic window fired rAF while in a different tab");
});
}
window.setTimeout( () => {
t.done();
}, 1000);
}
</script>
</body>
</html>
...@@ -49,6 +49,7 @@ function onSessionStarted(session) { ...@@ -49,6 +49,7 @@ function onSessionStarted(session) {
gl.clearColor(0.0, 1.0, 0.0, 1.0); gl.clearColor(0.0, 1.0, 0.0, 1.0);
gl.enable(gl.DEPTH_TEST); gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE); gl.enable(gl.CULL_FACE);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
} }
session.baseLayer = new XRWebGLLayer(session, gl); session.baseLayer = new XRWebGLLayer(session, gl);
...@@ -88,14 +89,14 @@ function onXRFrame(t, frame) { ...@@ -88,14 +89,14 @@ function onXRFrame(t, frame) {
// If in an exclusive session, set canvas to blue. Otherwise, red. // If in an exclusive session, set canvas to blue. Otherwise, red.
if (session.exclusive) { if (session.exclusive) {
if (onExclusiveXRFrameCallback) { if (onExclusiveXRFrameCallback) {
onExclusiveXRFrameCallback(session); onExclusiveXRFrameCallback(session, frame);
} }
gl.clearColor(0.0, 0.0, 1.0, 1.0); gl.clearColor(0.0, 0.0, 1.0, 1.0);
} else { } else {
if (onMagicWindowXRFrameCallback) { if (onMagicWindowXRFrameCallback) {
onMagicWindowXRFrameCallback(session); onMagicWindowXRFrameCallback(session, frame);
} }
gl.clearcolor(1.0, 0.0, 0.0, 1.0); gl.clearColor(1.0, 0.0, 0.0, 1.0);
} }
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
} }
...@@ -110,14 +111,11 @@ if (navigator.xr) { ...@@ -110,14 +111,11 @@ if (navigator.xr) {
// Set up the device to have a non-exclusive session (magic window) drawing // Set up the device to have a non-exclusive session (magic window) drawing
// into the full screen canvas on the page // into the full screen canvas on the page
let ctx = webglCanvas.getContext('xrpresent'); let ctx = webglCanvas.getContext('xrpresent');
// TODO(bsheedy): Enable and test this once non-exclusive session support device.requestSession({outputContext: ctx}).then( (session) => {
// is actually added to the implementation.
/*device.requestSession({outputContext: ctx}).then( (session) => {
onSessionStarted(session); onSessionStarted(session);
}).then( () => { }).then( () => {
initializationSteps['magicWindowStarted'] = true; initializationSteps['magicWindowStarted'] = true;
});*/ });
initializationSteps['magicWindowStarted'] = true;
}).then( () => { }).then( () => {
initializationSteps['getXRDevice'] = true; initializationSteps['getXRDevice'] = true;
}); });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment