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