Commit 9f2651be authored by Jacob DeWitt's avatar Jacob DeWitt Committed by Commit Bot

WebXR Gamepad input layout test

Verifies the following behavior for WebXR Gamepads:
1) Changes to the button and input axis values for the mock gamepad
   object make their way through all the plumbing and on to the session's
   input source's Gamepad.
2) Changing button and input axis values cause the Gamepad to be updated
   in-place. XRInputSource and Gamepad objects should not be re-created
   in this case and an inputsourceschange event should not be fired.

Bug: 976978
Change-Id: I6de7a45e357e6900eccca103741dddc33fc9d495
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1673083Reviewed-by: default avatarAlexander Cooper <alcooper@chromium.org>
Commit-Queue: Jacob DeWitt <jacde@chromium.org>
Cr-Commit-Position: refs/heads/master@{#671898}
parent cac7ec80
...@@ -232,6 +232,28 @@ class MockXRInputSource { ...@@ -232,6 +232,28 @@ class MockXRInputSource {
this.gamepad_ = null; this.gamepad_ = null;
} }
setGamepadButtonCount(button_count) {
this.gamepad_.buttons = [];
for (let i = 0; i < button_count; ++i) {
this.gamepad_.buttons.push(new device.mojom.GamepadButton());
}
}
setGamepadAxesCount(axes_count) {
this.gamepad_.axes = [];
for (let i = 0; i < axes_count; ++i) {
this.gamepad_.axes.push(0);
}
}
setGamepadButtonPressed(button_index, is_pressed) {
this.gamepad_.buttons[button_index].pressed = is_pressed;
}
setGamepadAxisValue(index, value) {
this.gamepad_.axes[index] = value;
}
getInputSourceState() { getInputSourceState() {
let input_state = new device.mojom.XRInputSourceState(); let input_state = new device.mojom.XRInputSourceState();
......
<!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>
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