blob: b321826e602fe279cfdcdf56ede35a0719f228a9 [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 = "WebXR InputSource's gamepad properly registers input";
let fakeDeviceInitParams = { supportsImmersive:true };
let requestSessionModes = ['immersive-vr'];
let testFunction = function(session, t, fakeDeviceController) {
// 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
}]);
// 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);
// Session must have a baseLayer or frame requests will be ignored.
session.updateRenderState({ baseLayer: new XRWebGLLayer(session, gl) });
// 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 = new MockXRInputSource();
input_source.connectGamepad();
input_source.setGamepadButtonCount(1);
input_source.setGamepadAxesCount(2);
fakeDeviceController.addInputSource(input_source);
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);
}
// 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) => {
session.requestAnimationFrame(() => {
// Make sure the exposed gamepad has the number of buttons and axes we
// requested.
cached_input_source = session.inputSources[0];
cached_gamepad = cached_input_source.gamepad;
assert_equals(cached_gamepad.buttons.length, 1);
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[0].pressed);
assert_equals(cached_gamepad.axes[0], 0);
assert_equals(cached_gamepad.axes[1], 0);
// Simulate button press.
input_source.setGamepadButtonPressed(0, true);
session.requestAnimationFrame(() => {
// Input source and gamepad should not be re-created. They should be
// updated in place when a button is pressed.
assertSameObjects();
assert_true(cached_gamepad.buttons[0].pressed);
// Simulate input axes movement.
input_source.setGamepadAxisValue(0, 0.5);
input_source.setGamepadAxisValue(1, -0.5);
session.requestAnimationFrame(() => {
// Input source and gamepad should not be re-created. They should be
// updated in place when input axes values change.
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[0].pressed);
resolve();
});
});
});
});
};
xr_session_promise_test(
testFunction, fakeDeviceInitParams, requestSessionModes, testName);
</script>