Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/webxr_util.js"></script>
<script src="resources/webxr_test_constants.js"></script>
<script>
let testName = "Input sources are re-created when handedness or target ray mode changes";
let watcherDone = new Event("watcherdone");
let fakeDeviceInitParams = TRACKED_IMMERSIVE_DEVICE;
let testFunction = function(session, fakeDeviceController, t) {
let eventWatcher = new EventWatcher(t, session, ["watcherdone"]);
let eventPromise = eventWatcher.wait_for(["watcherdone"]);
let inputChangeEvents = 0;
let cached_input_source = null;
function onInputSourcesChange(event) {
t.step(() => {
inputChangeEvents++;
assert_equals(event.session, session);
if (inputChangeEvents == 1) {
// The first change event should be adding our controller.
validateAdded(event.added, 1);
validateRemoved(event.removed, 0);
cached_input_source = getInputSources()[0];
assert_not_equals(cached_input_source, null);
assert_equals(cached_input_source.handedness, "none");
assert_equals(cached_input_source.targetRayMode, "gaze");
assertProfilesEqual(cached_input_source.profiles, ["a", "b"]);
} else if (inputChangeEvents == 2) {
// The second event should be replacing the controller with one that has
// the updated target ray mode.
validateInputSourceChange(event, "none", "tracked-pointer", ["a", "b"]);
cached_input_source = getInputSources()[0];
} else if (inputChangeEvents == 3) {
// The third event should be replacing the controller with one that has
// the updated handedness.
validateInputSourceChange(event, "left", "tracked-pointer", ["a", "b"]);
cached_input_source = getInputSources()[0];
} else if (inputChangeEvents == 4) {
// The fourth event should be updating the second value in the profiles
// array.
validateInputSourceChange(event, "left", "tracked-pointer", ["a", "c"]);
cached_input_source = getInputSources()[0];
} else if (inputChangeEvents == 5) {
// The fifth event should be removing the second value from the profiles
// array.
validateInputSourceChange(event, "left", "tracked-pointer", ["a"]);
session.dispatchEvent(watcherDone);
}
});
}
function assertProfilesEqual(profiles, expected_profiles) {
assert_equals(profiles.length, expected_profiles.length);
for (let i = 0; i < profiles.length; ++i) {
assert_equals(profiles[i], expected_profiles[i]);
}
}
function validateInputSourceChange(
event, expected_hand, expected_mode, expected_profiles) {
validateAdded(event.added, 1);
validateRemoved(event.removed, 1);
assert_true(event.removed.includes(cached_input_source));
assert_false(event.added.includes(cached_input_source));
let source = event.added[0];
assert_equals(source.handedness, expected_hand);
assert_equals(source.targetRayMode, expected_mode);
assertProfilesEqual(source.profiles, expected_profiles);
}
function validateAdded(added, length) {
t.step(() => {
assert_not_equals(added, null);
assert_equals(added.length, length,
"Added length matches expectations");
let currentSources = getInputSources();
added.forEach((source) => {
assert_true(currentSources.includes(source),
"Every element in added should be in the input source list");
});
});
}
function validateRemoved(removed, length) {
t.step(() => {
assert_not_equals(removed, null);
assert_equals(removed.length, length,
"Removed length matches expectations");
let currentSources = getInputSources();
removed.forEach((source) => {
assert_false(currentSources.includes(source),
"No element in removed should be in the input source list");
});
});
}
function getInputSources() {
return Array.from(session.inputSources.values());
}
session.addEventListener('inputsourceschange', onInputSourcesChange, false);
// Create a gaze based input source with no handedness that we can change
// to validate SameObject properties.
let input_source = fakeDeviceController.simulateInputSourceConnection({
handedness: "none",
targetRayMode: "gaze",
pointerOrigin: VALID_POINTER_TRANSFORM,
profiles: ["a", "b"]
});
// Make our first input source change after one frame, and wait an additional
// frame for that change to propogate. Then make additional changes, waiting
// one frame after each one to verify that they fired an inputsourceschanged
// event.
session.requestAnimationFrame((time, xrFrame) => {
input_source.setTargetRayMode("tracked-pointer");
session.requestAnimationFrame((time, xrFrame) => {
input_source.setHandedness("left");
session.requestAnimationFrame((time, xrFrame) => {
input_source.setProfiles(["a", "c"]);
session.requestAnimationFrame((time, xrFrame) => {
input_source.setProfiles(["a"]);
session.requestAnimationFrame((time, xrFrame) => {});
});
});
});
});
return eventPromise;
};
xr_session_promise_test(
testName, testFunction, fakeDeviceInitParams, 'immersive-vr');
</script>