Source code
Revision control
Copy as Markdown
Other Tools
function runTest(config)
{
// For debugging timeouts, keep track of the number of the
// various events received.
var debugEncryptedEventFired = false;
var debugWaitingForKeyEventFired = false;
var debugTimeUpdateEventCount = 0;
var debugMessage = '';
// Set global option explicit_timeout to true and control
// the timeout in the promise test below.
setup({
explicit_timeout: true
});
promise_test(function (test) {
var video = config.video;
var keysystem = config.keysystem;
var configuration = {
initDataTypes: [config.initDataType],
audioCapabilities: [{
contentType: config.audioType
}],
videoCapabilities: [{
contentType: config.videoType
}],
sessionTypes: ['temporary']
};
var initData;
var initDataType;
var mediaKeySession;
// As this code doesn't wait for the 'message' event for clearkey to avoid
// race conditions with 'waitingforkey', specify the key ID and
// key used by the encrypted content.
var keyId = new Uint8Array(config.content.keys[0].kid);
var rawKey = new Uint8Array(config.content.keys[0].key);
// Use the message handler for non clearkey drm
var handler = config.messageHandler || null;
// Override timeout() to use custom message instead of default
// message "Test timed out"
test.timeout = function () {
var message = 'timeout. message = ' + debugMessage
+ ', encrypted: ' + debugEncryptedEventFired
+ ', waitingforkey: ' + debugWaitingForKeyEventFired
+ ', timeupdate count: ' + debugTimeUpdateEventCount;
this.timeout_id = null;
this.set_status(this.TIMEOUT, message);
this.phase = this.phases.HAS_RESULT;
this.done();
};
return navigator.requestMediaKeySystemAccess(keysystem, [configuration]).then(function (access) {
debugMessage = 'createMediaKeys()';
return access.createMediaKeys();
}).then(function (mediaKeys) {
debugMessage = 'setMediaKeys()';
return video.setMediaKeys(mediaKeys);
}).then(function () {
return testmediasource(config);
}).then(function (source) {
debugMessage = 'wait_for_encrypted_event()';
mediaSource = source;
video.src = URL.createObjectURL(mediaSource);
video.play();
return wait_for_encrypted_event(video);
}).then(function (e) {
// Received the 'encrypted' event(s), so keep a copy of
// the initdata for use when creating the session later.
initDataType = config.initData ? config.initDataType : e.initDataType;
initData = config.initData || e.initData;
// Wait until the video indicates that it needs a key to
// continue.
debugMessage = 'wait_for_waitingforkey_event()';
return wait_for_waitingforkey_event(video);
}).then(function () {
// Make sure the video is NOT paused and not progressing
// before a key is provided. This requires the video
// to NOT have a clear lead.
assert_false(video.paused);
assert_less_than(video.currentTime, 0.2);
// Create a session.
mediaKeySession = video.mediaKeys.createSession('temporary');
debugMessage = 'generateRequest()';
return mediaKeySession.generateRequest(initDataType, initData);
}).then(function () {
// generateRequest() will cause a 'message' event to
// occur specifying the keyId that is needed
// Add the key needed to decrypt.
return wait_for_message_event(mediaKeySession, handler);
}).then(function () {
// Video should start playing now that it can decrypt the
// streams, so wait until a little bit of the video has
// played.
debugMessage = 'wait_for_timeupdate_event()';
return wait_for_timeupdate_event(video);
}).catch(function (error) {
assert_unreached('Error: ' + error.name);
});
// Typical test duration is 6 seconds on release builds
// (12 seconds on debug).
}, 'Waiting for a key.');
// Wait for an 'encrypted' event
function wait_for_encrypted_event(video)
{
return new Promise(function (resolve) {
video.addEventListener('encrypted', function listener(e) {
assert_equals(e.target, video);
assert_true(e instanceof window.MediaEncryptedEvent);
assert_equals(e.type, 'encrypted');
debugEncryptedEventFired = true;
video.removeEventListener('encrypted', listener);
resolve(e);
});
});
};
// Wait for a 'waitingforkey' event. Promise resolved when the
// event is received.
function wait_for_waitingforkey_event(video)
{
return new Promise(function (resolve) {
video.addEventListener('waitingforkey', function listener(e) {
assert_equals(e.target, video);
assert_equals(e.type, 'waitingforkey');
debugWaitingForKeyEventFired = true;
video.removeEventListener('waitingforkey', listener);
resolve(e);
});
});
};
// Wait for a 'timeupdate' event. Promise resolved if |video| has
// played for more than 0.2 seconds.
function wait_for_timeupdate_event(video)
{
return new Promise(function (resolve) {
video.addEventListener('timeupdate', function listener(e) {
assert_equals(e.target, video);
++debugTimeUpdateEventCount;
if (video.currentTime < 0.2)
return;
video.removeEventListener('timeupdate', listener);
resolve(e);
});
});
};
// We need to wait for the message even if for non clearkey DRMs.
function wait_for_message_event(mediaKeySession, handler)
{
return new Promise(function (resolve, reject) {
mediaKeySession.addEventListener('message', function listener(e) {
assert_equals(e.target, mediaKeySession);
assert_equals(e.type, 'message');
video.removeEventListener('message', listener);
return handler(e.messageType, e.message).then(function (response) {
return e.target.update(response)
}).then(resolve, reject);
});
});
}
}