tor-browser

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

RTCRtpParameters-helper.js (8032B)


      1 'use strict';
      2 
      3 // Test is based on the following editor draft:
      4 // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
      5 
      6 // Helper function for testing RTCRtpParameters dictionary fields
      7 
      8 // This file depends on dictionary-helper.js which should
      9 // be loaded from the main HTML file.
     10 
     11 // An offer/answer exchange is necessary for getParameters() to have any
     12 // negotiated parameters to return.
     13 async function doOfferAnswerExchange(t, caller) {
     14  const callee = new RTCPeerConnection();
     15  t.add_cleanup(() => callee.close());
     16  const offer = await caller.createOffer();
     17  await caller.setLocalDescription(offer);
     18  await callee.setRemoteDescription(offer);
     19  const answer = await callee.createAnswer();
     20  await callee.setLocalDescription(answer);
     21  await caller.setRemoteDescription(answer);
     22 
     23  return callee;
     24 }
     25 
     26 /*
     27  Validates the RTCRtpParameters returned from RTCRtpSender.prototype.getParameters
     28 
     29  5.2.  RTCRtpSender Interface
     30    getParameters
     31      - transactionId is set to a new unique identifier, used to match this getParameters
     32        call to a setParameters call that may occur later.
     33 
     34      - encodings is set to the value of the [[SendEncodings]] internal slot.
     35 
     36      - The headerExtensions sequence is populated based on the header extensions that
     37        have been negotiated for sending.
     38 
     39      - The codecs sequence is populated based on the codecs that have been negotiated
     40        for sending, and which the user agent is currently capable of sending. If
     41        setParameters has removed or reordered codecs, getParameters MUST return the
     42        shortened/reordered list. However, every time codecs are renegotiated by a
     43        new offer/answer exchange, the list of codecs MUST be restored to the full
     44        negotiated set, in the priority order indicated by the remote description,
     45        in effect discarding the effects of setParameters.
     46 
     47      - rtcp.cname is set to the CNAME of the associated RTCPeerConnection. rtcp.reducedSize
     48        is set to true if reduced-size RTCP has been negotiated for sending, and false otherwise.
     49 */
     50 function validateSenderRtpParameters(param) {
     51  validateRtpParameters(param);
     52 
     53  assert_array_field(param, 'encodings');
     54  for(const encoding of param.encodings) {
     55    validateEncodingParameters(encoding);
     56  }
     57 
     58  assert_not_equals(param.transactionId, undefined,
     59    'Expect sender param.transactionId to be set');
     60 
     61  assert_not_equals(param.rtcp.cname, undefined,
     62    'Expect sender param.rtcp.cname to be set');
     63 
     64  assert_not_equals(param.rtcp.reducedSize, undefined,
     65    'Expect sender param.rtcp.reducedSize to be set to either true or false');
     66 }
     67 
     68 /*
     69  Validates the RTCRtpParameters returned from RTCRtpReceiver.prototype.getParameters
     70 
     71  5.3.  RTCRtpReceiver Interface
     72    getParameters
     73      When getParameters is called, the RTCRtpParameters dictionary is constructed
     74      as follows:
     75 
     76      - The headerExtensions sequence is populated based on the header extensions that
     77        the receiver is currently prepared to receive.
     78 
     79      - The codecs sequence is populated based on the codecs that the receiver is currently
     80        prepared to receive.
     81 
     82      - rtcp.reducedSize is set to true if the receiver is currently prepared to receive
     83        reduced-size RTCP packets, and false otherwise. rtcp.cname is left undefined.
     84 
     85      - transactionId is left undefined.
     86 */
     87 function validateReceiverRtpParameters(param) {
     88  validateRtpParameters(param);
     89 
     90  assert_equals(param.transactionId, undefined,
     91    'Expect receiver param.transactionId to be unset');
     92 
     93  assert_not_equals(param.rtcp.reducedSize, undefined,
     94    'Expect receiver param.rtcp.reducedSize to be set');
     95 
     96  assert_equals(param.rtcp.cname, undefined,
     97    'Expect receiver param.rtcp.cname to be unset');
     98 }
     99 
    100 /*
    101  dictionary RTCRtpParameters {
    102    DOMString                                 transactionId;
    103    sequence<RTCRtpEncodingParameters>        encodings;
    104    sequence<RTCRtpHeaderExtensionParameters> headerExtensions;
    105    RTCRtcpParameters                         rtcp;
    106    sequence<RTCRtpCodecParameters>           codecs;
    107  };
    108 
    109 */
    110 function validateRtpParameters(param) {
    111  assert_optional_string_field(param, 'transactionId');
    112 
    113  assert_array_field(param, 'headerExtensions');
    114  for(const headerExt of param.headerExtensions) {
    115    validateHeaderExtensionParameters(headerExt);
    116  }
    117 
    118  assert_dict_field(param, 'rtcp');
    119  validateRtcpParameters(param.rtcp);
    120 
    121  assert_array_field(param, 'codecs');
    122  for(const codec of param.codecs) {
    123    validateCodecParameters(codec);
    124  }
    125 }
    126 
    127 /*
    128  dictionary RTCRtpEncodingParameters {
    129    boolean             active;
    130    unsigned long       maxBitrate;
    131 
    132    [readonly]
    133    DOMString           rid;
    134 
    135    double              scaleResolutionDownBy;
    136  };
    137 
    138 */
    139 function validateEncodingParameters(encoding) {
    140  assert_optional_boolean_field(encoding, 'active');
    141  assert_optional_unsigned_int_field(encoding, 'maxBitrate');
    142 
    143  assert_optional_string_field(encoding, 'rid');
    144  assert_optional_number_field(encoding, 'scaleResolutionDownBy');
    145 }
    146 
    147 /*
    148  dictionary RTCRtcpParameters {
    149    [readonly]
    150    DOMString cname;
    151 
    152    [readonly]
    153    boolean   reducedSize;
    154  };
    155 */
    156 function validateRtcpParameters(rtcp) {
    157  assert_optional_string_field(rtcp, 'cname');
    158  assert_optional_boolean_field(rtcp, 'reducedSize');
    159 }
    160 
    161 /*
    162  dictionary RTCRtpHeaderExtensionParameters {
    163    [readonly]
    164    DOMString      uri;
    165 
    166    [readonly]
    167    unsigned short id;
    168 
    169    [readonly]
    170    boolean        encrypted;
    171  };
    172 */
    173 function validateHeaderExtensionParameters(headerExt) {
    174  assert_optional_string_field(headerExt, 'uri');
    175  assert_optional_unsigned_int_field(headerExt, 'id');
    176  assert_optional_boolean_field(headerExt, 'encrypted');
    177 }
    178 
    179 /*
    180  dictionary RTCRtpCodecParameters {
    181    [readonly]
    182    required unsigned short payloadType;
    183 
    184    [readonly]
    185    required DOMString      mimeType;
    186 
    187    [readonly]
    188    required unsigned long  clockRate;
    189 
    190    [readonly]
    191    unsigned short channels;
    192 
    193    [readonly]
    194    DOMString      sdpFmtpLine;
    195  };
    196 */
    197 function validateCodecParameters(codec) {
    198  assert_unsigned_int_field(codec, 'payloadType');
    199  assert_string_field(codec, 'mimeType');
    200  assert_unsigned_int_field(codec, 'clockRate');
    201  assert_optional_unsigned_int_field(codec, 'channels');
    202  assert_optional_string_field(codec, 'sdpFmtpLine');
    203 }
    204 
    205 // Helper function to test that modifying an encoding field should succeed
    206 function test_modified_encoding(kind, field, value1, value2, desc) {
    207  promise_test(async t => {
    208    const pc = new RTCPeerConnection();
    209    t.add_cleanup(() => pc.close());
    210    const {
    211      sender
    212    } = pc.addTransceiver(kind, {
    213      sendEncodings: [{
    214        [field]: value1
    215      }]
    216    });
    217    await doOfferAnswerExchange(t, pc);
    218 
    219    const param1 = sender.getParameters();
    220    validateSenderRtpParameters(param1);
    221    const encoding1 = param1.encodings[0];
    222 
    223    assert_equals(encoding1[field], value1);
    224    encoding1[field] = value2;
    225 
    226    await sender.setParameters(param1);
    227    const param2 = sender.getParameters();
    228    validateSenderRtpParameters(param2);
    229    const encoding2 = param2.encodings[0];
    230    assert_equals(encoding2[field], value2);
    231  }, desc + ' with RTCRtpTransceiverInit');
    232 
    233  promise_test(async t => {
    234    const pc = new RTCPeerConnection();
    235    t.add_cleanup(() => pc.close());
    236    const {
    237      sender
    238    } = pc.addTransceiver(kind);
    239    await doOfferAnswerExchange(t, pc);
    240 
    241    const initParam = sender.getParameters();
    242    validateSenderRtpParameters(initParam);
    243    initParam.encodings[0][field] = value1;
    244    await sender.setParameters(initParam);
    245 
    246    const param1 = sender.getParameters();
    247    validateSenderRtpParameters(param1);
    248    const encoding1 = param1.encodings[0];
    249 
    250    assert_equals(encoding1[field], value1);
    251    encoding1[field] = value2;
    252 
    253    await sender.setParameters(param1);
    254    const param2 = sender.getParameters();
    255    validateSenderRtpParameters(param2);
    256    const encoding2 = param2.encodings[0];
    257    assert_equals(encoding2[field], value2);
    258  }, desc + ' without RTCRtpTransceiverInit');
    259 }