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 = "WebXR InputSource's gamepad properly registers input";
let fakeDeviceInitParams = TRACKED_IMMERSIVE_DEVICE;
let testFunction = function(session, fakeDeviceController, t) {
// There should only be one input source change event, which is from adding
// the input source at the start of the test.
let inputChangeEvents = 0;
function onInputSourcesChange(event) {
assert_equals(inputChangeEvents, 0,
"Gamepad button or input axis value changes should not fire an input source change event.");
inputChangeEvents++;
}
session.addEventListener('inputsourceschange', onInputSourcesChange, false);
// Create our input source and immediately toggle the primary input so that
// it appears as already needing to send a click event when it appears.
let input_source = fakeDeviceController.simulateInputSourceConnection({
handedness: "right",
targetRayMode: "tracked-pointer",
pointerOrigin: VALID_POINTER_TRANSFORM,
profiles: [],
supportedButtons: [
{
buttonType: 'grip',
pressed: false,
touched: false,
pressedValue: 0
},
{
buttonType: 'touchpad',
pressed: false,
touched: false,
pressedValue: 0
}
]
});
let cached_input_source = null;
let cached_gamepad = null;
function assertSameObjects() {
assert_equals(session.inputSources[0], cached_input_source);
assert_equals(cached_input_source.gamepad, cached_gamepad);
// Also make sure that WebXR gamepads have the index and id values required
// by the spec.
assert_equals(cached_gamepad.index, -1);
assert_equals(cached_gamepad.id, "");
}
// Input events and gamepad state changes (button presses, axis movements)
// need one frame to propagate, so this does (in order and running a rAF after
// each step):
// 1) Press the mock gamepad's button (so we can verify the button press makes
// its way to the WebXR gamepad and that it does not fire an
// inputsourceschange event).
// 2) Update the mock gamepad's input axes values (so we can verify the
// updated values make their way to the WebXR gamepad and that it does not
// fire an inputsourceschange event).
return new Promise((resolve) => {
requestSkipAnimationFrame(session, () => {
// Make sure the exposed gamepad has the number of buttons and axes we
// requested.
// 3 Buttons: trigger, grip, touchpad
// 2 Axes from the touchpad
cached_input_source = session.inputSources[0];
cached_gamepad = cached_input_source.gamepad;
t.step(() => {
assert_equals(cached_gamepad.index, -1);
assert_equals(cached_gamepad.id, "");
assert_equals(cached_gamepad.buttons.length, 3);
assert_equals(cached_gamepad.axes.length, 2);
// Initially, the button should not be pressed and the axes values should
// be set to 0.
assert_false(cached_gamepad.buttons[1].pressed);
assert_equals(cached_gamepad.axes[0], 0);
assert_equals(cached_gamepad.axes[1], 0);
}, "Verify initial state");
// Simulate button press.
input_source.updateButtonState({
buttonType: 'grip',
pressed: true,
touched: true,
value: 1.0
});
session.requestAnimationFrame(() => {
t.step(() => {
assertSameObjects();
assert_true(cached_gamepad.buttons[1].pressed);
}, "Gamepad is updated in place when a button is pressed");
// Simulate input axes movement.
input_source.updateButtonState({
buttonType: 'touchpad',
pressed: false,
touched: true,
value: 0,
xValue: 0.5,
yValue: -0.5
});
session.requestAnimationFrame(() => {
// Input source and gamepad should not be re-created. They should be
// updated in place when input axes values change.
t.step(() => {
assertSameObjects();
assert_equals(cached_gamepad.axes[0], 0.5);
assert_equals(cached_gamepad.axes[1], -0.5);
// Button that was pressed last frame should still be pressed.
assert_true(cached_gamepad.buttons[1].pressed);
}, "Gamepad is updated in place when axes values change");
resolve();
});
});
});
});
};
xr_session_promise_test(
testName, testFunction, fakeDeviceInitParams, 'immersive-vr');
</script>