summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/encrypted-media/scripts/waiting-for-a-key.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/encrypted-media/scripts/waiting-for-a-key.js')
-rw-r--r--testing/web-platform/tests/encrypted-media/scripts/waiting-for-a-key.js166
1 files changed, 166 insertions, 0 deletions
diff --git a/testing/web-platform/tests/encrypted-media/scripts/waiting-for-a-key.js b/testing/web-platform/tests/encrypted-media/scripts/waiting-for-a-key.js
new file mode 100644
index 0000000000..fdfb855677
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/scripts/waiting-for-a-key.js
@@ -0,0 +1,166 @@
+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);
+ });
+ });
+ }
+}