OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 var keySystem = QueryString.keysystem; | 5 var keySystem = QueryString.keysystem; |
6 var mediaFile = QueryString.mediafile; | 6 var mediaFile = QueryString.mediafile; |
7 var mediaType = QueryString.mediatype || 'video/webm; codecs="vorbis, vp8"'; | 7 var mediaType = QueryString.mediatype || 'video/webm; codecs="vorbis, vp8"'; |
8 var useMSE = QueryString.usemse == 1; | 8 var useMSE = QueryString.usemse == 1; |
9 | 9 |
10 // Default key used to encrypt many media files used in browser tests. | 10 // Default key used to encrypt many media files used in browser tests. |
11 var KEY = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b, | 11 var KEY = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b, |
12 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]); | 12 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]); |
13 // KEY_ID constant used as init data while encrypting test media files. | 13 // KEY_ID constant used as init data while encrypting test media files. |
14 var KEY_ID = getInitDataFromKeyId("0123456789012345"); | 14 var KEY_ID = getInitDataFromKeyId("0123456789012345"); |
15 // Heart beat message header. | 15 // Heart beat message header. |
16 var HEART_BEAT_HEADER = 'HEARTBEAT'; | 16 var HEART_BEAT_HEADER = 'HEARTBEAT'; |
17 var CDM_FILE_IO_TEST_RESULT_HEADER = 'CDMFILEIOTESTRESULT'; | |
17 var EXTERNAL_CLEAR_KEY_KEY_SYSTEM = "org.chromium.externalclearkey"; | 18 var EXTERNAL_CLEAR_KEY_KEY_SYSTEM = "org.chromium.externalclearkey"; |
18 // Note that his URL has been normalized from the one in clear_key_cdm.cc. | 19 // Note that his URL has been normalized from the one in clear_key_cdm.cc. |
19 var EXTERNAL_CLEAR_KEY_HEARTBEAT_URL = | 20 var EXTERNAL_CLEAR_KEY_HEARTBEAT_URL = |
20 'http://test.externalclearkey.chromium.org/'; | 21 'http://test.externalclearkey.chromium.org/'; |
21 | 22 |
22 function isHeartbeatMessage(msg) { | 23 function hasPrefix(msg, prefix) { |
23 if (msg.length < HEART_BEAT_HEADER.length) | 24 if (msg.length < prefix.length) |
24 return false; | 25 return false; |
25 for (var i = 0; i < HEART_BEAT_HEADER.length; ++i) { | 26 for (var i = 0; i < prefix.length; ++i) { |
ddorwin
2013/12/04 05:27:08
is there a reason we can't use substr?
xhwang
2013/12/10 01:24:25
msg is an uint8 array, not a string :(
| |
26 if (String.fromCharCode(msg[i]) != HEART_BEAT_HEADER[i]) | 27 if (String.fromCharCode(msg[i]) != prefix[i]) |
27 return false; | 28 return false; |
28 } | 29 } |
29 return true; | 30 return true; |
30 } | 31 } |
31 | 32 |
33 function isHeartbeatMessage(msg) { | |
34 return hasPrefix(msg, HEART_BEAT_HEADER); | |
35 } | |
36 | |
37 function isCdmFileIOTestMessage(msg) { | |
38 return hasPrefix(msg, CDM_FILE_IO_TEST_RESULT_HEADER); | |
39 } | |
40 | |
32 function loadEncryptedMediaFromURL(video) { | 41 function loadEncryptedMediaFromURL(video) { |
33 return loadEncryptedMedia(video, mediaFile, keySystem, KEY, useMSE); | 42 return loadEncryptedMedia(video, mediaFile, keySystem, KEY, useMSE); |
34 } | 43 } |
35 | 44 |
36 function loadEncryptedMedia(video, mediaFile, keySystem, key, useMSE, | 45 function loadEncryptedMedia(video, mediaFile, keySystem, key, useMSE, |
37 appendSourceCallbackFn) { | 46 appendSourceCallbackFn) { |
38 var keyRequested = false; | 47 var keyRequested = false; |
39 var sourceOpened = false; | 48 var sourceOpened = false; |
40 // Add properties to enable verification that events occurred. | 49 // Add properties to enable verification that events occurred. |
41 video.receivedKeyAdded = false; | 50 video.receivedKeyAdded = false; |
42 video.receivedHeartbeat = false; | 51 video.receivedHeartbeat = false; |
52 video.cdmFileIOTestPassed = false; | |
43 video.isHeartbeatExpected = keySystem === EXTERNAL_CLEAR_KEY_KEY_SYSTEM; | 53 video.isHeartbeatExpected = keySystem === EXTERNAL_CLEAR_KEY_KEY_SYSTEM; |
54 video.isCdmFileIOTestExpected = keySystem === EXTERNAL_CLEAR_KEY_KEY_SYSTEM; | |
44 video.receivedKeyMessage = false; | 55 video.receivedKeyMessage = false; |
45 | 56 |
46 if (!(video && mediaFile && keySystem && key)) { | 57 if (!(video && mediaFile && keySystem && key)) { |
47 failTest('Missing parameters in loadEncryptedMedia().'); | 58 failTest('Missing parameters in loadEncryptedMedia().'); |
48 return; | 59 return; |
49 } | 60 } |
50 | 61 |
51 function onNeedKey(e) { | 62 function onNeedKey(e) { |
52 if (keyRequested) | 63 if (keyRequested) |
53 return; | 64 return; |
(...skipping 28 matching lines...) Expand all Loading... | |
82 return; | 93 return; |
83 } | 94 } |
84 | 95 |
85 if (isHeartbeatMessage(e.message)) { | 96 if (isHeartbeatMessage(e.message)) { |
86 console.log('onKeyMessage - heartbeat', e); | 97 console.log('onKeyMessage - heartbeat', e); |
87 e.target.receivedHeartbeat = true; | 98 e.target.receivedHeartbeat = true; |
88 verifyHeartbeatMessage(e); | 99 verifyHeartbeatMessage(e); |
89 return; | 100 return; |
90 } | 101 } |
91 | 102 |
103 if (isCdmFileIOTestMessage(e.message)) { | |
104 var success = getCdmFileIOTestResult(e); | |
105 console.log('onKeyMessage - CDM file IO test: ' + | |
106 (success ? 'Success' : 'Fail')); | |
107 e.target.cdmFileIOTestPassed = success; | |
108 return; | |
109 } | |
110 | |
92 // No tested key system returns defaultURL in for key request messages. | 111 // No tested key system returns defaultURL in for key request messages. |
93 if (e.defaultURL) { | 112 if (e.defaultURL) { |
94 failTest('keymessage unexpectedly has defaultURL: ' + e.defaultURL); | 113 failTest('keymessage unexpectedly has defaultURL: ' + e.defaultURL); |
95 return; | 114 return; |
96 } | 115 } |
97 | 116 |
98 // keymessage in response to generateKeyRequest. Reply with key. | 117 // keymessage in response to generateKeyRequest. Reply with key. |
99 console.log('onKeyMessage - key request', e); | 118 console.log('onKeyMessage - key request', e); |
100 var initData = e.message; | 119 var initData = e.message; |
101 if (mediaType.indexOf('mp4') != -1) | 120 if (mediaType.indexOf('mp4') != -1) |
102 initData = KEY_ID; // Temporary hack for Clear Key in v0.1. | 121 initData = KEY_ID; // Temporary hack for Clear Key in v0.1. |
103 video.webkitAddKey(keySystem, key, initData); | 122 video.webkitAddKey(keySystem, key, initData); |
104 } | 123 } |
105 | 124 |
106 function verifyHeartbeatMessage(e) { | 125 function verifyHeartbeatMessage(e) { |
107 // Only External Clear Key sends a HEARTBEAT message. | 126 // Only External Clear Key sends a HEARTBEAT message. |
108 if (e.keySystem != EXTERNAL_CLEAR_KEY_KEY_SYSTEM) { | 127 if (e.keySystem != EXTERNAL_CLEAR_KEY_KEY_SYSTEM) { |
109 failTest('Unexpected heartbeat from ' + e.keySystem); | 128 failTest('Unexpected heartbeat from ' + e.keySystem); |
110 return; | 129 return; |
111 } | 130 } |
112 | 131 |
113 if (e.defaultURL != EXTERNAL_CLEAR_KEY_HEARTBEAT_URL) { | 132 if (e.defaultURL != EXTERNAL_CLEAR_KEY_HEARTBEAT_URL) { |
114 failTest('Heartbeat message with unexpected defaultURL: ' + e.defaultURL); | 133 failTest('Heartbeat message with unexpected defaultURL: ' + e.defaultURL); |
115 return; | 134 return; |
116 } | 135 } |
117 } | 136 } |
118 | 137 |
138 function getCdmFileIOTestResult(e) { | |
139 // Only External Clear Key sends a HEARTBEAT message. | |
ddorwin
2013/12/04 05:27:08
update comment
xhwang
2013/12/10 01:24:25
Done.
| |
140 if (e.keySystem != EXTERNAL_CLEAR_KEY_KEY_SYSTEM) { | |
141 failTest('Unexpected CDM file IO test result from ' + e.keySystem); | |
142 return false; | |
143 } | |
144 | |
145 if (e.message.length != CDM_FILE_IO_TEST_RESULT_HEADER.length + 1) | |
ddorwin
2013/12/04 05:27:08
Explain that the result is appended and one charac
xhwang
2013/12/10 01:24:25
Done.
| |
146 return false; | |
147 | |
148 var result_index = CDM_FILE_IO_TEST_RESULT_HEADER.length; | |
149 return String.fromCharCode(e.message[result_index]) == 1; | |
ddorwin
2013/12/04 05:27:08
'1' for clarity?
xhwang
2013/12/10 01:24:25
Well, e.message[result_index] == '1' doesn't work.
ddorwin
2013/12/11 21:16:16
but can we s/1/'1'/? There's an implicit conversio
| |
150 } | |
151 | |
119 video.addEventListener('webkitneedkey', onNeedKey); | 152 video.addEventListener('webkitneedkey', onNeedKey); |
120 video.addEventListener('webkitkeymessage', onKeyMessage); | 153 video.addEventListener('webkitkeymessage', onKeyMessage); |
121 video.addEventListener('webkitkeyerror', function() { | 154 video.addEventListener('webkitkeyerror', function() { |
122 setResultInTitle("KeyError"); | 155 setResultInTitle("KeyError"); |
123 }); | 156 }); |
124 video.addEventListener('webkitkeyadded', onKeyAdded); | 157 video.addEventListener('webkitkeyadded', onKeyAdded); |
125 installTitleEventHandler(video, 'error'); | 158 installTitleEventHandler(video, 'error'); |
126 | 159 |
127 if (useMSE) { | 160 if (useMSE) { |
128 var mediaSource = loadMediaSource(mediaFile, mediaType, | 161 var mediaSource = loadMediaSource(mediaFile, mediaType, |
129 appendSourceCallbackFn); | 162 appendSourceCallbackFn); |
130 video.src = window.URL.createObjectURL(mediaSource); | 163 video.src = window.URL.createObjectURL(mediaSource); |
131 } else { | 164 } else { |
132 video.src = mediaFile; | 165 video.src = mediaFile; |
133 } | 166 } |
134 } | 167 } |
135 | 168 |
136 function getInitDataFromKeyId(keyID) { | 169 function getInitDataFromKeyId(keyID) { |
137 var init_key_id = new Uint8Array(keyID.length); | 170 var init_key_id = new Uint8Array(keyID.length); |
138 for(var i = 0; i < keyID.length; i++) { | 171 for(var i = 0; i < keyID.length; i++) { |
139 init_key_id[i] = keyID.charCodeAt(i); | 172 init_key_id[i] = keyID.charCodeAt(i); |
140 } | 173 } |
141 return init_key_id; | 174 return init_key_id; |
142 } | 175 } |
OLD | NEW |