Index: third_party/WebKit/LayoutTests/imported/wpt/encrypted-media/util/utils.js |
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/encrypted-media/util/utils.js b/third_party/WebKit/LayoutTests/imported/wpt/encrypted-media/util/utils.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..978cc5434d684869d1c3c5d7952e3f65901fd452 |
--- /dev/null |
+++ b/third_party/WebKit/LayoutTests/imported/wpt/encrypted-media/util/utils.js |
@@ -0,0 +1,285 @@ |
+function testnamePrefix( qualifier, keysystem ) { |
+ return ( qualifier || '' ) + ( keysystem === 'org.w3.clearkey' ? keysystem : 'drm' ); |
+} |
+ |
+function getInitData(initDataType) { |
+ |
+ // FIXME: This is messed up, because here we are hard coding the key ids for the different content |
+ // that we use for clearkey testing: webm and mp4. For keyids we return the mp4 one |
+ // |
+ // The content used with the DRM today servers has a different key id altogether |
+ |
+ if (initDataType == 'webm') { |
+ return new Uint8Array([ |
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F |
+ ]); |
+ } |
+ |
+ if (initDataType == 'cenc') { |
+ return new Uint8Array([ |
+ 0x00, 0x00, 0x00, 0x34, // size |
+ 0x70, 0x73, 0x73, 0x68, // 'pssh' |
+ 0x01, // version = 1 |
+ 0x00, 0x00, 0x00, // flags |
+ 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02, // Common SystemID |
+ 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B, |
+ 0x00, 0x00, 0x00, 0x01, // key count |
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0xd2, 0xfc, 0x41, // key id |
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
+ 0x00, 0x00, 0x00, 0x00 // datasize |
+ ]); |
+ } |
+ if (initDataType == 'keyids') { |
+ var keyId = new Uint8Array([ |
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0xd2, 0xfc, 0x41, |
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
+ ]); |
+ return stringToUint8Array(createKeyIDs(keyId)); |
+ } |
+ throw 'initDataType ' + initDataType + ' not supported.'; |
+} |
+ |
+function stringToUint8Array(str) |
+{ |
+ var result = new Uint8Array(str.length); |
+ for(var i = 0; i < str.length; i++) { |
+ result[i] = str.charCodeAt(i); |
+ } |
+ return result; |
+} |
+// Encodes |data| into base64url string. There is no '=' padding, and the |
+// characters '-' and '_' must be used instead of '+' and '/', respectively. |
+function base64urlEncode(data) { |
+ var result = btoa(String.fromCharCode.apply(null, data)); |
+ return result.replace(/=+$/g, '').replace(/\+/g, "-").replace(/\//g, "_"); |
+} |
+// Decode |encoded| using base64url decoding. |
+function base64urlDecode(encoded) { |
+ return atob(encoded.replace(/\-/g, "+").replace(/\_/g, "/")); |
+} |
+// Decode |encoded| using base64 to a Uint8Array |
+function base64DecodeToUnit8Array(encoded) { |
+ return new Uint8Array( atob( encoded ).split('').map( function(c){return c.charCodeAt(0);} ) ); |
+} |
+// Clear Key can also support Key IDs Initialization Data. |
+// ref: http://w3c.github.io/encrypted-media/keyids-format.html |
+// Each parameter is expected to be a key id in an Uint8Array. |
+function createKeyIDs() { |
+ var keyIds = '{"kids":["'; |
+ for (var i = 0; i < arguments.length; i++) { |
+ if (i != 0) keyIds += '","'; |
+ keyIds += base64urlEncode(arguments[i]); |
+ } |
+ keyIds += '"]}'; |
+ return keyIds; |
+} |
+ |
+function getSupportedKeySystem() { |
+ var userAgent = navigator.userAgent.toLowerCase(); |
+ var keysystem = undefined; |
+ if (userAgent.indexOf('edge') > -1 ) { |
+ keysystem = 'com.microsoft.playready'; |
+ } else if ( userAgent.indexOf('chrome') > -1 || userAgent.indexOf('firefox') > -1 ) { |
+ keysystem = 'com.widevine.alpha'; |
+ } |
+ return keysystem; |
+} |
+ |
+function waitForEventAndRunStep(eventName, element, func, stepTest) |
+{ |
+ var eventCallback = function(event) { |
+ if (func) |
+ func(event); |
+ } |
+ |
+ element.addEventListener(eventName, stepTest.step_func(eventCallback), true); |
+} |
+ |
+function waitForEvent(eventName, element) { |
+ return new Promise(function(resolve) { |
+ element.addEventListener(eventName, resolve, true); |
+ }) |
+} |
+ |
+var consoleDiv = null; |
+ |
+function consoleWrite(text) |
+{ |
+ if (!consoleDiv && document.body) { |
+ consoleDiv = document.createElement('div'); |
+ document.body.appendChild(consoleDiv); |
+ } |
+ var span = document.createElement('span'); |
+ span.appendChild(document.createTextNode(text)); |
+ span.appendChild(document.createElement('br')); |
+ consoleDiv.appendChild(span); |
+} |
+ |
+function forceTestFailureFromPromise(test, error, message) |
+{ |
+ test.step_func(assert_unreached)(message ? message + ': ' + error.message : error); |
+} |
+ |
+// Returns an array of audioCapabilities that includes entries for a set of |
+// codecs that should cover all user agents. |
+function getPossibleAudioCapabilities() |
+{ |
+ return [ |
+ { contentType: 'audio/mp4; codecs="mp4a.40.2"' }, |
+ { contentType: 'audio/webm; codecs="opus"' }, |
+ ]; |
+} |
+ |
+// Returns a trivial MediaKeySystemConfiguration that should be accepted, |
+// possibly as a subset of the specified capabilities, by all user agents. |
+function getSimpleConfiguration() |
+{ |
+ return [ { |
+ initDataTypes : [ 'webm', 'cenc', 'keyids' ], |
+ audioCapabilities: getPossibleAudioCapabilities() |
+ } ]; |
+} |
+ |
+// Returns a MediaKeySystemConfiguration for |initDataType| that should be |
+// accepted, possibly as a subset of the specified capabilities, by all |
+// user agents. |
+function getSimpleConfigurationForInitDataType(initDataType) |
+{ |
+ return [ { |
+ initDataTypes: [ initDataType ], |
+ audioCapabilities: getPossibleAudioCapabilities() |
+ } ]; |
+} |
+ |
+// Returns a promise that is fulfilled with true if |initDataType| is supported, |
+// by keysystem or false if not. |
+function isInitDataTypeSupported(keysystem,initDataType) |
+{ |
+ return navigator.requestMediaKeySystemAccess( |
+ keysystem, getSimpleConfigurationForInitDataType(initDataType)) |
+ .then(function() { return true; }, function() { return false; }); |
+} |
+ |
+function getSupportedInitDataTypes( keysystem ) |
+{ |
+ return [ 'cenc', 'keyids', 'webm' ].filter( isInitDataTypeSupported.bind( null, keysystem ) ); |
+} |
+ |
+function arrayBufferAsString(buffer) |
+{ |
+ var array = []; |
+ Array.prototype.push.apply( array, new Uint8Array( buffer ) ); |
+ return '0x' + array.map( function( x ) { return x < 16 ? '0'+x.toString(16) : x.toString(16); } ).join(''); |
+} |
+ |
+function dumpKeyStatuses(keyStatuses) |
+{ |
+ var userAgent = navigator.userAgent.toLowerCase(); |
+ if (userAgent.indexOf('edge') === -1) { |
+ consoleWrite("for (var entry of keyStatuses)"); |
+ for (var entry of keyStatuses) { |
+ consoleWrite(arrayBufferAsString(entry[0]) + ": " + entry[1]); |
+ } |
+ consoleWrite("for (var keyId of keyStatuses.keys())"); |
+ for (var keyId of keyStatuses.keys()) { |
+ consoleWrite(arrayBufferAsString(keyId)); |
+ } |
+ consoleWrite("for (var status of keyStatuses.values())"); |
+ for (var status of keyStatuses.values()) { |
+ consoleWrite(status); |
+ } |
+ consoleWrite("for (var entry of keyStatuses.entries())"); |
+ for (var entry of keyStatuses.entries()) { |
+ consoleWrite(arrayBufferAsString(entry[0]) + ": " + entry[1]); |
+ } |
+ consoleWrite("keyStatuses.forEach()"); |
+ keyStatuses.forEach(function(status, keyId) { |
+ consoleWrite(arrayBufferAsString(keyId) + ": " + status); |
+ }); |
+ } else { |
+ consoleWrite("keyStatuses.forEach()"); |
+ keyStatuses.forEach(function(keyId, status) { |
+ consoleWrite(arrayBufferAsString(keyId) + ": " + status); |
+ }); |
+ } |
+} |
+ |
+// Verify that |keyStatuses| contains just the keys in |keys.expected| |
+// and none of the keys in |keys.unexpected|. All keys should have status |
+// 'usable'. Example call: verifyKeyStatuses(mediaKeySession.keyStatuses, |
+// { expected: [key1], unexpected: [key2] }); |
+function verifyKeyStatuses(keyStatuses, keys) |
+{ |
+ var expected = keys.expected || []; |
+ var unexpected = keys.unexpected || []; |
+ |
+ // |keyStatuses| should have same size as number of |keys.expected|. |
+ assert_equals(keyStatuses.size, expected.length, "keystatuses should have expected size"); |
+ |
+ // All |keys.expected| should be found. |
+ expected.map(function(key) { |
+ assert_true(keyStatuses.has(key), "keystatuses should have the expected keys"); |
+ assert_equals(keyStatuses.get(key), 'usable', "keystatus value should be 'usable'"); |
+ }); |
+ |
+ // All |keys.unexpected| should not be found. |
+ unexpected.map(function(key) { |
+ assert_false(keyStatuses.has(key), "keystatuses should not have unexpected keys"); |
+ assert_equals(keyStatuses.get(key), undefined, "keystatus for unexpected key should be undefined"); |
+ }); |
+} |
+ |
+// This function checks that calling |testCase.func| returns a |
+// rejected Promise with the error.name equal to |
+// |testCase.exception|. |
+function test_exception(testCase /*...*/) { |
+ var func = testCase.func; |
+ var exception = testCase.exception; |
+ var args = Array.prototype.slice.call(arguments, 1); |
+ |
+ // Currently blink throws for TypeErrors rather than returning |
+ // a rejected promise (http://crbug.com/359386). |
+ // FIXME: Remove try/catch once they become failed promises. |
+ try { |
+ return func.apply(null, args).then( |
+ function (result) { |
+ assert_unreached(format_value(func)); |
+ }, |
+ function (error) { |
+ assert_equals(error.name, exception, format_value(func)); |
+ assert_not_equals(error.message, "", format_value(func)); |
+ } |
+ ); |
+ } catch (e) { |
+ // Only allow 'TypeError' exceptions to be thrown. |
+ // Everything else should be a failed promise. |
+ assert_equals('TypeError', exception, format_value(func)); |
+ assert_equals(e.name, exception, format_value(func)); |
+ } |
+} |
+ |
+// Check that the events sequence (array of strings) matches the pattern (array of either strings, or |
+// arrays of strings, with the latter representing a possibly repeating sub-sequence) |
+function checkEventSequence(events,pattern) { |
+ function th(i) { return i + (i < 4 ? ["th", "st", "nd", "rd"][i] : "th"); } |
+ var i = 0, j=0, k=0; |
+ while(i < events.length && j < pattern.length) { |
+ if (!Array.isArray(pattern[j])) { |
+ assert_equals(events[i], pattern[j], "Expected " + th(i+1) + " event to be '" + pattern[j] + "'"); |
+ ++i; |
+ ++j; |
+ } else { |
+ assert_equals(events[i], pattern[j][k], "Expected " + th(i+1) + " event to be '" + pattern[j][k] + "'"); |
+ ++i; |
+ k = (k+1)%pattern[j].length; |
+ if (k === 0 && events[i] !== pattern[j][0]) { |
+ ++j; |
+ } |
+ } |
+ } |
+ assert_equals(i,events.length,"Received more events than expected"); |
+ assert_equals(j,pattern.length,"Expected more events than received"); |
+} |
+ |
+ |