tor-browser

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

RTCPeerConnection-addTransceiver-renegotiation.https.html (3062B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <meta name="timeout" content="long">
      4 <title>RTCPeerConnection: media flows to a second unidirectional transceiver added through renegotiation.</title>
      5 <script src="/resources/testharness.js"></script>
      6 <script src="/resources/testharnessreport.js"></script>
      7 <script src="RTCPeerConnection-helper.js"></script>
      8 <script>
      9  'use strict';
     10 
     11  async function doTest(t, kind, firstTransceiverDirection) {
     12    const pc1 = new RTCPeerConnection();
     13    const pc2 = new RTCPeerConnection();
     14    t.add_cleanup(() => pc1.close());
     15    t.add_cleanup(() => pc2.close());
     16 
     17    exchangeIceCandidates(pc1, pc2);
     18 
     19    // Add a transceiver that we won't use and negotiate.
     20    pc1.addTransceiver(kind, {direction: "recvonly"});
     21    await pc1.setLocalDescription();
     22    await pc2.setRemoteDescription(pc1.localDescription);
     23    const [sendTransceiver1] = pc2.getTransceivers();
     24    sendTransceiver1.direction = firstTransceiverDirection;
     25    await pc2.setLocalDescription();
     26    await pc1.setRemoteDescription(pc2.localDescription);
     27 
     28    // Add another transceiver, that we will use, and renegotiate.
     29    const stream = await getNoiseStream({[kind]: true});
     30    const [track] = stream.getTracks();
     31    t.add_cleanup(() => track.stop());
     32 
     33    pc1.addTransceiver(kind, {direction: "recvonly"});
     34    await pc1.setLocalDescription();
     35    await pc2.setRemoteDescription(pc1.localDescription);
     36    const [, sendTransceiver2] = pc2.getTransceivers();
     37    sendTransceiver2.direction = "sendonly";
     38    sendTransceiver2.sender.replaceTrack(track);
     39 
     40    await pc2.setLocalDescription();
     41    await pc1.setRemoteDescription(pc2.localDescription);
     42 
     43    const [, recvTransceiver] = pc1.getTransceivers();
     44    const {receiver} = recvTransceiver;
     45    const threshold = 10;
     46    let inboundStats, timedout = false;
     47    t.step_timeout(() => timedout = true, 10000);
     48    while (!timedout) {
     49      const stats = await receiver.getStats();
     50      inboundStats = [...stats.values()].find(({type}) => type == "inbound-rtp");
     51      if (inboundStats?.packetsReceived > threshold) break;
     52      await new Promise(r => t.step_timeout(r, 50));
     53    }
     54    assert_greater_than(inboundStats?.packetsReceived,
     55      threshold,
     56      "packets received indicates media flow."
     57    );
     58  }
     59 
     60  promise_test(async t => {
     61    await doTest(t, "video", "sendonly");
     62  }, "Video flows to RTCPeerConnection's second transceiver added through renegotiation, with first transceiver also sending");
     63 
     64  promise_test(async t => {
     65    await doTest(t, "audio", "sendonly");
     66  }, "Audio flows to RTCPeerConnection's second transceiver added through renegotiation, with first transceiver also sending");
     67 
     68  promise_test(async t => {
     69    await doTest(t, "video", "inactive");
     70  }, "Video flows to RTCPeerConnection's second transceiver added through renegotiation, with first transceiver inactive");
     71 
     72  promise_test(async t => {
     73    await doTest(t, "audio", "inactive");
     74  }, "Audio flows to RTCPeerConnection's second transceiver added through renegotiation, with first transceiver inactive");
     75 
     76 </script>