<!DOCTYPE html>
<title>Test that load() succeeds on a session just closed</title>
<div id="logs"></div>
<script src='eme_player_js/app_loader.js' type='text/javascript'></script>
<script type='text/javascript'>
  // This test only uses |keySystem| and |licenseServerURL|.
  var testConfig = new TestConfig();
  testConfig.loadQueryParams();

  // Use the default KEY_ID and KEY as specified in eme_player_js/globals.js.
  const keyId = KEY_ID;
  const key = KEY;

  // This test only works with EXTERNAL_CLEARKEY. Persistent sessions are not
  // supported by CLEARKEY, and WIDEVINE doesn't support persistent sessions
  // on Linux which is the only system with a test license server.
  if (testConfig.keySystem != EXTERNAL_CLEARKEY) {
    Utils.timeLog('Unsupported key system ' + testConfig.keySystem);
  }

  // This test doesn't play any media, so no concern with specifying multiple
  // codecs. This is done to provide a set of codecs that should cover all
  // user agents. However, the CDM must support persistent licenses.
  const config = [{
    initDataTypes: ['webm'],
    audioCapabilities: [
      {contentType: 'audio/mp4; codecs="mp4a.40.2"'},
      {contentType: 'audio/webm; codecs="opus"'},
    ],
    persistentState: 'optional',
    sessionTypes: ['persistent-license'],
  }];

  var mediaKeys;
  var mediaKeySession;
  var mediaKeySessionId;
  navigator.requestMediaKeySystemAccess(testConfig.keySystem, config)
      .then(function(access) {
        return access.createMediaKeys();
      })
      .then(function(result) {
        Utils.timeLog('Creating session');
        mediaKeys = result;
        mediaKeySession = mediaKeys.createSession('persistent-license');

        // As this is using 'webm' initDataType, the data to generateRequest()
        // is simply the key ID.
        Utils.timeLog('Calling generateRequest()');
        return mediaKeySession.generateRequest(
            'webm', Utils.convertToUint8Array(keyId));
      })
      .then(function() {
        // Save the session ID so it can be loaded later.
        mediaKeySessionId = mediaKeySession.sessionId;

        // After update() is called, a 'keystatuseschange' event will occur.
        // Wait for it before checking the key statuses. Registering the event
        // handler now to ensure that the event gets caught. There is no need
        // to do anything in the event handler as the key statuses are on
        // |mediaKeySession|, and they can be checked after the promise is
        // resolved.
        const waitForKeyStatusChangePromise =
            Utils.waitForEvent(mediaKeySession, 'keystatuseschange');

        Utils.timeLog('Calling update()');
        const jwkSet = Utils.createJWKData(keyId, key);
        return Promise.all([
            mediaKeySession.update(jwkSet),
            waitForKeyStatusChangePromise
        ]);
      })
      .then(function() {
        // Session should have 1 usable key.
        Utils.timeLog('Checking for usable keyStatuses');
        Utils.verifyKeyStatuses(
            mediaKeySession.keyStatuses, [{keyId: keyId, status: 'usable'}]);

        // After close() is called, another 'keystatuseschange' event should
        // occur. Wait for it as well as the result for close().
        const waitForKeyStatusChangePromise =
            Utils.waitForEvent(mediaKeySession, 'keystatuseschange');

        // Now call close() and wait for the session to be closed along with
        // another 'keystatuseschange' event.
        Utils.timeLog('Calling close()');
        return Promise.all([
            mediaKeySession.close(),
            mediaKeySession.closed,
            waitForKeyStatusChangePromise
        ]);
      })
      .then(function() {
        // After close() there should be no keys.
        Utils.timeLog('Checking for empty keyStatuses');
        Utils.verifyKeyStatuses(mediaKeySession.keyStatuses, []);

        // Create a new session object.
        Utils.timeLog('Creating new session');
        mediaKeySession = mediaKeys.createSession('persistent-license');

        // After load() is called, a 'keystatuseschange' event should occur
        // for this new session. Wait for it as well as the result for load().
        const waitForKeyStatusChangePromise =
            Utils.waitForEvent(mediaKeySession, 'keystatuseschange');

        // Try to load the previous session.
        Utils.timeLog('Calling load()');
        return Promise.all([
            mediaKeySession.load(mediaKeySessionId),
            waitForKeyStatusChangePromise
        ]);
      })
      .then(function() {
        // Loaded session should still have the same usable key.
        Utils.timeLog('Checking for usable keyStatuses');
        Utils.verifyKeyStatuses(
            mediaKeySession.keyStatuses, [{keyId: keyId, status: 'usable'}]);

        // After close() is called on the loaded session, another
        // 'keystatuseschange' event should occur. Wait for it
        // as well as the result for close().
        const waitForKeyStatusChangePromise =
            Utils.waitForEvent(mediaKeySession, 'keystatuseschange');

        // Now call close() and wait for the session to be closed along with
        // the 'keystatuseschange' event.
        Utils.timeLog('Calling close()');
        return Promise.all([
            mediaKeySession.close(),
            mediaKeySession.closed,
            waitForKeyStatusChangePromise
        ]);
      })
      .then(function() {
        // After close() there should be no keys.
        Utils.timeLog('Checking for empty keyStatuses');
        Utils.verifyKeyStatuses(mediaKeySession.keyStatuses, []);
        Utils.setResultInTitle('ENDED');
      })
      .catch(function(error) {
        Utils.timeLog(error);
        Utils.failTest('Failed test.');
      });
</script>
</html>
