xrInputSource_gamepad_input_registered.https.html (4731B)
1 <!DOCTYPE html> 2 <script src="/resources/testharness.js"></script> 3 <script src="/resources/testharnessreport.js"></script> 4 <script src="../resources/webxr_util.js"></script> 5 <script src="../resources/webxr_test_constants.js"></script> 6 7 <script> 8 let testName = "WebXR InputSource's gamepad properly registers input"; 9 10 let fakeDeviceInitParams = TRACKED_IMMERSIVE_DEVICE; 11 12 let testFunction = function(session, fakeDeviceController, t) { 13 14 // There should only be one input source change event, which is from adding 15 // the input source at the start of the test. 16 let inputChangeEvents = 0; 17 function onInputSourcesChange(event) { 18 assert_equals(inputChangeEvents, 0, 19 "Gamepad button or input axis value changes should not fire an input source change event."); 20 inputChangeEvents++; 21 } 22 23 session.addEventListener('inputsourceschange', onInputSourcesChange, false); 24 25 // Create our input source and immediately toggle the primary input so that 26 // it appears as already needing to send a click event when it appears. 27 let input_source = fakeDeviceController.simulateInputSourceConnection({ 28 handedness: "right", 29 targetRayMode: "tracked-pointer", 30 pointerOrigin: VALID_POINTER_TRANSFORM, 31 profiles: [], 32 supportedButtons: [ 33 { 34 buttonType: 'grip', 35 pressed: false, 36 touched: false, 37 pressedValue: 0 38 }, 39 { 40 buttonType: 'touchpad', 41 pressed: false, 42 touched: false, 43 pressedValue: 0 44 } 45 ] 46 }); 47 48 let cached_input_source = null; 49 let cached_gamepad = null; 50 51 function assertSameObjects() { 52 assert_equals(session.inputSources[0], cached_input_source); 53 assert_equals(cached_input_source.gamepad, cached_gamepad); 54 55 // Also make sure that WebXR gamepads have the index and id values required 56 // by the spec. 57 assert_equals(cached_gamepad.index, -1); 58 assert_equals(cached_gamepad.id, ""); 59 } 60 61 // Input events and gamepad state changes (button presses, axis movements) 62 // need one frame to propagate, so this does (in order and running a rAF after 63 // each step): 64 // 1) Press the mock gamepad's button (so we can verify the button press makes 65 // its way to the WebXR gamepad and that it does not fire an 66 // inputsourceschange event). 67 // 2) Update the mock gamepad's input axes values (so we can verify the 68 // updated values make their way to the WebXR gamepad and that it does not 69 // fire an inputsourceschange event). 70 return new Promise((resolve) => { 71 requestSkipAnimationFrame(session, () => { 72 // Make sure the exposed gamepad has the number of buttons and axes we 73 // requested. 74 // 3 Buttons: trigger, grip, touchpad 75 // 2 Axes from the touchpad 76 cached_input_source = session.inputSources[0]; 77 cached_gamepad = cached_input_source.gamepad; 78 t.step(() => { 79 assert_equals(cached_gamepad.index, -1); 80 assert_equals(cached_gamepad.id, ""); 81 assert_equals(cached_gamepad.buttons.length, 3); 82 assert_equals(cached_gamepad.axes.length, 2); 83 // Initially, the button should not be pressed and the axes values should 84 // be set to 0. 85 assert_false(cached_gamepad.buttons[1].pressed); 86 assert_equals(cached_gamepad.axes[0], 0); 87 assert_equals(cached_gamepad.axes[1], 0); 88 }, "Verify initial state"); 89 // Simulate button press. 90 input_source.updateButtonState({ 91 buttonType: 'grip', 92 pressed: true, 93 touched: true, 94 value: 1.0 95 }); 96 session.requestAnimationFrame(() => { 97 t.step(() => { 98 assertSameObjects(); 99 assert_true(cached_gamepad.buttons[1].pressed); 100 }, "Gamepad is updated in place when a button is pressed"); 101 102 // Simulate input axes movement. 103 input_source.updateButtonState({ 104 buttonType: 'touchpad', 105 pressed: false, 106 touched: true, 107 value: 0, 108 xValue: 0.5, 109 yValue: -0.5 110 }); 111 session.requestAnimationFrame(() => { 112 // Input source and gamepad should not be re-created. They should be 113 // updated in place when input axes values change. 114 t.step(() => { 115 assertSameObjects(); 116 assert_equals(cached_gamepad.axes[0], 0.5); 117 assert_equals(cached_gamepad.axes[1], -0.5); 118 // Button that was pressed last frame should still be pressed. 119 assert_true(cached_gamepad.buttons[1].pressed); 120 }, "Gamepad is updated in place when axes values change"); 121 resolve(); 122 }); 123 }); 124 }); 125 }); 126 }; 127 128 xr_session_promise_test( 129 testName, testFunction, fakeDeviceInitParams, 'immersive-vr'); 130 </script>