waiting-for-a-key.js (6843B)
1 function runTest(config) 2 { 3 // For debugging timeouts, keep track of the number of the 4 // various events received. 5 var debugEncryptedEventFired = false; 6 var debugWaitingForKeyEventFired = false; 7 var debugTimeUpdateEventCount = 0; 8 var debugMessage = ''; 9 10 // Set global option explicit_timeout to true and control 11 // the timeout in the promise test below. 12 setup({ 13 explicit_timeout: true 14 }); 15 16 promise_test(function (test) { 17 var video = config.video; 18 var keysystem = config.keysystem; 19 var configuration = { 20 initDataTypes: [config.initDataType], 21 audioCapabilities: [{ 22 contentType: config.audioType 23 }], 24 videoCapabilities: [{ 25 contentType: config.videoType 26 }], 27 sessionTypes: ['temporary'] 28 }; 29 var initData; 30 var initDataType; 31 var mediaKeySession; 32 // As this code doesn't wait for the 'message' event for clearkey to avoid 33 // race conditions with 'waitingforkey', specify the key ID and 34 // key used by the encrypted content. 35 var keyId = new Uint8Array(config.content.keys[0].kid); 36 var rawKey = new Uint8Array(config.content.keys[0].key); 37 // Use the message handler for non clearkey drm 38 var handler = config.messageHandler || null; 39 40 // Override timeout() to use custom message instead of default 41 // message "Test timed out" 42 test.timeout = function () { 43 var message = 'timeout. message = ' + debugMessage 44 + ', encrypted: ' + debugEncryptedEventFired 45 + ', waitingforkey: ' + debugWaitingForKeyEventFired 46 + ', timeupdate count: ' + debugTimeUpdateEventCount; 47 48 this.timeout_id = null; 49 this.set_status(this.TIMEOUT, message); 50 this.phase = this.phases.HAS_RESULT; 51 this.done(); 52 }; 53 54 return navigator.requestMediaKeySystemAccess(keysystem, [configuration]).then(function (access) { 55 debugMessage = 'createMediaKeys()'; 56 return access.createMediaKeys(); 57 }).then(function (mediaKeys) { 58 debugMessage = 'setMediaKeys()'; 59 return video.setMediaKeys(mediaKeys); 60 }).then(function () { 61 return testmediasource(config); 62 }).then(function (source) { 63 debugMessage = 'wait_for_encrypted_event()'; 64 mediaSource = source; 65 video.src = URL.createObjectURL(mediaSource); 66 video.play(); 67 return wait_for_encrypted_event(video); 68 }).then(function (e) { 69 // Received the 'encrypted' event(s), so keep a copy of 70 // the initdata for use when creating the session later. 71 initDataType = config.initData ? config.initDataType : e.initDataType; 72 initData = config.initData || e.initData; 73 // Wait until the video indicates that it needs a key to 74 // continue. 75 debugMessage = 'wait_for_waitingforkey_event()'; 76 return wait_for_waitingforkey_event(video); 77 }).then(function () { 78 // Make sure the video is NOT paused and not progressing 79 // before a key is provided. This requires the video 80 // to NOT have a clear lead. 81 assert_false(video.paused); 82 assert_less_than(video.currentTime, 0.2); 83 // Create a session. 84 mediaKeySession = video.mediaKeys.createSession('temporary'); 85 debugMessage = 'generateRequest()'; 86 return mediaKeySession.generateRequest(initDataType, initData); 87 }).then(function () { 88 // generateRequest() will cause a 'message' event to 89 // occur specifying the keyId that is needed 90 // Add the key needed to decrypt. 91 return wait_for_message_event(mediaKeySession, handler); 92 }).then(function () { 93 // Video should start playing now that it can decrypt the 94 // streams, so wait until a little bit of the video has 95 // played. 96 debugMessage = 'wait_for_timeupdate_event()'; 97 return wait_for_timeupdate_event(video); 98 }).catch(function (error) { 99 assert_unreached('Error: ' + error.name); 100 }); 101 102 // Typical test duration is 6 seconds on release builds 103 // (12 seconds on debug). 104 }, 'Waiting for a key.'); 105 106 // Wait for an 'encrypted' event 107 function wait_for_encrypted_event(video) 108 { 109 return new Promise(function (resolve) { 110 video.addEventListener('encrypted', function listener(e) { 111 assert_equals(e.target, video); 112 assert_true(e instanceof window.MediaEncryptedEvent); 113 assert_equals(e.type, 'encrypted'); 114 debugEncryptedEventFired = true; 115 video.removeEventListener('encrypted', listener); 116 resolve(e); 117 }); 118 }); 119 }; 120 121 // Wait for a 'waitingforkey' event. Promise resolved when the 122 // event is received. 123 function wait_for_waitingforkey_event(video) 124 { 125 return new Promise(function (resolve) { 126 video.addEventListener('waitingforkey', function listener(e) { 127 assert_equals(e.target, video); 128 assert_equals(e.type, 'waitingforkey'); 129 debugWaitingForKeyEventFired = true; 130 video.removeEventListener('waitingforkey', listener); 131 resolve(e); 132 }); 133 }); 134 }; 135 136 // Wait for a 'timeupdate' event. Promise resolved if |video| has 137 // played for more than 0.2 seconds. 138 function wait_for_timeupdate_event(video) 139 { 140 return new Promise(function (resolve) { 141 video.addEventListener('timeupdate', function listener(e) { 142 assert_equals(e.target, video); 143 ++debugTimeUpdateEventCount; 144 if (video.currentTime < 0.2) 145 return; 146 video.removeEventListener('timeupdate', listener); 147 resolve(e); 148 }); 149 }); 150 }; 151 152 // We need to wait for the message even if for non clearkey DRMs. 153 function wait_for_message_event(mediaKeySession, handler) 154 { 155 return new Promise(function (resolve, reject) { 156 mediaKeySession.addEventListener('message', function listener(e) { 157 assert_equals(e.target, mediaKeySession); 158 assert_equals(e.type, 'message'); 159 video.removeEventListener('message', listener); 160 return handler(e.messageType, e.message).then(function (response) { 161 return e.target.update(response) 162 }).then(resolve, reject); 163 }); 164 }); 165 } 166 }