OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 // Utils provide logging functions and other JS functions commonly used by the | 5 // Utils provide logging functions and other JS functions commonly used by the |
6 // app and media players. | 6 // app and media players. |
7 var Utils = new function() { | 7 var Utils = new function() { |
8 this.titleChanged = false; | 8 } |
9 }; | |
10 | 9 |
11 // Adds options to document element. | 10 Utils.isHeartBeatMessage = function(msg) { |
12 Utils.addOptions = function(elementID, keyValueOptions, disabledOptions) { | 11 var message = String.fromCharCode.apply(null, msg); |
13 disabledOptions = disabledOptions || []; | 12 return message.substring(0, HEART_BEAT_HEADER.length) == HEART_BEAT_HEADER; |
14 var selectElement = document.getElementById(elementID); | |
15 var keys = Object.keys(keyValueOptions); | |
16 for (var i = 0; i < keys.length; i++) { | |
17 var key = keys[i]; | |
18 var option = new Option(key, keyValueOptions[key]); | |
19 option.title = keyValueOptions[key]; | |
20 if (disabledOptions.indexOf(key) >= 0) | |
21 option.disabled = true; | |
22 selectElement.options.add(option); | |
23 } | |
24 }; | 13 }; |
25 | 14 |
26 Utils.convertToArray = function(input) { | 15 Utils.convertToArray = function(input) { |
27 if (Array.isArray(input)) | 16 if (Array.isArray(input)) |
28 return input; | 17 return input; |
29 return [input]; | 18 return [input]; |
30 }; | 19 }; |
31 | 20 |
| 21 Utils.getHexString = function(uintArray) { |
| 22 var hex_str = ''; |
| 23 for (var i = 0; i < uintArray.length; i++) { |
| 24 var hex = uintArray[i].toString(16); |
| 25 if (hex.length == 1) |
| 26 hex = '0' + hex; |
| 27 hex_str += hex; |
| 28 } |
| 29 return hex_str; |
| 30 }; |
| 31 |
32 Utils.convertToUint8Array = function(msg) { | 32 Utils.convertToUint8Array = function(msg) { |
33 var ans = new Uint8Array(msg.length); | 33 var ans = new Uint8Array(msg.length); |
34 for (var i = 0; i < msg.length; i++) { | 34 for (var i = 0; i < msg.length; i++) { |
35 ans[i] = msg.charCodeAt(i); | 35 ans[i] = msg.charCodeAt(i); |
36 } | 36 } |
37 return ans; | 37 return ans; |
38 }; | 38 }; |
39 | 39 |
| 40 Utils.timeLog = function(/**/) { |
| 41 function documentLog(time, log) { |
| 42 var time = '<span style="color: green">' + time + '</span>'; |
| 43 docLogs.innerHTML = time + ' - ' + log + '<br>' + docLogs.innerHTML; |
| 44 } |
| 45 |
| 46 if (arguments.length == 0) |
| 47 return; |
| 48 var time = Utils.getCurrentTimeString(); |
| 49 // Log to document. |
| 50 documentLog(time, arguments[0]); |
| 51 |
| 52 // Log to JS console. |
| 53 var args = []; |
| 54 args.push(time + ' - '); |
| 55 for (var i = 0; i < arguments.length; i++) { |
| 56 args.push(arguments[i]); |
| 57 } |
| 58 console.log.apply(console, args); |
| 59 }; |
| 60 |
| 61 Utils.getCurrentTimeString = function() { |
| 62 var date = new Date(); |
| 63 var hours = ('0' + date.getHours()).slice(-2); |
| 64 var minutes = ('0' + date.getMinutes()).slice(-2); |
| 65 var secs = ('0' + date.getSeconds()).slice(-2); |
| 66 var milliSecs = ('00' + date.getMilliseconds()).slice(-3); |
| 67 return hours + ':' + minutes + ':' + secs + '.' + milliSecs; |
| 68 }; |
| 69 |
| 70 Utils.failTest = function(msg) { |
| 71 var failMessage = 'FAIL: '; |
| 72 // Handle exception messages; |
| 73 if (msg.message) { |
| 74 failMessage += msg.name ? msg.name : 'Error '; |
| 75 failMessage += msg.message; |
| 76 } |
| 77 // Handle failing events. |
| 78 else if (msg instanceof Event) |
| 79 failMessage = msg.target + '.' + msg.type; |
| 80 else |
| 81 failMessage = msg; |
| 82 Utils.timeLog('<span style="color: red">' + failMessage + '</span>', msg); |
| 83 }; |
| 84 |
| 85 Utils.sendRequest = function(requestType, responseType, message, serverURL, |
| 86 onSuccessCallbackFn) { |
| 87 var xmlhttp = new XMLHttpRequest(); |
| 88 xmlhttp.responseType = responseType; |
| 89 xmlhttp.open(requestType, serverURL, true); |
| 90 |
| 91 xmlhttp.onload = function(e) { |
| 92 if (this.status == 200) { |
| 93 if (onSuccessCallbackFn) |
| 94 onSuccessCallbackFn(this.response); |
| 95 } else { |
| 96 Utils.timeLog('Bad response status: ' + this.status); |
| 97 Utils.timeLog('Bad response: ' + this.response); |
| 98 } |
| 99 }; |
| 100 Utils.timeLog('Sending request to server: ' + serverURL); |
| 101 xmlhttp.send(message); |
| 102 }; |
| 103 |
| 104 // Adds options to document element. |
| 105 Utils.addOptions = function(elementID, keyValueOptions) { |
| 106 var selectElement = document.getElementById(elementID); |
| 107 var keys = Object.keys(keyValueOptions); |
| 108 for (var i = 0; i < keys.length; i++) { |
| 109 var option = new Option(keys[i], keyValueOptions[keys[i]]); |
| 110 option.title = keyValueOptions[keys[i]]; |
| 111 selectElement.options.add(option); |
| 112 } |
| 113 }; |
| 114 |
40 Utils.createJWKData = function(keyId, key) { | 115 Utils.createJWKData = function(keyId, key) { |
41 // JWK routines copied from third_party/WebKit/LayoutTests/media/ | 116 // JWK routines copied from third_party/WebKit/LayoutTests/media/ |
42 // encrypted-media/encrypted-media-utils.js | 117 // encrypted-media/encrypted-media-utils.js |
43 // | 118 // |
44 // Encodes data (Uint8Array) into base64 string without trailing '='. | 119 // Encodes data (Uint8Array) into base64 string without trailing '='. |
45 // TODO(jrummell): Update once the EME spec is updated to say base64url | 120 // TODO(jrummell): Update once the EME spec is updated to say base64url |
46 // encoding. | 121 // encoding. |
47 function base64Encode(data) { | 122 function base64Encode(data) { |
48 var result = btoa(String.fromCharCode.apply(null, data)); | 123 var result = btoa(String.fromCharCode.apply(null, data)); |
49 return result.replace(/=+$/g, ''); | 124 return result.replace(/=+$/g, ''); |
(...skipping 16 matching lines...) Expand all Loading... |
66 if (i != 0) | 141 if (i != 0) |
67 jwkSet += ','; | 142 jwkSet += ','; |
68 jwkSet += arguments[i]; | 143 jwkSet += arguments[i]; |
69 } | 144 } |
70 jwkSet += ']}'; | 145 jwkSet += ']}'; |
71 return jwkSet; | 146 return jwkSet; |
72 } | 147 } |
73 | 148 |
74 return Utils.convertToUint8Array(createJWKSet(createJWK(keyId, key))); | 149 return Utils.convertToUint8Array(createJWKSet(createJWK(keyId, key))); |
75 }; | 150 }; |
76 | |
77 Utils.documentLog = function(log, success, time) { | |
78 if (!docLogs) | |
79 return; | |
80 time = time || Utils.getCurrentTimeString(); | |
81 var timeLog = '<span style="color: green">' + time + '</span>'; | |
82 var logColor = !success ? 'red' : 'black'; // default is true. | |
83 log = '<span style="color: "' + logColor + '>' + log + '</span>'; | |
84 docLogs.innerHTML = timeLog + ' - ' + log + '<br>' + docLogs.innerHTML; | |
85 }; | |
86 | |
87 Utils.ensureOptionInList = function(listID, option) { | |
88 var selectElement = document.getElementById(listID); | |
89 for (var i = 0; i < selectElement.length; i++) { | |
90 if (selectElement.options[i].value == option) { | |
91 selectElement.value = option; | |
92 return; | |
93 } | |
94 } | |
95 // The list does not have the option, let's add it and select it. | |
96 var optionElement = new Option(option, option); | |
97 optionElement.title = option; | |
98 selectElement.options.add(optionElement); | |
99 selectElement.value = option; | |
100 }; | |
101 | |
102 Utils.failTest = function(msg, newTitle) { | |
103 var failMessage = 'FAIL: '; | |
104 var title = 'FAILED'; | |
105 // Handle exception messages; | |
106 if (msg.message) { | |
107 title = msg.name || 'Error'; | |
108 failMessage += title + ' ' + msg.message; | |
109 } else if (msg instanceof Event) { | |
110 // Handle failing events. | |
111 failMessage = msg.target + '.' + msg.type; | |
112 title = msg.type; | |
113 } else { | |
114 failMessage += msg; | |
115 } | |
116 // Force newTitle if passed. | |
117 title = newTitle || title; | |
118 // Log failure. | |
119 Utils.documentLog(failMessage, false); | |
120 console.log(failMessage, msg); | |
121 Utils.setResultInTitle(title); | |
122 }; | |
123 | |
124 Utils.getCurrentTimeString = function() { | |
125 var date = new Date(); | |
126 var hours = ('0' + date.getHours()).slice(-2); | |
127 var minutes = ('0' + date.getMinutes()).slice(-2); | |
128 var secs = ('0' + date.getSeconds()).slice(-2); | |
129 var milliSecs = ('00' + date.getMilliseconds()).slice(-3); | |
130 return hours + ':' + minutes + ':' + secs + '.' + milliSecs; | |
131 }; | |
132 | |
133 Utils.getDefaultKey = function(forceInvalidResponse) { | |
134 if (forceInvalidResponse) { | |
135 Utils.timeLog('Forcing invalid key data.'); | |
136 return new Uint8Array([0xAA]); | |
137 } | |
138 return KEY; | |
139 }; | |
140 | |
141 Utils.getHexString = function(uintArray) { | |
142 var hex_str = ''; | |
143 for (var i = 0; i < uintArray.length; i++) { | |
144 var hex = uintArray[i].toString(16); | |
145 if (hex.length == 1) | |
146 hex = '0' + hex; | |
147 hex_str += hex; | |
148 } | |
149 return hex_str; | |
150 }; | |
151 | |
152 Utils.getInitDataFromMessage = function(message, mediaType) { | |
153 var initData = message.message; | |
154 if (mediaType.indexOf('mp4') != -1) { | |
155 // Temporary hack for Clear Key in v0.1. | |
156 // If content uses mp4, then message.message is PSSH data. Instead of | |
157 // parsing that data we hard code the initData. | |
158 initData = Utils.convertToUint8Array(KEY_ID); | |
159 } | |
160 return initData; | |
161 }; | |
162 | |
163 Utils.hasPrefix = function(msg, prefix) { | |
164 var message = String.fromCharCode.apply(null, msg); | |
165 return message.substring(0, prefix.length) == prefix; | |
166 }; | |
167 | |
168 Utils.installTitleEventHandler = function(element, event) { | |
169 element.addEventListener(event, function(e) { | |
170 Utils.setResultInTitle(e.type); | |
171 }, false); | |
172 }; | |
173 | |
174 Utils.isHeartBeatMessage = function(msg) { | |
175 return Utils.hasPrefix(msg, HEART_BEAT_HEADER); | |
176 }; | |
177 | |
178 Utils.resetTitleChange = function() { | |
179 this.titleChanged = false; | |
180 document.title = ''; | |
181 }; | |
182 | |
183 Utils.sendRequest = function(requestType, responseType, message, serverURL, | |
184 onSuccessCallbackFn, forceInvalidResponse) { | |
185 var requestAttemptCount = 0; | |
186 var MAXIMUM_REQUEST_ATTEMPTS = 3; | |
187 var REQUEST_RETRY_DELAY_MS = 3000; | |
188 | |
189 function sendRequestAttempt() { | |
190 requestAttemptCount++; | |
191 if (requestAttemptCount == MAXIMUM_REQUEST_ATTEMPTS) { | |
192 Utils.failTest('FAILED: Exceeded maximum license request attempts.'); | |
193 return; | |
194 } | |
195 | |
196 var xmlhttp = new XMLHttpRequest(); | |
197 xmlhttp.responseType = responseType; | |
198 xmlhttp.open(requestType, serverURL, true); | |
199 | |
200 xmlhttp.onload = function(e) { | |
201 if (this.status == 200) { | |
202 if (onSuccessCallbackFn) | |
203 onSuccessCallbackFn(this.response); | |
204 } else { | |
205 Utils.timeLog('Bad response status: ' + this.status); | |
206 Utils.timeLog('Bad response: ' + this.response); | |
207 Utils.timeLog('Retrying request if possible in ' + | |
208 LICENSE_REQUEST_RETRY_DELAY_MS + 'ms'); | |
209 setTimeout(sendRequestAttempt, LICENSE_REQUEST_RETRY_DELAY_MS); | |
210 } | |
211 }; | |
212 Utils.timeLog('Attempt (' + requestAttemptCount + | |
213 '): sending request to server: ' + serverURL); | |
214 xmlhttp.send(message); | |
215 } | |
216 | |
217 if (forceInvalidResponse) { | |
218 Utils.timeLog('Not sending request - forcing an invalid response.'); | |
219 return onSuccessCallbackFn([0xAA]); | |
220 } | |
221 sendRequestAttempt(); | |
222 }; | |
223 | |
224 Utils.setResultInTitle = function(title) { | |
225 // If document title is 'ENDED', then update it with new title to possibly | |
226 // mark a test as failure. Otherwise, keep the first title change in place. | |
227 if (!this.titleChanged || document.title.toUpperCase() == 'ENDED') | |
228 document.title = title.toUpperCase(); | |
229 Utils.timeLog('Set document title to: ' + title + ', updated title: ' + | |
230 document.title); | |
231 this.titleChanged = true; | |
232 }; | |
233 | |
234 Utils.timeLog = function(/**/) { | |
235 if (arguments.length == 0) | |
236 return; | |
237 var time = Utils.getCurrentTimeString(); | |
238 // Log to document. | |
239 Utils.documentLog(arguments[0], time); | |
240 // Log to JS console. | |
241 var logString = time + ' - '; | |
242 for (var i = 0; i < arguments.length; i++) { | |
243 logString += ' ' + arguments[i]; | |
244 } | |
245 console.log(logString); | |
246 }; | |
OLD | NEW |