| <!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> |