blob: dca7229760039e79e73961560ccc95defa76fcc9 [file] [log] [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();
// 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 =;
function onSuccess(response) {
var key = new Uint8Array(response);
Utils.timeLog('Calling update()');
mediaKeySession.update(key).then(resolve, reject);
'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 =;
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.
const 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) {
'Supports initDataType ' +
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,
.then(function() {
// Session should have 1 usable key.
Utils.timeLog('Checking for usable keyStatuses');
mediaKeySession.keyStatuses, [{keyId: keyId, status: 'usable'}]);
// Once remove() is called, another 'keystatuseschange' event will
// happen.
const waitForKeyStatusChangePromise =
Utils.waitForEvent(mediaKeySession, 'keystatuseschange');
Utils.timeLog('Calling remove()');
const removePromise = mediaKeySession.remove();
return Promise.all([removePromise, waitForKeyStatusChangePromise]);
.then(function() {
// After remove() all keys should be 'released'.
Utils.timeLog('Checking for released keyStatuses');
mediaKeySession.keyStatuses, [{keyId: keyId, status: 'released'}]);
// After remove() the session expiry should be NaN.
if (!isNaN(mediaKeySession.expiration)) {
Utils.failTest('expiration is not Nan');
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, []);
.catch(function(error) {
Utils.failTest('Failed test.');