1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 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>
|