1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160

media / test / data / eme_remove_session_test.html [blame]

<!DOCTYPE html>
<title>Test that remove() succeeds on temporary sessions</title>
// This test is similar to the layout test
// encrypted-media-session-remove-temporary.html, but needs to run as a
// browser test as it needs access to a license server (for Widevine).

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

  // Code for using the Widevine key system.
  function WidevineKeySystemHelper() {}

  // Called when a 'message' event happens. Send the message to the license
  // server, and when the response is received, call update() and then call
  // |resolve| or |reject| as appropriate.
  WidevineKeySystemHelper.prototype.onMessage = function(
      event, resolve, reject) {
    var mediaKeySession = event.target;
    function onSuccess(response) {
      var key = new Uint8Array(response);
      Utils.timeLog('Calling update()');
      mediaKeySession.update(key).then(resolve, reject);
    }
    Utils.sendRequest(
        'POST', 'arraybuffer', Utils.convertToUint8Array(event.message),
        this.testConfig.licenseServerURL, onSuccess);
  };

  // Code for using the ClearKey key system.
  function ClearKeyKeySystemHelper() {}

  // Called when a 'message' event happens. For ClearKey we know the key to be
  // used, so simply call update() and then call |resolve| or |reject| as
  // appropriate.
  ClearKeyKeySystemHelper.prototype.onMessage = function(
      event, resolve, reject) {
    var mediaKeySession = event.target;

    Utils.timeLog('Calling update()');
    const jwkSet = Utils.createJWKData(keyId, key);
    mediaKeySession.update(jwkSet).then(resolve, reject);
  };

  var keySystemHelper;
  if (testConfig.keySystem == WIDEVINE_KEYSYSTEM) {
    keySystemHelper = new WidevineKeySystemHelper();
  } else if (
      testConfig.keySystem == CLEARKEY ||
      testConfig.keySystem == EXTERNAL_CLEARKEY) {
    keySystemHelper = new ClearKeyKeySystemHelper();
  } else {
    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.
  config = [{
    initDataTypes: ['webm'],
    audioCapabilities: [
      {contentType: 'audio/mp4; codecs="mp4a.40.2"'},
      {contentType: 'audio/webm; codecs="opus"'},
    ],
    persistentState: 'optional',
    sessionTypes: ['temporary'],
  }];

  var mediaKeySession;
  navigator.requestMediaKeySystemAccess(testConfig.keySystem, config)
      .then(function(access) {
        Utils.timeLog(
            'Supports initDataType ' +
            access.getConfiguration().initDataTypes[0]);
        return access.createMediaKeys();
      })
      .then(function(mediaKeys) {
        Utils.timeLog('Creating session');
        mediaKeySession = mediaKeys.createSession();

        // Register for the 'message' event before it happens. Although the
        // event shouldn't be generated until after the generateRequest()
        // promise is resolved, the handlers may be queued before the
        // JavaScript code runs (and thus be lost if an event handler is
        // not registered).
        // When the 'message' event occurs, keySystemHelper.onMessage() will
        // run. It will end up calling update(), and |waitForMessagePromise|
        // will be resolved or rejected with the result of calling update().
        const waitForMessagePromise = Utils.waitForEvent(
            mediaKeySession, 'message', keySystemHelper.onMessage);

        // 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');

        // As this is using 'webm' initDataType, the data to generateRequest()
        // is simply the key ID.
        Utils.timeLog('Calling generateRequest()');
        const generateRequestPromise = mediaKeySession.generateRequest(
            'webm', Utils.convertToUint8Array(keyId));

        // Can't tell what order the events happen, so simply wait for them all.
        return Promise.all([
          generateRequestPromise, waitForMessagePromise,
          waitForKeyStatusChangePromise
        ]);
      })
      .then(function() {
        // Session should have 1 usable key.
        Utils.timeLog('Checking for usable keyStatuses');
        Utils.verifyKeyStatuses(
            mediaKeySession.keyStatuses, [{keyId: keyId, status: 'usable'}]);

        promises = [];
        // Once remove() is called, another 'keystatuseschange' event will
        // happen.
        promises.push(Utils.waitForEvent(mediaKeySession, 'keystatuseschange'));

        Utils.timeLog('Calling remove()');
        promises.push(mediaKeySession.remove());

        return Promise.all(promises);
      })
      .then(function() {
        // After remove() all keys should be 'released'.
        Utils.timeLog('Checking for released keyStatuses');
        Utils.verifyKeyStatuses(
            mediaKeySession.keyStatuses, [{keyId: keyId, status: 'released'}]);
        // After remove() the session expiry should be NaN.
        if (!isNaN(mediaKeySession.expiration)) {
          Utils.failTest('expiration is not Nan');
          return;
        }
        Utils.timeLog('Calling close()');
        return mediaKeySession.close();
      })
      .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>