Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Side by Side Diff: third_party/WebKit/LayoutTests/imported/wpt/encrypted-media/polyfill/edge-keystatuses.js

Issue 2546853003: Add W3C encrypted-media tests (Closed)
Patch Set: rebase now that content files landed Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 (function() {
2
3 // This polyfill fixes the following problems with Edge browser
4 // (1) Various maplike methods for keystatuses are not supported or suported incorrectly
5 // (2) Key Ids exposed in keystatuses are incorrect (byte swaps)
6 if ( navigator.userAgent.toLowerCase().indexOf('edge') > -1 ) {
7 //////////////////////////////////////////////////////////////////////// ///////////////////////
8 // The following function is the core of this JS patch. The rest of this file is infrastructure
9 // required to enable this function
10 //////////////////////////////////////////////////////////////////////// ///////////////////////
11 function _proxyKeyStatusesChange( event ) {
12 this._keyStatuses.clear();
13 var keyStatuses = [];
14 this._session.keyStatuses.forEach( function( keyId, status ) {
15 var newKeyId = new Uint8Array( keyId );
16
17 function swap( arr, a, b ) { var t = arr[a]; arr[a] = arr[b]; ar r[b] = t; }
18 swap( newKeyId, 0, 3 );
19 swap( newKeyId, 1, 2 );
20 swap( newKeyId, 4, 5 );
21 swap( newKeyId, 6, 7 );
22
23 keyStatuses.push( { key: newKeyId, status: status, ord: arrayBuf ferAsString( newKeyId ) } );
24 });
25
26 function lexicographical( a, b ) { return a < b ? -1 : a === b ? 0 : +1; }
27 function lexicographicalkey( a, b ) { return lexicographical( a.ord, b.ord ); }
28
29 keyStatuses.sort( lexicographicalkey ).forEach( function( obj ) {
30 this._keyStatuses._set( obj.key, obj.status );
31 }.bind( this ) );
32
33 this.dispatchEvent( event );
34 };
35 //////////////////////////////////////////////////////////////////////// ///////////////////////
36
37 // Override MediaKeys.createSession
38 var _mediaKeysCreateSession = MediaKeys.prototype.createSession;
39 MediaKeys.prototype.createSession = function ( sessionType ) {
40 return new MediaKeySession( _mediaKeysCreateSession.call( this, sess ionType ) );
41 };
42
43 // MediaKeySession proxy
44 function MediaKeySession( session ) {
45 EventTarget.call( this );
46 this._session = session;
47 this._keyStatuses = new MediaKeyStatusMap();
48 this._session.addEventListener("keystatuseschange",this._onKeyStatus esChange.bind(this));
49 this._session.addEventListener("message",this.dispatchEvent.bind(thi s));
50 }
51
52 MediaKeySession.prototype = Object.create( EventTarget.prototype );
53
54 Object.defineProperties( MediaKeySession.prototype, {
55 sessionId: { get: function() { return this._session.sessionId; } },
56 expiration: { get: function() { return this._session.expiration; } } ,
57 closed: { get: function() { return this._session.closed; } },
58 keyStatuses:{ get: function() { return this._keyStatuses; } }
59 });
60
61 [ "generateRequest", "load", "update", "remove", "close" ].forEach( func tion( fnname ) {
62 MediaKeySession.prototype[ fnname ] = function() {
63 return window.MediaKeySession.prototype[ fnname ].apply( this._s ession, arguments );
64 }
65 } );
66
67 MediaKeySession.prototype._onKeyStatusesChange = _proxyKeyStatusesChange ;
68
69 // MediaKeyStatusMap proxy
70 //
71 // We need a proxy class to replace the broken MediaKeyStatusMap one. We cannot use a
72 // regular Map directly because we need get and has methods to compare b y value not
73 // as references.
74 function MediaKeyStatusMap() { this._map = new Map(); }
75
76 Object.defineProperties( MediaKeyStatusMap.prototype, {
77 size: { get: function() { return this._map.size; } },
78 forEach: { get: function() { return function( f ) { retur n this._map.forEach( f ); } } },
79 entries: { get: function() { return function() { return t his._map.entries(); } } },
80 values: { get: function() { return function() { return t his._map.values(); } } },
81 keys: { get: function() { return function() { return t his._map.keys(); } } },
82 clear: { get: function() { return function() { return t his._map.clear(); } } } } );
83
84 MediaKeyStatusMap.prototype[ Symbol.iterator ] = function() { return thi s._map[ Symbol.iterator ]() };
85
86 MediaKeyStatusMap.prototype.has = function has( keyId ) {
87 for ( var k of this._map.keys() ) { if ( arrayBufferEqual( k, keyId ) ) return true; }
88 return false;
89 };
90
91 MediaKeyStatusMap.prototype.get = function get( keyId ) {
92 for ( var k of this._map.entries() ) { if ( arrayBufferEqual( k[ 0 ] , keyId ) ) return k[ 1 ]; }
93 };
94
95 MediaKeyStatusMap.prototype._set = function _set( keyId, status ) {
96 this._map.set( new Uint8Array( keyId ), status );
97 };
98
99 function arrayBufferEqual(buf1, buf2)
100 {
101 if (buf1.byteLength !== buf2.byteLength) return false;
102 var a1 = Array.from( new Int8Array(buf1) ), a2 = Array.from( new Int 8Array(buf2) );
103 return a1.every( function( x, i ) { return x === a2[i]; } );
104 }
105
106 // EventTarget
107 function EventTarget(){
108 this.listeners = {};
109 };
110
111 EventTarget.prototype.listeners = null;
112
113 EventTarget.prototype.addEventListener = function(type, callback){
114 if(!(type in this.listeners)) {
115 this.listeners[type] = [];
116 }
117 this.listeners[type].push(callback);
118 };
119
120 EventTarget.prototype.removeEventListener = function(type, callback){
121 if(!(type in this.listeners)) {
122 return;
123 }
124 var stack = this.listeners[type];
125 for(var i = 0, l = stack.length; i < l; i++){
126 if(stack[i] === callback){
127 stack.splice(i, 1);
128 return this.removeEventListener(type, callback);
129 }
130 }
131 };
132
133 EventTarget.prototype.dispatchEvent = function(event){
134 if(!(event.type in this.listeners)) {
135 return;
136 }
137 var stack = this.listeners[event.type];
138 event.target = this;
139 for(var i = 0, l = stack.length; i < l; i++) {
140 stack[i].call(this, event);
141 }
142 };
143 }
144 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698