diff options
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.js | 166 |
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 000000000..fee70e24a --- /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.', {timeout: 20000}); + + // 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); + }); + }); + } +} |