tor-browser

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

RTCPeerConnection-setLocalDescription-rollback.html (6840B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <title>RTCPeerConnection.prototype.setLocalDescription rollback</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  //   generateAudioReceiveOnlyOffer
     15 
     16  /*
     17    4.3.2.  Interface Definition
     18      [Constructor(optional RTCConfiguration configuration)]
     19      interface RTCPeerConnection : EventTarget {
     20        Promise<void>                      setLocalDescription(
     21            RTCSessionDescriptionInit description);
     22 
     23        readonly attribute RTCSessionDescription? localDescription;
     24        readonly attribute RTCSessionDescription? currentLocalDescription;
     25        readonly attribute RTCSessionDescription? pendingLocalDescription;
     26 
     27        Promise<void>                      setRemoteDescription(
     28            RTCSessionDescriptionInit description);
     29 
     30        readonly attribute RTCSessionDescription? remoteDescription;
     31        readonly attribute RTCSessionDescription? currentRemoteDescription;
     32        readonly attribute RTCSessionDescription? pendingRemoteDescription;
     33        ...
     34      };
     35 
     36    4.6.2.  RTCSessionDescription Class
     37      dictionary RTCSessionDescriptionInit {
     38        required RTCSdpType type;
     39                 DOMString  sdp = "";
     40      };
     41 
     42    4.6.1.  RTCSdpType
     43      enum RTCSdpType {
     44        "offer",
     45        "pranswer",
     46        "answer",
     47        "rollback"
     48      };
     49   */
     50 
     51  /*
     52    4.3.1.6.  Set the RTCSessionSessionDescription
     53      2.2.2.  If description is set as a local description, then run one of the
     54              following steps:
     55        - If description is of type "rollback", then this is a rollback. Set
     56          connection.pendingLocalDescription to null and signaling state to stable.
     57   */
     58  promise_test(t=> {
     59    const pc = new RTCPeerConnection();
     60    t.add_cleanup(() => pc.close());
     61 
     62    const states = [];
     63    pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
     64 
     65    return pc.createOffer()
     66    .then(offer => pc.setLocalDescription(offer))
     67    .then(() => {
     68      assert_equals(pc.signalingState, 'have-local-offer');
     69      assert_not_equals(pc.localDescription, null);
     70      assert_equals(pc.localDescription, pc.localDescription);
     71      assert_equals(pc.pendingLocalDescription, pc.localDescription);
     72      assert_equals(pc.currentLocalDescription, null);
     73 
     74      return pc.setLocalDescription({ type: 'rollback' });
     75    })
     76    .then(() => {
     77      assert_equals(pc.signalingState, 'stable');
     78      assert_equals(pc.localDescription, null);
     79      assert_equals(pc.pendingLocalDescription, null);
     80      assert_equals(pc.currentLocalDescription, null);
     81 
     82      assert_array_equals(states, ['have-local-offer', 'stable']);
     83    });
     84  }, 'setLocalDescription(rollback) from have-local-offer state should reset back to stable state');
     85 
     86  /*
     87    4.3.1.6.  Set the RTCSessionSessionDescription
     88      2.3.  If the description's type is invalid for the current signaling state of
     89            connection, then reject p with a newly created InvalidStateError and abort
     90            these steps. Note that this implies that once the answerer has performed
     91            setLocalDescription with his answer, this cannot be rolled back.
     92 
     93    [jsep]
     94      4.1.8.2.  Rollback
     95        - Rollback can only be used to cancel proposed changes;
     96          there is no support for rolling back from a stable state to a
     97          previous stable state
     98   */
     99  promise_test(t => {
    100    const pc = new RTCPeerConnection();
    101    t.add_cleanup(() => pc.close());
    102    return promise_rejects_dom(t, 'InvalidStateError',
    103      pc.setLocalDescription({ type: 'rollback' }));
    104  }, `setLocalDescription(rollback) from stable state should reject with InvalidStateError`);
    105 
    106  promise_test(t => {
    107    const pc = new RTCPeerConnection();
    108    t.add_cleanup(() => pc.close());
    109    return generateAudioReceiveOnlyOffer(pc)
    110    .then(offer =>
    111      pc.setRemoteDescription(offer)
    112      .then(() => pc.createAnswer()))
    113    .then(answer => pc.setLocalDescription(answer))
    114    .then(() => {
    115      return promise_rejects_dom(t, 'InvalidStateError',
    116        pc.setLocalDescription({ type: 'rollback' }));
    117    });
    118  }, `setLocalDescription(rollback) after setting answer description should reject with InvalidStateError`);
    119 
    120  promise_test(async t => {
    121    const pc = new RTCPeerConnection();
    122    t.add_cleanup(() => pc.close());
    123    const offer = await generateAudioReceiveOnlyOffer(pc);
    124    await pc.setRemoteDescription(offer);
    125    await promise_rejects_dom(t, 'InvalidStateError', pc.setLocalDescription({ type: 'rollback' }));
    126  }, `setLocalDescription(rollback) after setting a remote offer should reject with InvalidStateError`);
    127 
    128  promise_test(t => {
    129    const pc = new RTCPeerConnection();
    130    t.add_cleanup(() => pc.close());
    131    return pc.createOffer()
    132    .then(offer => pc.setLocalDescription(offer))
    133    .then(() => pc.setLocalDescription({
    134      type: 'rollback',
    135      sdp: '!<Invalid SDP Content>;'
    136    }));
    137  }, `setLocalDescription(rollback) should ignore invalid sdp content and succeed`);
    138 
    139  promise_test(async t => {
    140    const pc = new RTCPeerConnection();
    141    t.add_cleanup(() => pc.close());
    142 
    143    pc.addTransceiver('audio', { direction: 'recvonly' });
    144    await pc.setLocalDescription(await pc.createOffer());
    145    const sldPromise = pc.setLocalDescription({type: "rollback"});
    146 
    147    assert_equals(pc.signalingState, "have-local-offer", "signalingState should not be set synchronously after a call to sLD");
    148 
    149    assert_not_equals(pc.pendingLocalDescription, null, "pendingLocalDescription should not be set synchronously after a call to sLD");
    150    assert_equals(pc.pendingLocalDescription.type, "offer");
    151    assert_equals(pc.pendingLocalDescription, pc.localDescription);
    152    assert_equals(pc.pendingRemoteDescription, null, "pendingRemoteDescription should never be set due to sLD(offer)");
    153 
    154    const stablePromise = new Promise(resolve => {
    155      pc.onsignalingstatechange = () => {
    156        resolve(pc.signalingState);
    157      }
    158    });
    159    const raceValue = await Promise.race([stablePromise, sldPromise]);
    160    assert_equals(raceValue, "stable", "signalingstatechange event should fire before sLD resolves");
    161    assert_equals(pc.pendingLocalDescription, null, "pendingLocalDescription should be updated before the signalingstatechange event");
    162    assert_equals(pc.pendingRemoteDescription, null, "pendingRemoteDescription should never be set due to sLD(offer)");
    163 
    164    await sldPromise;
    165  }, "setLocalDescription(rollback) should update internal state with a queued tassk, in the right order");
    166 
    167 </script>