tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

xrInputSource_gamepad_disconnect.https.html (6509B)


      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 gets disconnected when the input source is removed";
      9 
     10 let watcherDone = new Event("watcherdone");
     11 
     12 let fakeDeviceInitParams = TRACKED_IMMERSIVE_DEVICE;
     13 
     14 let testFunction = function(session, fakeDeviceController, t) {
     15  let eventWatcher = new EventWatcher(t, session, ["watcherdone"]);
     16  let eventPromise = eventWatcher.wait_for(["watcherdone"]);
     17 
     18  let inputChangeEvents = 0;
     19  let cached_input_source = null;
     20  function onInputSourcesChange(event) {
     21    t.step(() => {
     22      inputChangeEvents++;
     23 
     24      // The first change event should be adding our controller/gamepad.
     25      if (inputChangeEvents === 1) {
     26        // We should have one input source
     27        assert_equals(session.inputSources.length, 1,
     28          "should initially have an input source");
     29        assertGamepadConnected();
     30      } else if (inputChangeEvents === 2) {
     31        // The second event should be disconnecting our gamepad, we should still
     32        // have an input source.
     33        assert_equals(session.inputSources.length, 1,
     34          "removing the gamepad shouldn't remove the input source");
     35        // However, disconnecting the gamepad from the input source should cause
     36        // the input source to be re-created. Verify this.
     37        assertInputSourceRecreated(event);
     38        assertGamepadDisconnected();
     39        cached_input_source = session.inputSources[0];
     40      } else if (inputChangeEvents === 3) {
     41        assert_equals(session.inputSources.length, 1,
     42          "re-adding the gamepad shouldn't add an extra input source");
     43        // The third event should be reconnecting our gamepad, we should still
     44        // have an input source. However, it should have been re-created.
     45        assertInputSourceRecreated(event);
     46        assertGamepadConnected();
     47      } else if (inputChangeEvents === 4) {
     48        // The fourth event should be disconnecting our gamepad, we should no
     49        // longer have an input source.
     50        assert_equals(session.inputSources.length, 0,
     51          "input source should have been disconnected");
     52        assertGamepadDisconnected();
     53      } else if (inputChangeEvents === 5) {
     54        // The fifth event should be re-connecting our gamepad to prep for
     55        // ending the session.
     56        assert_equals(session.inputSources.length, 1,
     57          "input source should have been re-connected");
     58        assertGamepadConnected();
     59        session.dispatchEvent(watcherDone);
     60      }
     61    });
     62  }
     63 
     64  function assertInputSourceRecreated(event) {
     65    assert_equals(event.added.length, 1);
     66    assert_equals(event.removed.length, 1);
     67    assert_equals(session.inputSources[0], event.added[0]);
     68    assert_equals(cached_input_source, event.removed[0]);
     69  }
     70 
     71  function assertGamepadConnected() {
     72    cached_input_source = session.inputSources[0];
     73    assert_not_equals(cached_input_source, null,
     74      "Expect to get a cached_input_source, iteration: " + inputChangeEvents);
     75    assert_not_equals(cached_input_source.gamepad, null,
     76      "Expect to have a gamepad, iteration: " + inputChangeEvents);
     77    assert_equals(cached_input_source.gamepad.index, -1,
     78      "WebXR Gamepad.index must be -1, iteration: " + inputChangeEvents);
     79    assert_equals(cached_input_source.gamepad.id, "",
     80      "WebXR Gamepad.id must be empty string, iteration: " + inputChangeEvents);
     81    assert_true(cached_input_source.gamepad.connected,
     82      "Expect the gamepad to be connected, iteration: " + inputChangeEvents);
     83  }
     84 
     85  function assertGamepadDisconnected() {
     86    assert_not_equals(cached_input_source, null,
     87      "Expect to have a cached_input_source, iteration: " + inputChangeEvents);
     88    assert_not_equals(cached_input_source.gamepad, null,
     89      "Expect to have a gamepad on cached_input_source, iteration: " + inputChangeEvents);
     90    assert_equals(cached_input_source.gamepad.index, -1,
     91      "WebXR Gamepad.index must be -1, iteration: " + inputChangeEvents);
     92    assert_equals(cached_input_source.gamepad.id, "",
     93      "WebXR Gamepad.id must be empty string, iteration: " + inputChangeEvents);
     94    assert_false(cached_input_source.gamepad.connected,
     95      "Expect cached gamepad to be disconnected, iteration: " + inputChangeEvents);
     96  }
     97 
     98  session.addEventListener('inputsourceschange', onInputSourcesChange, false);
     99 
    100  // A set of supported buttons which should cause the runtime to treat the
    101  // controller as supporting a gamepad.
    102  let gamepadButtons = [
    103    {
    104      buttonType: 'grip',
    105      pressed: false,
    106      touched: false,
    107      pressedValue: 0
    108    },
    109    {
    110      buttonType: 'touchpad',
    111      pressed: false,
    112      touched: false,
    113      pressedValue: 0
    114    }
    115  ];
    116 
    117  let input_source = fakeDeviceController.simulateInputSourceConnection({
    118    handedness: "right",
    119    targetRayMode: "tracked-pointer",
    120    pointerOrigin: VALID_POINTER_TRANSFORM,
    121    profiles: [],
    122    supportedButtons: gamepadButtons
    123  });
    124 
    125  // Input events need one frame to propagate, so this does (in order and running
    126  // a rAF after each step:
    127  // 1. Disconnect the gamepad (so we can verify that the gamepad is disconnected)
    128  // 2. Reconnect the gamepad (so we can set up to disconnect the controller)
    129  // 3. Disconnect the controller (so we can verify that it's gamepad gets disconnected).
    130  // 4. Adds the controller back (so we can test the end Session)
    131  // 5. Waits for all of the input events to finish propagating, then ends the
    132  // session, at which point the controller should be disconnected.
    133  return new Promise((resolve) => {
    134    requestSkipAnimationFrame(session, () => {
    135      input_source.setSupportedButtons([]);
    136      session.requestAnimationFrame(() => {
    137        input_source.setSupportedButtons(gamepadButtons);
    138        session.requestAnimationFrame(() => {
    139          input_source.disconnect();
    140          session.requestAnimationFrame(() => {
    141            input_source.reconnect();
    142            session.requestAnimationFrame(() => {
    143              eventPromise.then(() => {
    144                session.end().then(() => {
    145                  assertGamepadDisconnected();
    146                  resolve();
    147                });
    148              });
    149            });
    150          });
    151        });
    152      });
    153    });
    154  });
    155 };
    156 
    157 xr_session_promise_test(
    158  testName, testFunction, fakeDeviceInitParams, 'immersive-vr');
    159 </script>