<html>
  <body>
    <script type="text/javascript">
      // Since promises run asynchronously, use the pages title to keep track
      // of the result.
      function setResultInTitle(title) {
        if (title == "" || title == "success" ||
            title == "Unsupported keySystem" ||
            title == "None of the requested configurations were supported.") {
          document.title = title;
        } else {
          console.log("Unexpected result: " + title);
          document.title = "unexpected result";
        }
      };

      // Compares 2 arrays of MediaKeySystemMediaCapability, comparing only
      // |contentType|. This assumes the order is the same. Returns "success"
      // if they match, an error message if they don't.
      function verifyCapabilitiesAreEqual(actual, expected) {
        if (actual.length != expected.length)
          return "mismatched lengths";
        for (var i = 0; i < actual.length; i++) {
          // Only compare |contentType|. Other properties are ignored.
          if (actual[i].contentType !== expected[i].contentType)
            return actual[i].contentType + " does not match " +
                   expected[i].contentType + " at index " + i;
        }
        return "success";
      }

      // Calls navigator.requestMediaKeySystemAccess() using the supplied codec
      // lists, and then verifies the result. Sets page title when done.
      function requestMediaKeySystemAccessAndVerifyConfiguration(
          keySystem, initDataType, audioCodecList, videoCodecList) {
        var configuration = {
            initDataTypes: [initDataType],
            audioCapabilities: [],
            videoCapabilities: []
        };
        if (audioCodecList !== null) {
          for (entry of audioCodecList) {
            configuration.audioCapabilities.push({contentType: entry});
          };
        }
        if (videoCodecList !== null) {
          for (entry of videoCodecList) {
            configuration.videoCapabilities.push({contentType: entry});
          };
        }
        // This is using promises which will run asynchronously.
        navigator.requestMediaKeySystemAccess(keySystem, [configuration])
            .then(function(response) {
              var allowedConfig = response.getConfiguration();
              if (allowedConfig.initDataTypes.length !== 1) {
                setResultInTitle("initDataType length mismatch");
                return;
              }
              if (allowedConfig.initDataTypes[0] !== initDataType) {
                setResultInTitle("initDataType returned " +
                                 allowedConfig.initDataTypes[0] +
                                 ", expected " + initDataType);
                return;
              }
              if (audioCodecList !== null) {
                var result =
                    verifyCapabilitiesAreEqual(allowedConfig.audioCapabilities,
                                            configuration.audioCapabilities);
                if (result !== "success") {
                  setResultInTitle(result);
                  return;
                }
              } else if (allowedConfig.audioCapabilities.length > 0) {
                setResultInTitle("audioCapabilities set when none expected");
                return;
              }
              if (videoCodecList !== null) {
                setResultInTitle(
                    verifyCapabilitiesAreEqual(allowedConfig.videoCapabilities,
                                            configuration.videoCapabilities));
                return;
              } else if (allowedConfig.videoCapabilities.length > 0) {
                setResultInTitle("videoCapabilities set when none expected");
                return;
              }
              setResultInTitle("success");
            })
            .catch(function(err) { setResultInTitle(err.message); });
      };

      function checkKeySystemWithMediaMimeType(keySystem, initDataType,
                                               audioCodecList, videoCodecList) {
        setResultInTitle("");
        requestMediaKeySystemAccessAndVerifyConfiguration(
            keySystem, initDataType, audioCodecList, videoCodecList);
      };
    </script>
  </body>
</html>
