tor-browser

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

RTCPeerConnection-setDescription-transceiver.html (11249B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <title>RTCPeerConnection Set Session Description - Transceiver Tests</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  //   generateAnswer
     15 
     16  /*
     17    4.3.2.  Interface Definition
     18 
     19      [Constructor(optional RTCConfiguration configuration)]
     20      interface RTCPeerConnection : EventTarget {
     21        Promise<void>                      setLocalDescription(
     22            RTCSessionDescriptionInit description);
     23 
     24        Promise<void>                      setRemoteDescription(
     25            RTCSessionDescriptionInit description);
     26        ...
     27      };
     28 
     29    4.6.2.  RTCSessionDescription Class
     30      dictionary RTCSessionDescriptionInit {
     31        required RTCSdpType type;
     32                 DOMString  sdp = "";
     33      };
     34 
     35    4.6.1.  RTCSdpType
     36      enum RTCSdpType {
     37        "offer",
     38        "pranswer",
     39        "answer",
     40        "rollback"
     41      };
     42 
     43    5.4.  RTCRtpTransceiver Interface
     44 
     45      interface RTCRtpTransceiver {
     46        readonly attribute DOMString?                  mid;
     47        [SameObject]
     48        readonly attribute RTCRtpSender                sender;
     49        [SameObject]
     50        readonly attribute RTCRtpReceiver              receiver;
     51        readonly attribute RTCRtpTransceiverDirection  direction;
     52        readonly attribute RTCRtpTransceiverDirection? currentDirection;
     53        ...
     54      };
     55   */
     56 
     57  /*
     58    4.3.1.6.  Set the RTCSessionSessionDescription
     59      7.  If description is set as a local description, then run the following steps for
     60          each media description in description that is not yet associated with an
     61          RTCRtpTransceiver object:
     62        1.  Let transceiver be the RTCRtpTransceiver used to create the media
     63            description.
     64        2.  Set transceiver's mid value to the mid of the corresponding media
     65            description.
     66   */
     67  promise_test(t => {
     68    const pc = new RTCPeerConnection();
     69    t.add_cleanup(() => pc.close());
     70    const transceiver = pc.addTransceiver('audio');
     71    assert_equals(transceiver.mid, null);
     72 
     73    return pc.createOffer()
     74    .then(offer => {
     75      assert_equals(transceiver.mid, null,
     76        'Expect transceiver.mid to still be null after createOffer');
     77 
     78      return pc.setLocalDescription(offer)
     79      .then(() => {
     80        assert_equals(typeof transceiver.mid, 'string',
     81          'Expect transceiver.mid to set to valid string value');
     82 
     83        assert_equals(offer.sdp.includes(`\r\na=mid:${transceiver.mid}`), true,
     84          'Expect transceiver mid to be found in offer SDP');
     85      });
     86    });
     87  }, 'setLocalDescription(offer) with m= section should assign mid to corresponding transceiver');
     88 
     89  /*
     90    4.3.1.6.  Set the RTCSessionSessionDescription
     91      8.  If description is set as a remote description, then run the following steps
     92          for each media description in description:
     93        2.  If no suitable transceiver is found (transceiver is unset), run the following
     94            steps:
     95          1.  Create an RTCRtpSender, sender, from the media description.
     96          2.  Create an RTCRtpReceiver, receiver, from the media description.
     97          3.  Create an RTCRtpTransceiver with sender, receiver and direction, and let
     98              transceiver be the result.
     99        3.  Set transceiver's mid value to the mid of the corresponding media description.
    100   */
    101  promise_test(t => {
    102    const pc1 = new RTCPeerConnection();
    103    t.add_cleanup(() => pc1.close());
    104    const pc2 = new RTCPeerConnection();
    105 
    106    t.add_cleanup(() => pc2.close());
    107 
    108    const transceiver1 = pc1.addTransceiver('audio');
    109    assert_array_equals(pc1.getTransceivers(), [transceiver1]);
    110    assert_array_equals(pc2.getTransceivers(), []);
    111 
    112    return pc1.createOffer()
    113    .then(offer => {
    114      return Promise.all([
    115        pc1.setLocalDescription(offer),
    116        pc2.setRemoteDescription(offer)
    117      ])
    118      .then(() => {
    119        const transceivers = pc2.getTransceivers();
    120        assert_equals(transceivers.length, 1,
    121          'Expect new transceiver added to pc2 after setRemoteDescription');
    122 
    123        const [ transceiver2 ] = transceivers;
    124 
    125        assert_equals(typeof transceiver2.mid, 'string',
    126          'Expect transceiver2.mid to be set');
    127 
    128        assert_equals(transceiver1.mid, transceiver2.mid,
    129          'Expect transceivers of both side to have the same mid');
    130 
    131        assert_equals(offer.sdp.includes(`\r\na=mid:${transceiver2.mid}`), true,
    132          'Expect transceiver mid to be found in offer SDP');
    133      });
    134    });
    135  }, 'setRemoteDescription(offer) with m= section and no existing transceiver should create corresponding transceiver');
    136 
    137  /*
    138    4.3.1.6.  Set the RTCSessionSessionDescription
    139      9.  If description is of type "rollback", then run the following steps:
    140        1.  If the mid value of an RTCRtpTransceiver was set to a non-null value by
    141            the RTCSessionDescription that is being rolled back, set the mid value
    142            of that transceiver to null, as described by [JSEP] (section 4.1.8.2.).
    143   */
    144  promise_test(t => {
    145    const pc = new RTCPeerConnection();
    146    t.add_cleanup(() => pc.close());
    147    const transceiver = pc.addTransceiver('audio');
    148    assert_equals(transceiver.mid, null);
    149 
    150    return pc.createOffer()
    151    .then(offer => {
    152      assert_equals(transceiver.mid, null);
    153      return pc.setLocalDescription(offer);
    154    })
    155    .then(() => {
    156      assert_not_equals(transceiver.mid, null);
    157      return pc.setLocalDescription({ type: 'rollback' });
    158    })
    159    .then(() => {
    160      assert_equals(transceiver.mid, null,
    161      'Expect transceiver.mid to become null again after rollback');
    162    });
    163  }, 'setLocalDescription(rollback) should unset transceiver.mid');
    164 
    165  promise_test(t => {
    166    const pc = new RTCPeerConnection();
    167    t.add_cleanup(() => pc.close());
    168    const transceiver1 = pc.addTransceiver('audio');
    169    assert_equals(transceiver1.mid, null);
    170 
    171    return pc.createOffer()
    172    .then(offer =>
    173       pc.setLocalDescription(offer)
    174       .then(() => generateAnswer(offer)))
    175    .then(answer => pc.setRemoteDescription(answer))
    176    .then(() => {
    177      // pc is back to stable state
    178      // create another transceiver
    179      const transceiver2 = pc.addTransceiver('video');
    180 
    181      assert_not_equals(transceiver1.mid, null);
    182      assert_equals(transceiver2.mid, null);
    183 
    184      return pc.createOffer()
    185      .then(offer => pc.setLocalDescription(offer))
    186      .then(() => {
    187        assert_not_equals(transceiver1.mid, null);
    188        assert_not_equals(transceiver2.mid, null,
    189          'Expect transceiver2.mid to become set');
    190 
    191        return pc.setLocalDescription({ type: 'rollback' });
    192      })
    193      .then(() => {
    194        assert_not_equals(transceiver1.mid, null,
    195          'Expect transceiver1.mid to stay set');
    196 
    197        assert_equals(transceiver2.mid, null,
    198          'Expect transceiver2.mid to be rolled back to null');
    199      });
    200    })
    201  }, 'setLocalDescription(rollback) should only unset transceiver mids associated with current round');
    202 
    203  /*
    204    4.3.1.6.  Set the RTCSessionSessionDescription
    205      9.  If description is of type "rollback", then run the following steps:
    206        2.  If an RTCRtpTransceiver was created by applying the RTCSessionDescription
    207            that is being rolled back, and a track has not been attached to it via
    208            addTrack, remove that transceiver from connection's set of transceivers,
    209            as described by [JSEP] (section 4.1.8.2.).
    210   */
    211  promise_test(t => {
    212    const pc1 = new RTCPeerConnection();
    213    t.add_cleanup(() => pc1.close());
    214    const pc2 = new RTCPeerConnection();
    215 
    216    t.add_cleanup(() => pc2.close());
    217 
    218    pc1.addTransceiver('audio');
    219 
    220    return pc1.createOffer()
    221    .then(offer => pc2.setRemoteDescription(offer))
    222    .then(() => {
    223      const transceivers = pc2.getTransceivers();
    224      assert_equals(transceivers.length, 1);
    225      const [ transceiver ] = transceivers;
    226 
    227      assert_equals(typeof transceiver.mid, 'string',
    228        'Expect transceiver.mid to be set');
    229 
    230      return pc2.setRemoteDescription({ type: 'rollback' })
    231      .then(() => {
    232        assert_equals(transceiver.mid, null,
    233          'Expect transceiver.mid to be unset');
    234 
    235        assert_array_equals(pc2.getTransceivers(), [],
    236          `Expect transceiver to be removed from pc2's transceiver list`);
    237      });
    238    });
    239  }, 'setRemoteDescription(rollback) should remove newly created transceiver from transceiver list');
    240 
    241  promise_test(async t => {
    242    const pc1 = new RTCPeerConnection();
    243    t.add_cleanup(() => pc1.close());
    244    const pc2 = new RTCPeerConnection();
    245    t.add_cleanup(() => pc2.close());
    246 
    247    pc1.addTransceiver('audio');
    248    const offer = await pc1.createOffer();
    249    await pc1.setLocalDescription(offer);
    250 
    251    await pc2.setRemoteDescription(offer);
    252    pc2.getTransceivers()[0].stop();
    253    const answer = await pc2.createAnswer();
    254 
    255    await pc1.setRemoteDescription(answer);
    256 
    257    assert_equals(pc1.getTransceivers()[0].currentDirection, 'inactive', 'A stopped m-line should give an inactive transceiver');
    258  }, 'setRemoteDescription should set transceiver inactive if its corresponding m section is rejected');
    259 
    260  /*
    261    TODO
    262      - Steps for transceiver direction is added to tip of tree draft, but not yet
    263        published as editor's draft
    264 
    265    4.3.1.6.  Set the RTCSessionSessionDescription
    266      8.  If description is set as a remote description, then run the following steps
    267          for each media description in description:
    268        1.  As described by [JSEP] (section 5.9.), attempt to find an existing
    269            RTCRtpTransceiver object, transceiver, to represent the media description.
    270        3.  If the media description has no MID, and transceiver's mid is unset, generate
    271            a random value as described in [JSEP] (section 5.9.).
    272        4.  If the direction of the media description is sendrecv or sendonly, and
    273            transceiver.receiver.track has not yet been fired in a track event, process
    274            the remote track for the media description, given transceiver.
    275        5.  If the media description is rejected, and transceiver is not already stopped,
    276            stop the RTCRtpTransceiver transceiver.
    277 
    278    [JSEP]
    279    5.9.  Applying a Remote Description
    280      - If the m= section is not associated with any RtpTransceiver
    281        (possibly because it was dissociated in the previous step),
    282        either find an RtpTransceiver or create one according to the
    283        following steps:
    284 
    285        - If the m= section is sendrecv or recvonly, and there are
    286          RtpTransceivers of the same type that were added to the
    287          PeerConnection by addTrack and are not associated with any
    288          m= section and are not stopped, find the first (according to
    289          the canonical order described in Section 5.2.1) such
    290          RtpTransceiver.
    291 
    292        - If no RtpTransceiver was found in the previous step, create
    293          one with a recvonly direction.
    294   */
    295 </script>