tor-browser

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

hardware-capability-stats.https.html (3976B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <title>Stats exposing hardware capability</title>
      4 <meta name="timeout" content="long">
      5 <script src="/resources/testharness.js"></script>
      6 <script src="/resources/testharnessreport.js"></script>
      7 <script src="/resources/testdriver.js"></script>
      8 <script src="/resources/testdriver-vendor.js"></script>
      9 <script src="../webrtc/RTCPeerConnection-helper.js"></script>
     10 <script>
     11 /*
     12 * Test stats that expose hardware capabilities are only exposed according to
     13 * the conditions described in https://w3c.github.io/webrtc-stats/#limiting-exposure-of-hardware-capabilities.
     14 */
     15 'use strict';
     16 
     17 function getStatEntry(report, type, kind, assertStatsExists = true) {
     18  const values = [...report.values()];
     19  const for_kind = values.filter(
     20    stat => stat.type == type && stat.kind == kind);
     21 
     22  if (assertStatsExists) {
     23    assert_equals(1, for_kind.length,
     24                  "Expected report to have only 1 entry with type '" + type +
     25                  "' and kind '" + kind + "'. Found values " + for_kind);
     26  }
     27  return for_kind.length > 0 ? for_kind[0] : null;
     28 }
     29 
     30 async function hasEncodedAndDecodedFrames(pc, t) {
     31  while (true) {
     32    const report = await pc.getStats();
     33    const inboundRtp = getStatEntry(report, 'inbound-rtp', 'video', false);
     34    const outboundRtp = getStatEntry(report, 'outbound-rtp', 'video', false);
     35    if (inboundRtp?.framesDecoded > 0 && outboundRtp?.framesEncoded > 0) {
     36      return;
     37    }
     38    // Avoid any stats caching, which can otherwise make this an infinite loop.
     39    await (new Promise(r => t.step_timeout(r, 100)));
     40  }
     41 }
     42 
     43 async function setupPcAndGetStatEntry(
     44  t, stream, type, kind, stat) {
     45  const pc1 = new RTCPeerConnection();
     46  t.add_cleanup(() => pc1.close());
     47  const pc2 = new RTCPeerConnection();
     48  t.add_cleanup(() => pc2.close());
     49  for (const track of stream.getTracks()) {
     50    pc1.addTrack(track, stream);
     51    pc2.addTrack(track, stream);
     52    t.add_cleanup(() => track.stop());
     53  }
     54 
     55  exchangeIceCandidates(pc1, pc2);
     56  await exchangeOfferAnswer(pc1, pc2);
     57  await hasEncodedAndDecodedFrames(pc1, t);
     58  const report = await pc1.getStats();
     59  return getStatEntry(report, type, kind);
     60 }
     61 
     62 for (const args of [
     63  // RTCOutboundRtpStreamStats.powerEfficientEncoder
     64  ['outbound-rtp', 'video', 'powerEfficientEncoder'],
     65  // RTCOutboundRtpStreamStats.encoderImplementation
     66  ['outbound-rtp', 'video', 'encoderImplementation'],
     67  // RTCInboundRtpStreamStats.powerEfficientDecoder
     68  ['inbound-rtp', 'video', 'powerEfficientDecoder'],
     69  // RTCOutboundRtpStreamStats.decoderImplementation
     70  ['inbound-rtp', 'video', 'decoderImplementation'],
     71 ]) {
     72  const type = args[0];
     73  const kind = args[1];
     74  const stat = args[2];
     75 
     76  promise_test(async (t) => {
     77    const stream = await getNoiseStream({video: true, audio: true});
     78    const statsEntry = await setupPcAndGetStatEntry(t, stream, type, kind, stat);
     79    assert_not_own_property(statsEntry, stat);
     80  }, stat + " not exposed when not capturing.");
     81 
     82  // Exposing hardware capabilities when a there is a fullscreen element was
     83  // removed with https://github.com/w3c/webrtc-stats/pull/713.
     84  promise_test(async (t) => {
     85    const stream = await getNoiseStream({video: true, audio: true});
     86 
     87    const element = document.getElementById('elementToFullscreen');
     88    await test_driver.bless("fullscreen", () => element.requestFullscreen());
     89    t.add_cleanup(() => document.exitFullscreen());
     90 
     91    const statsEntry = await setupPcAndGetStatEntry(
     92      t, stream, type, kind, stat);
     93    assert_not_own_property(statsEntry, stat);
     94  }, stat + " not exposed when fullscreen and not capturing.");
     95 
     96  promise_test(async (t) => {
     97    const stream = await navigator.mediaDevices.getUserMedia(
     98      {video: true, audio: true});
     99    const statsEntry = await setupPcAndGetStatEntry(
    100      t, stream, type, kind, stat);
    101    assert_own_property(statsEntry, stat);
    102  }, stat + " exposed when capturing.");
    103 }
    104 
    105 </script>
    106 <body>
    107  <div id="elementToFullscreen"></div>
    108 </body>