<!doctype html>
<meta charset=utf-8>
<title>Stats exposing hardware capability</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="../webrtc/RTCPeerConnection-helper.js"></script>
<script src="../webrtc/RTCStats-helper.js"></script>
<script>
/*
 * Test stats that expose hardware capabilities are only exposed according to
 * the conditions described in https://w3c.github.io/webrtc-stats/#limiting-exposure-of-hardware-capabilities.
 */
'use strict';

function getStatEntry(report, type, kind) {
  const values = [...report.values()];
  const for_kind = values.filter(
    stat => stat.type == type && stat.kind == kind);

  assert_equals(1, for_kind.length,
                "Expected report to have only 1 entry with type '" + type +
                "' and kind '" + kind + "'. Found values " + for_kind);
  return for_kind[0];
}

async function hasEncodedAndDecodedFrames(pc, t) {
  while (true) {
    const report = await pc.getStats();
    const inboundRtp = getStatEntry(report, 'inbound-rtp', 'video');
    const outboundRtp = getStatEntry(report, 'outbound-rtp', 'video');
    if (inboundRtp.framesDecoded > 0 && outboundRtp.framesEncoded > 0) {
      return;
    }
    // Avoid any stats caching, which can otherwise make this an infinite loop.
    await (new Promise(r => t.step_timeout(r, 100)));
  }
}

async function setupPcAndGetStatEntry(
  t, stream, type, kind, stat) {
  const pc1 = new RTCPeerConnection();
  t.add_cleanup(() => pc1.close());
  const pc2 = new RTCPeerConnection();
  t.add_cleanup(() => pc2.close());
  for (const track of stream.getTracks()) {
    pc1.addTrack(track, stream);
    pc2.addTrack(track, stream);
    t.add_cleanup(() => track.stop());
  }

  exchangeIceCandidates(pc1, pc2);
  await exchangeOfferAnswer(pc1, pc2);
  await hasEncodedAndDecodedFrames(pc1, t);
  const report = await pc1.getStats();
  return getStatEntry(report, type, kind);
}

for (const args of [
  // RTCOutboundRtpStreamStats.powerEfficientEncoder
  ['outbound-rtp', 'video', 'powerEfficientEncoder'],
  // RTCOutboundRtpStreamStats.encoderImplementation
  ['outbound-rtp', 'video', 'encoderImplementation'],
  // RTCInboundRtpStreamStats.powerEfficientDecoder
  ['inbound-rtp', 'video', 'powerEfficientDecoder'],
  // RTCOutboundRtpStreamStats.decoderImplementation
  ['inbound-rtp', 'video', 'decoderImplementation'],
]) {
  const type = args[0];
  const kind = args[1];
  const stat = args[2];

  promise_test(async (t) => {
    const stream = await getNoiseStream({video: true, audio: true});
    const statsEntry = await setupPcAndGetStatEntry(t, stream, type, kind, stat);
    assert_not_own_property(statsEntry, stat);
  }, stat + " not exposed when not capturing.");

  // Exposing hardware capabilities when a there is a fullscreen element was
  // removed with https://github.com/w3c/webrtc-stats/pull/713.
  promise_test(async (t) => {
    const stream = await getNoiseStream({video: true, audio: true});

    const element = document.getElementById('elementToFullscreen');
    await test_driver.bless("fullscreen", () => element.requestFullscreen());
    t.add_cleanup(() => document.exitFullscreen());

    const statsEntry = await setupPcAndGetStatEntry(
      t, stream, type, kind, stat);
    assert_not_own_property(statsEntry, stat);
  }, stat + " not exposed when fullscreen and not capturing.");

  promise_test(async (t) => {
    const stream = await navigator.mediaDevices.getUserMedia(
      {video: true, audio: true});
    const statsEntry = await setupPcAndGetStatEntry(
      t, stream, type, kind, stat);
    assert_own_property(statsEntry, stat);
  }, stat + " exposed when capturing.");
}

</script>
<body>
  <div id="elementToFullscreen"></div>
</body>
