tor-browser

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

RTCTrackEvent-fire.html (5853B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <title>Change of msid in remote description should trigger related track events</title>
      4 <script src="/resources/testharness.js"></script>
      5 <script src="/resources/testharnessreport.js"></script>
      6 <script>
      7 const sdpBase =`v=0
      8 o=- 5511237691691746 2 IN IP4 127.0.0.1
      9 s=-
     10 t=0 0
     11 a=group:BUNDLE 0
     12 a=ice-options:trickle
     13 a=ice-lite
     14 a=msid-semantic:WMS *
     15 m=audio 9 UDP/TLS/RTP/SAVPF 111 103 9 102 0 8 105 13 110 113 126
     16 c=IN IP6 ::
     17 a=rtcp:9 IN IP6 ::
     18 a=rtcp-mux
     19 a=mid:0
     20 a=sendrecv
     21 a=ice-ufrag:z0i8R3C9C4hPRWls
     22 a=ice-pwd:O7bPpOFAqasqoidV4yxnFVbc
     23 a=ice-lite
     24 a=fingerprint:sha-256 B7:9C:0D:C9:D1:42:57:97:82:4D:F9:B7:93:75:49:C3:42:21:5A:DD:9C:B5:ED:53:53:F0:B4:C8:AE:88:7A:E7
     25 a=setup:actpass
     26 a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
     27 a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid
     28 a=rtpmap:0 PCMU/8000`;
     29 
     30 const sdp0 = sdpBase + `
     31 `;
     32 
     33 const sdp1 = sdpBase + `
     34 a=msid:1 2
     35 a=ssrc:3 cname:4
     36 a=ssrc:3 msid:1 2
     37 `;
     38 
     39 const sdp2 = sdpBase + `
     40 a=ssrc:3 cname:4
     41 a=ssrc:3 msid:1 2
     42 `;
     43 
     44 const sdp3 = sdpBase + `
     45 a=msid:1 2
     46 a=ssrc:3 cname:4
     47 a=ssrc:3 msid:3 2
     48 `;
     49 
     50 const sdp4 = sdp1.replace('msid-semantic', 'unknownattr');
     51 
     52 const sdp5 = sdpBase + `
     53 a=msid:-
     54 `;
     55 
     56 const sdp6 = sdpBase + `
     57 a=msid:1 2
     58 a=msid:1 2
     59 `;
     60 
     61 async function applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp)
     62 {
     63    const testTrackPromise = new Promise(resolve  => {
     64        pc.ontrack = (event) => { resolve([event.track, event.streams]); };
     65    });
     66    await pc.setRemoteDescription({type: 'offer', sdp: sdp});
     67    return testTrackPromise;
     68 }
     69 
     70 promise_test(async test => {
     71    const pc = new RTCPeerConnection();
     72    test.add_cleanup(() => pc.close());
     73 
     74    const [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp0);
     75    assert_equals(streams.length, 1, "track event has a stream");
     76 }, "When a=msid is absent, the track should still be associated with a stream");
     77 
     78 promise_test(async test => {
     79    const pc = new RTCPeerConnection();
     80    test.add_cleanup(() => pc.close());
     81 
     82    const [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp1);
     83    assert_equals(streams.length, 1, "track event has a stream");
     84    assert_equals(streams[0].id, "1", "msid should match");
     85 }, "Source-level msid should be ignored if media-level msid is present");
     86 
     87 promise_test(async test => {
     88    const pc = new RTCPeerConnection();
     89    test.add_cleanup(() => pc.close());
     90 
     91    const [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp2);
     92    assert_equals(streams.length, 1, "track event has a stream");
     93    assert_equals(streams[0].id, "1", "msid should match");
     94 }, "Source-level msid should be parsed if media-level msid is absent");
     95 
     96 promise_test(async test => {
     97    const pc = new RTCPeerConnection();
     98    test.add_cleanup(() => pc.close());
     99 
    100    let track;
    101    let streams;
    102    try {
    103      [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp3);
    104    } catch (e) {
    105      return;
    106    }
    107    assert_equals(streams.length, 1, "track event has a stream");
    108    assert_equals(streams[0].id, "1", "msid should match");
    109 }, "Source-level msid should be ignored, or an error should be thrown, if a different media-level msid is present");
    110 
    111 promise_test(async test => {
    112    const pc = new RTCPeerConnection();
    113    test.add_cleanup(() => pc.close());
    114 
    115    const [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp4);
    116    assert_equals(streams.length, 1, "track event has a stream");
    117    assert_equals(streams[0].id, "1", "msid should match");
    118 }, "stream ids should be found even if msid-semantic is absent");
    119 
    120 promise_test(async test => {
    121    const pc = new RTCPeerConnection();
    122    test.add_cleanup(() => pc.close());
    123 
    124    const [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp5);
    125    assert_equals(streams.length, 0, "track event has no stream");
    126 }, "a=msid:- should result in a track event with no streams");
    127 
    128 promise_test(async test => {
    129    const pc = new RTCPeerConnection();
    130    test.add_cleanup(() => pc.close());
    131 
    132    const [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp6);
    133    assert_equals(streams.length, 1, "track event has one stream");
    134 }, "Duplicate a=msid should result in a track event with one stream");
    135 
    136 promise_test(async test => {
    137    const pc = new RTCPeerConnection();
    138    test.add_cleanup(() => pc.close());
    139 
    140    const [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp1);
    141    assert_equals(streams.length, 1, "track event has a stream");
    142    assert_equals(streams[0].id, "1", "msid should match");
    143    const stream = streams[0];
    144 
    145    await pc.setLocalDescription(await pc.createAnswer());
    146 
    147    const testTrackPromise = new Promise((resolve) => { stream.onremovetrack = resolve; });
    148    await pc.setRemoteDescription({type: 'offer', 'sdp': sdp0});
    149    await testTrackPromise;
    150 
    151    assert_equals(stream.getAudioTracks().length, 0, "stream should be empty");
    152 }, "Applying a remote description with removed msid should trigger firing a removetrack event on the corresponding stream");
    153 
    154 promise_test(async test => {
    155    const pc = new RTCPeerConnection();
    156    test.add_cleanup(() => pc.close());
    157 
    158    let [track0, streams0] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp0);
    159 
    160    await pc.setLocalDescription(await pc.createAnswer());
    161 
    162    let [track1, streams1] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp1);
    163 
    164    assert_equals(streams1.length, 1, "track event has a stream");
    165    assert_equals(streams1[0].id, "1", "msid should match");
    166    assert_equals(streams1[0].getTracks()[0], track0, "track should match");
    167 }, "Applying a remote description with a new msid should trigger firing an event with populated streams");
    168 </script>