blob: 1734b6d5aa72ccc7abaf1a644191eca083533c6f [file] [log] [blame]
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>let additionalChromiumResources = ["../resources/xr-internal-device-mocking.js"];</script>
<script src="/webxr/resources/webxr_util.js"></script>
<script src="/webxr/resources/webxr_test_constants.js"></script>
<script src="/webxr/resources/webxr_test_constants_fake_world.js"></script>
<script src="/webxr/resources/webxr_test_asserts.js"></script>
<script>
// Because WebXR Test API hit test extensions do not yet cover the hit test source lifetimes,
// this is an internal, Chrome-only WPT.
// 1m above world origin.
const VIEWER_ORIGIN_TRANSFORM = {
position: [0, 1, 0],
orientation: [0, 0, 0, 1],
};
// 0.25m above world origin.
const FLOOR_ORIGIN_TRANSFORM = {
position: [0, -0.25, 0],
orientation: [0, 0, 0, 1],
};
const fakeDeviceInitParams = {
supportedModes: ["immersive-ar"],
views: VALID_VIEWS,
floorOrigin: FLOOR_ORIGIN_TRANSFORM, // aka mojo_from_floor
viewerOrigin: VIEWER_ORIGIN_TRANSFORM, // aka mojo_from_viewer
supportedFeatures: ALL_FEATURES,
world: createFakeWorld(5.0, 2.0, 5.0), // webxr_test_constants_fake_world.js has detailed description of the fake world
};
const test_function_generator = function(isTransientTest, isGarbageCollectionTest) {
return function(session, fakeDeviceController, t) {
let controller = null;
fakeDeviceController.setHitTestSourceCreationCallback((params, htsController) => {
controller = htsController;
return Promise.resolve(true);
});
return session.requestReferenceSpace('local').then((localSpace) => {
const validation_function = (hitTestSource) => {
const spinRAF = function() {
session.requestAnimationFrame(spinRAF);
};
const rAFcb = function(time, frame) {
session.requestAnimationFrame(spinRAF);
const hitTestResults = isTransientTest ? frame.getHitTestResultsForTransientInput(hitTestSource)
: frame.getHitTestResults(hitTestSource);
t.step(() => {
assert_not_equals(hitTestResults, null, "Results should be non-null!");
});
if(isGarbageCollectionTest) {
hitTestSource = null;
self.gc();
} else {
hitTestSource.cancel();
}
};
session.requestAnimationFrame(rAFcb);
return t.step_wait(() => controller.deleted);
};
// Same validation will happen both in transient and non-transient variant
if(isTransientTest) {
return session.requestHitTestSourceForTransientInput({
profile: "generic-touchscreen",
offsetRay: new XRRay(),
}).then(validation_function);
} else {
return session.requestHitTestSource({
space: localSpace,
offsetRay: new XRRay(),
}).then(validation_function);
}
}); // return session.requestReferenceSpace('local').then((localSpace) => { ...
}; // return function(session, fakeDeviceController, t) { ...
}
xr_session_promise_test("Ensures hit test source cancellation propagates to the device when manually cancelled.",
test_function_generator(/*isTransientTest=*/false, /*isGarbageCollectionTest=*/false),
fakeDeviceInitParams,
'immersive-ar', { 'requiredFeatures': ['hit-test'] });
xr_session_promise_test("Ensures transient input hit test source cancellation propagates to the device when manually cancelled.",
test_function_generator(/*isTransientTest=*/true, /*isGarbageCollectionTest=*/false),
fakeDeviceInitParams,
'immersive-ar', { 'requiredFeatures': ['hit-test'] });
if(self.gc) {
xr_session_promise_test("Ensures hit test source cancellation propagates to the device when relying on GC",
test_function_generator(/*isTransientTest=*/false, /*isGarbageCollectionTest=*/true),
fakeDeviceInitParams,
'immersive-ar', { 'requiredFeatures': ['hit-test'] });
xr_session_promise_test("Ensures transient input hit test source cancellation propagates to the device when relying on GC",
test_function_generator(/*isTransientTest=*/true, /*isGarbageCollectionTest=*/true),
fakeDeviceInitParams,
'immersive-ar', { 'requiredFeatures': ['hit-test'] });
}
</script>