tor-browser

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

RTCPeerConnection-setLocalDescription.html (5583B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <title>RTCPeerConnection.prototype.setLocalDescription</title>
      4 <script src="/resources/testharness.js"></script>
      5 <script src="/resources/testharnessreport.js"></script>
      6 <script src="RTCPeerConnection-helper.js"></script>
      7 <script>
      8  'use strict';
      9 
     10  // Test is based on the following editor draft:
     11  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
     12 
     13  // The following helper functions are called from RTCPeerConnection-helper.js:
     14  //   generateDataChannelOffer
     15  //   assert_session_desc_not_similar
     16  //   assert_session_desc_similar
     17 
     18  /*
     19    4.3.2.  Interface Definition
     20      [Constructor(optional RTCConfiguration configuration)]
     21      interface RTCPeerConnection : EventTarget {
     22        Promise<void>                      setRemoteDescription(
     23            RTCSessionDescriptionInit description);
     24 
     25        readonly attribute RTCSessionDescription? remoteDescription;
     26        readonly attribute RTCSessionDescription? currentRemoteDescription;
     27        readonly attribute RTCSessionDescription? pendingRemoteDescription;
     28        ...
     29      };
     30 
     31    4.6.2.  RTCSessionDescription Class
     32      dictionary RTCSessionDescriptionInit {
     33        required RTCSdpType type;
     34                 DOMString  sdp = "";
     35      };
     36 
     37    4.6.1.  RTCSdpType
     38      enum RTCSdpType {
     39        "offer",
     40        "pranswer",
     41        "answer",
     42        "rollback"
     43      };
     44   */
     45 
     46  promise_test(t => {
     47    const pc = new RTCPeerConnection();
     48    t.add_cleanup(() => pc.close());
     49 
     50    const states = [];
     51    pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
     52 
     53    return generateAudioReceiveOnlyOffer(pc)
     54    .then(offer1 =>
     55      pc.setLocalDescription(offer1)
     56      .then(() => generateAnswer(offer1))
     57      .then(answer => pc.setRemoteDescription(answer))
     58      .then(() => {
     59        pc.createDataChannel('test');
     60        return generateVideoReceiveOnlyOffer(pc);
     61      })
     62      .then(offer2 =>
     63        pc.setLocalDescription(offer2)
     64        .then(() => {
     65          assert_equals(pc.signalingState, 'have-local-offer');
     66          assert_session_desc_not_similar(offer1, offer2);
     67          assert_session_desc_similar(pc.localDescription, offer2);
     68          assert_session_desc_similar(pc.currentLocalDescription, offer1);
     69          assert_session_desc_similar(pc.pendingLocalDescription, offer2);
     70 
     71          assert_array_equals(states, ['have-local-offer', 'stable', 'have-local-offer']);
     72        })));
     73  }, 'Calling createOffer() and setLocalDescription() again after one round of local-offer/remote-answer should succeed');
     74 
     75  promise_test(async t => {
     76    const pc1 = new RTCPeerConnection();
     77    t.add_cleanup(() => pc1.close());
     78 
     79    const pc2 = new RTCPeerConnection();
     80    t.add_cleanup(() => pc2.close());
     81 
     82    const states = [];
     83    pc1.addEventListener('signalingstatechange', () => states.push(pc1.signalingState));
     84 
     85    assert_equals(pc1.localDescription, null);
     86    assert_equals(pc1.currentLocalDescription, null);
     87    assert_equals(pc1.pendingLocalDescription, null);
     88 
     89    pc1.createDataChannel('test');
     90    const offer = await pc1.createOffer();
     91 
     92    assert_equals(pc1.localDescription, null);
     93    assert_equals(pc1.currentLocalDescription, null);
     94    assert_equals(pc1.pendingLocalDescription, null);
     95 
     96    await pc1.setLocalDescription(offer);
     97 
     98    assert_session_desc_similar(pc1.localDescription, offer);
     99    assert_equals(pc1.currentLocalDescription, null);
    100    assert_session_desc_similar(pc1.pendingLocalDescription, offer);
    101 
    102    await pc2.setRemoteDescription(offer);
    103    const answer = await pc2.createAnswer();
    104    await pc2.setLocalDescription(answer);
    105    await pc1.setRemoteDescription(answer);
    106 
    107    assert_equals(pc1.signalingState, 'stable');
    108    assert_session_desc_similar(pc1.localDescription, offer);
    109    assert_session_desc_similar(pc1.currentLocalDescription, offer);
    110    assert_equals(pc1.pendingLocalDescription, null);
    111 
    112    const stream = await getNoiseStream({audio:true});
    113    pc2.addTrack(stream.getTracks()[0], stream);
    114 
    115    const reoffer = await pc2.createOffer();
    116    await pc2.setLocalDescription(reoffer);
    117    await pc1.setRemoteDescription(reoffer);
    118    const reanswer = await pc1.createAnswer();
    119    await pc1.setLocalDescription(reanswer);
    120 
    121    assert_session_desc_similar(pc1.localDescription, reanswer);
    122    assert_session_desc_similar(pc1.currentLocalDescription, reanswer);
    123    assert_equals(pc1.pendingLocalDescription, null);
    124  }, 'Switching role from answerer to offerer after going back to stable state should succeed');
    125 
    126  promise_test(async t => {
    127    const pc = new RTCPeerConnection();
    128    t.add_cleanup(() => pc.close());
    129    const offer = await pc.createOffer();
    130    let eventSequence = '';
    131    const signalingstatechangeResolver = new Resolver();
    132    pc.onsignalingstatechange = () => {
    133      eventSequence += 'onsignalingstatechange;';
    134      signalingstatechangeResolver.resolve();
    135    };
    136    await pc.setLocalDescription(offer);
    137    eventSequence += 'setLocalDescription;';
    138    await signalingstatechangeResolver;
    139    assert_equals(eventSequence, 'onsignalingstatechange;setLocalDescription;');
    140  }, 'onsignalingstatechange fires before setLocalDescription resolves');
    141 
    142  /*
    143    TODO
    144      4.3.2.  setLocalDescription
    145        4.  If description.sdp is null and description.type is pranswer, set description.sdp
    146            to lastAnswer.
    147        7.  If description.type is pranswer and description.sdp does not match lastAnswer,
    148            reject the promise with a newly created InvalidModificationError and abort these
    149            steps.
    150   */
    151 
    152 </script>