chromium/media/test/data/eme_load_session_after_close_test.html

<!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>