<!DOCTYPE html>
<title>Test running different types of CDM in the system</title>
<div id="console"></div>
<script src='eme_player_js/app_loader.js' type='text/javascript'></script>
<script type='text/javascript'>

  function log(message) {
    let consoleElement = document.getElementById('console');
    let entry = document.createElement('div');
    entry.appendChild(document.createTextNode(message));
    consoleElement.appendChild(entry);
    console.log(message);
  }

  const EXTERNAL_CLEARKEY_DIFFERENTGUID
      = 'org.chromium.externalclearkey.differentguid';
  const crashKeyId = 'crash';
  const normalJwkSet = Utils.createJWKData(KEY_ID, KEY);
  const crashJwkSet = Utils.createJWKData(crashKeyId, KEY);

  var config = {
    initDataTypes : [ 'keyids' ],
    videoCapabilities: [{contentType: 'video/webm; codecs="vp8"'}],
    persistentState: 'optional',
    sessionTypes: ['temporary'],
  };

  function createMediaKeySession(key_system) {
    var mediaKeySession;
    return navigator.requestMediaKeySystemAccess(key_system, [config])
        .then(function(access) {
      initDataType = access.getConfiguration().initDataTypes[0];
      initData = Utils.createKeyIdsInitializationData(KEY_ID)
      return access.createMediaKeys();
    }).then(function(result) {
      log('CDM created');
      var mediaKeys = result;
      mediaKeySession = mediaKeys.createSession();
      return mediaKeySession.generateRequest(initDataType, initData);
    }).then(function() {
      mediaKeySession.update(normalJwkSet);
    }).then(function() {
      return mediaKeySession;
    });
  }

  log('Start test');

  // Using EXTERNAL_CLEARKEY
  var session1;

  // Both using EXTERNAL_CLEARKEY_DIFFERENTGUID
  var session2;
  var session3;

  // The following creates 3 MediaKeys instances each with a MediaKeySession.
  // MediaKeys using different CDM GUID will run in different processes.
  // |session1| uses EXTERNAL_CLEARKEY that is registered with the default GUID
  // for Clear Key CDM. |session2/3| use EXTERNAL_CLEARKEY_DIFFERENTGUID that is
  // registered with a different GUID. So |session1| will run in process1, and
  // |session2/3| will run in process2.
  //
  // Then we send a special response |crashJwkSet| to session2 which will cause
  // the process2 to crash. This will close both |session2/3| as they run in the
  // same process. |session1| should not be affected. Then we try to create
  // another MediaKeySession using EXTERNAL_CLEARKEY_DIFFERENTGUID, and the
  // creation should work as a new process should be started.

  createMediaKeySession(EXTERNAL_CLEARKEY).then(function(session) {
    log('Session1 created');
    session1 = session;
    return createMediaKeySession(EXTERNAL_CLEARKEY_DIFFERENTGUID);
  }).then(function(session) {
    log('Session2 created');
    session2 = session;
    return createMediaKeySession(EXTERNAL_CLEARKEY_DIFFERENTGUID);
  }).then(function(session) {
    log('Session3 created');
    session3 = session;
    log('Crash session2');
    return session.update(crashJwkSet);
  }).finally(function() {
    // Due to the crash, the update() above could resolve or reject.
    // So use "finally" so that we continue the test regardless.
    log('Session2 crashed');
    return session2.closed;
  }).then(function() {
    log('Session2 closed');
    return session3.closed;
  }).then(function() {
    log('Session3 also closed');
    return session1.update(normalJwkSet);
  }).then(function() {
    log('Session1 still works');
    return createMediaKeySession(EXTERNAL_CLEARKEY_DIFFERENTGUID);
  }).then(function(session) {
    log('Can still create a session after crash');
    Utils.setResultInTitle('ENDED');
  }).catch(function(error) {
    log('Error: ' + error);
    Utils.failTest('Test failed: ' + error);
  });

</script>
</html>
