<!doctype html>
<title>MediaStreamTrack GetSettings</title>
<p class="instructions">When prompted, accept to share your video stream.</p>
<meta name=timeout content=long>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
  'use strict'

  // https://w3c.github.io/mediacapture-main/archives/20170605/getusermedia.html

  promise_test(t => {
    const constraints = {
      video: true,
      audio: false
    };

    return navigator.mediaDevices.getUserMedia(constraints)
    .then(mediaStream => {
      const settings1 = mediaStream.getVideoTracks()[0].getSettings();
      const videoConstraints = {
        deviceId: settings1.deviceId
      };

      return navigator.mediaDevices.getUserMedia({
        video: videoConstraints,
        audio: false
      }).then(mediaStream => {
        const settings2 = mediaStream.getVideoTracks()[0].getSettings();
        assert_equals(settings1.deviceId, settings2.deviceId);
      });
    });
  }, 'A device can be opened twice and have the same device ID');

  promise_test(t => {
    const constraints = {
      video: true,
      audio: false
    };

    return navigator.mediaDevices.getUserMedia(constraints)
    .then(mediaStream => {
      const settings1 = mediaStream.getVideoTracks()[0].getSettings();
      const videoConstraints = {
        deviceId: settings1.deviceId,
        width: {
          exact: settings1.width / 2
        }
      };

      return navigator.mediaDevices.getUserMedia({
        video: videoConstraints,
        audio: false
      }).then(mediaStream => {
        const settings2 = mediaStream.getVideoTracks()[0].getSettings();
        assert_equals(settings1.deviceId, settings2.deviceId);
        assert_equals(settings1.width / 2, settings2.width);
      });
    });
  }, 'A device can be opened twice with different resolutions');

  promise_test(t => {
    return navigator.mediaDevices.enumerateDevices().then(async devices => {
      for (var device of devices) {
        if (device.kind == "audiooutput")
          continue;
        var device_id_constraint = {deviceId: {exact: device.deviceId}};
        var constraints = device.kind == "audioinput"
          ? {audio: device_id_constraint}
          : {video: device_id_constraint};

        var stream = await navigator.mediaDevices.getUserMedia(constraints);
        assert_equals(stream.getTracks()[0].getSettings().groupId,
                      device.groupId);
        assert_greater_than(device.groupId.length, 0);
      }
    });
  }, 'groupId is correctly reported by getSettings() for all devices');

  async function createAudioStreamAndGetSettings(t) {
    const stream = await navigator.mediaDevices.getUserMedia({audio: true});
    t.add_cleanup(() => stream.getAudioTracks()[0].stop());
    return stream.getAudioTracks()[0].getSettings();
  }

  promise_test(async t => {
    const settings = await createAudioStreamAndGetSettings(t);
    assert_equals(typeof(settings.deviceId), "string",
                  "deviceId should exist and it should be a string.");
  }, 'deviceId is reported by getSettings() for getUserMedia() audio tracks');

  promise_test(async t => {
    const settings = await createAudioStreamAndGetSettings(t);
    assert_equals(typeof(settings.groupId), "string",
                  "groupId should exist and it should be a string.");
  }, 'groupId is reported by getSettings() for getUserMedia() audio tracks');

  promise_test(async t => {
    const settings = await createAudioStreamAndGetSettings(t);
    assert_equals(typeof(settings.sampleRate), "number",
                  "sampleRate should exist and it should be a number.");
    assert_greater_than(settings.sampleRate, 0);
  }, 'sampleRate is reported by getSettings() for getUserMedia() audio tracks');

  promise_test(async t => {
    const settings = await createAudioStreamAndGetSettings(t);
    assert_equals(typeof(settings.sampleSize), "number",
                  "sampleSize should exist and it should be a number.");
    assert_greater_than(settings.sampleSize, 0);
  }, 'sampleSize is reported by getSettings() for getUserMedia() audio tracks');

  promise_test(async t => {
    const settings = await createAudioStreamAndGetSettings(t);
    assert_equals(typeof(settings.echoCancellation), "boolean",
                  "echoCancellation should exist and it should be a boolean.");
  }, 'echoCancellation is reported by getSettings() for getUserMedia() audio tracks');

  promise_test(async t => {
    const settings = await createAudioStreamAndGetSettings(t);
    assert_equals(typeof(settings.autoGainControl), "boolean",
                  "autoGainControl should exist and it should be a boolean.");
  }, 'autoGainControl is reported by getSettings() for getUserMedia() audio tracks');

  promise_test(async t => {
    const settings = await createAudioStreamAndGetSettings(t);
    assert_equals(typeof(settings.noiseSuppression), "boolean",
                  "noiseSuppression should exist and it should be a boolean.");
  }, 'noiseSuppression is reported by getSettings() for getUserMedia() audio tracks');

  promise_test(async t => {
    const settings = await createAudioStreamAndGetSettings(t);
    assert_equals(typeof(settings.latency), "number",
                  "latency should exist and it should be a number.");
    assert_greater_than_equal(settings.latency,0);
  }, 'latency is reported by getSettings() for getUserMedia() audio tracks');

  promise_test(async t => {
    const settings = await createAudioStreamAndGetSettings(t);
    assert_equals(typeof(settings.channelCount), "number",
                  "channelCount should exist and it should be a number.");
    assert_greater_than(settings.channelCount, 0);
  }, 'channelCount is reported by getSettings() for getUserMedia() audio tracks');

  async function createVideoStreamAndGetSettings(t) {
    const stream = await navigator.mediaDevices.getUserMedia({video: true});
    t.add_cleanup(() => stream.getVideoTracks()[0].stop());
    return stream.getVideoTracks()[0].getSettings();
  }

  promise_test(async t => {
    const settings = await createVideoStreamAndGetSettings(t);
    assert_equals(typeof(settings.deviceId), "string",
                  "deviceId should exist and it should be a string.");
  }, 'deviceId is reported by getSettings() for getUserMedia() video tracks');

  promise_test(async t => {
    const settings = await createVideoStreamAndGetSettings(t);
    assert_equals(typeof(settings.groupId), "string",
                  "groupId should exist and it should be a string.");
  }, 'groupId is reported by getSettings() for getUserMedia() video tracks');

  promise_test(async t => {
    const settings = await createVideoStreamAndGetSettings(t);
    assert_equals(typeof(settings.width), "number",
                  "width should exist and it should be a number.");
    assert_true(Number.isInteger(settings.width), "width should be an integer.");
    assert_greater_than_equal(settings.width, 0);;
  }, 'width is reported by getSettings() for getUserMedia() video tracks');

  promise_test(async t => {
    const settings = await createVideoStreamAndGetSettings(t);
    assert_equals(typeof(settings.height), "number",
                  "height should exist and it should be a number.");
    assert_true(Number.isInteger(settings.height), "height should be an integer.");
    assert_greater_than_equal(settings.height, 0);
  }, 'height is reported by getSettings() for getUserMedia() video tracks');

  promise_test(async t => {
    const settings = await createVideoStreamAndGetSettings(t);
    assert_equals(typeof(settings.aspectRatio), "number",
                  "aspectRatio should exist and it should be a number.");
    assert_greater_than_equal(settings.aspectRatio, 0);
  }, 'aspectRatio is reported by getSettings() for getUserMedia() video tracks');

  promise_test(async t => {
    const settings = await createVideoStreamAndGetSettings(t);
    assert_equals(typeof(settings.frameRate), "number",
                  "frameRate should exist and it should be a number.");
    assert_greater_than_equal(settings.frameRate, 0);
  }, 'frameRate is reported by getSettings() for getUserMedia() video tracks');

  promise_test(async t => {
    const settings = await createVideoStreamAndGetSettings(t);
    // facingMode not treated as mandatory because not all platforms provide
    // this information.
    if (settings.facingMode) {
      assert_equals(typeof(settings.facingMode), "string",
                  "If facingMode is provided it should be a string.");
      assert_in_array(settings.facingMode,
                  ['user', 'environment', 'left', 'right']);
    }
  }, 'facingMode is reported by getSettings() for getUserMedia() video tracks');

  promise_test(async t => {
    const settings = await createVideoStreamAndGetSettings(t);
    assert_equals(typeof(settings.resizeMode), "string",
                "resizeMode should exist and it should be a string.");
    assert_in_array(settings.resizeMode, ['none', 'crop-and-scale']);
  }, 'resizeMode is reported by getSettings() for getUserMedia() video tracks');
</script>
