diff options
Diffstat (limited to 'testing/web-platform/tests/webxr/gamepads-module/xrInputSource_gamepad_disconnect.https.html')
-rw-r--r-- | testing/web-platform/tests/webxr/gamepads-module/xrInputSource_gamepad_disconnect.https.html | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webxr/gamepads-module/xrInputSource_gamepad_disconnect.https.html b/testing/web-platform/tests/webxr/gamepads-module/xrInputSource_gamepad_disconnect.https.html new file mode 100644 index 0000000000..bd69649d44 --- /dev/null +++ b/testing/web-platform/tests/webxr/gamepads-module/xrInputSource_gamepad_disconnect.https.html @@ -0,0 +1,159 @@ +<!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 gets disconnected when the input source is removed"; + +let watcherDone = new Event("watcherdone"); + +let fakeDeviceInitParams = TRACKED_IMMERSIVE_DEVICE; + +let testFunction = function(session, fakeDeviceController, t) { + let eventWatcher = new EventWatcher(t, session, ["watcherdone"]); + let eventPromise = eventWatcher.wait_for(["watcherdone"]); + + let inputChangeEvents = 0; + let cached_input_source = null; + function onInputSourcesChange(event) { + t.step(() => { + inputChangeEvents++; + + // The first change event should be adding our controller/gamepad. + if (inputChangeEvents === 1) { + // We should have one input source + assert_equals(session.inputSources.length, 1, + "should initially have an input source"); + assertGamepadConnected(); + } else if (inputChangeEvents === 2) { + // The second event should be disconnecting our gamepad, we should still + // have an input source. + assert_equals(session.inputSources.length, 1, + "removing the gamepad shouldn't remove the input source"); + // However, disconnecting the gamepad from the input source should cause + // the input source to be re-created. Verify this. + assertInputSourceRecreated(event); + assertGamepadDisconnected(); + cached_input_source = session.inputSources[0]; + } else if (inputChangeEvents === 3) { + assert_equals(session.inputSources.length, 1, + "re-adding the gamepad shouldn't add an extra input source"); + // The third event should be reconnecting our gamepad, we should still + // have an input source. However, it should have been re-created. + assertInputSourceRecreated(event); + assertGamepadConnected(); + } else if (inputChangeEvents === 4) { + // The fourth event should be disconnecting our gamepad, we should no + // longer have an input source. + assert_equals(session.inputSources.length, 0, + "input source should have been disconnected"); + assertGamepadDisconnected(); + } else if (inputChangeEvents === 5) { + // The fifth event should be re-connecting our gamepad to prep for + // ending the session. + assert_equals(session.inputSources.length, 1, + "input source should have been re-connected"); + assertGamepadConnected(); + session.dispatchEvent(watcherDone); + } + }); + } + + function assertInputSourceRecreated(event) { + assert_equals(event.added.length, 1); + assert_equals(event.removed.length, 1); + assert_equals(session.inputSources[0], event.added[0]); + assert_equals(cached_input_source, event.removed[0]); + } + + function assertGamepadConnected() { + cached_input_source = session.inputSources[0]; + assert_not_equals(cached_input_source, null, + "Expect to get a cached_input_source, iteration: " + inputChangeEvents); + assert_not_equals(cached_input_source.gamepad, null, + "Expect to have a gamepad, iteration: " + inputChangeEvents); + assert_equals(cached_input_source.gamepad.index, -1, + "WebXR Gamepad.index must be -1, iteration: " + inputChangeEvents); + assert_equals(cached_input_source.gamepad.id, "", + "WebXR Gamepad.id must be empty string, iteration: " + inputChangeEvents); + assert_true(cached_input_source.gamepad.connected, + "Expect the gamepad to be connected, iteration: " + inputChangeEvents); + } + + function assertGamepadDisconnected() { + assert_not_equals(cached_input_source, null, + "Expect to have a cached_input_source, iteration: " + inputChangeEvents); + assert_not_equals(cached_input_source.gamepad, null, + "Expect to have a gamepad on cached_input_source, iteration: " + inputChangeEvents); + assert_equals(cached_input_source.gamepad.index, -1, + "WebXR Gamepad.index must be -1, iteration: " + inputChangeEvents); + assert_equals(cached_input_source.gamepad.id, "", + "WebXR Gamepad.id must be empty string, iteration: " + inputChangeEvents); + assert_false(cached_input_source.gamepad.connected, + "Expect cached gamepad to be disconnected, iteration: " + inputChangeEvents); + } + + session.addEventListener('inputsourceschange', onInputSourcesChange, false); + + // A set of supported buttons which should cause the runtime to treat the + // controller as supporting a gamepad. + let gamepadButtons = [ + { + buttonType: 'grip', + pressed: false, + touched: false, + pressedValue: 0 + }, + { + buttonType: 'touchpad', + pressed: false, + touched: false, + pressedValue: 0 + } + ]; + + let input_source = fakeDeviceController.simulateInputSourceConnection({ + handedness: "right", + targetRayMode: "tracked-pointer", + pointerOrigin: VALID_POINTER_TRANSFORM, + profiles: [], + supportedButtons: gamepadButtons + }); + + // Input events need one frame to propagate, so this does (in order and running + // a rAF after each step: + // 1. Disconnect the gamepad (so we can verify that the gamepad is disconnected) + // 2. Reconnect the gamepad (so we can set up to disconnect the controller) + // 3. Disconnect the controller (so we can verify that it's gamepad gets disconnected). + // 4. Adds the controller back (so we can test the end Session) + // 5. Waits for all of the input events to finish propagating, then ends the + // session, at which point the controller should be disconnected. + return new Promise((resolve) => { + requestSkipAnimationFrame(session, () => { + input_source.setSupportedButtons([]); + session.requestAnimationFrame(() => { + input_source.setSupportedButtons(gamepadButtons); + session.requestAnimationFrame(() => { + input_source.disconnect(); + session.requestAnimationFrame(() => { + input_source.reconnect(); + session.requestAnimationFrame(() => { + eventPromise.then(() => { + session.end().then(() => { + assertGamepadDisconnected(); + resolve(); + }); + }); + }); + }); + }); + }); + }); + }); +}; + +xr_session_promise_test( + testName, testFunction, fakeDeviceInitParams, 'immersive-vr'); +</script> |