Updating XTBs based on .GRDs from branch master
[chromium-blink-merge.git] / media / test / data / eme_player_js / player_utils.js
bloba532e1af7a37224d2d1f967fa1b2b7e5272a9d33
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.
5 // The PlayerUtils provides utility functions to binding common media events
6 // to specific player functions. It also provides functions to load media source
7 // base on test configurations.
8 var PlayerUtils = new function() {
11 // Prepares a video element for playback by setting default event handlers
12 // and source attribute.
13 PlayerUtils.registerDefaultEventListeners = function(player) {
14   Utils.timeLog('Registering video event handlers.');
15   // Map from event name to event listener function name.  It is common for
16   // event listeners to be named onEventName.
17   var eventListenerMap = {
18     'encrypted': 'onEncrypted',
19     'webkitneedkey': 'onWebkitNeedKey',
20     'webkitkeymessage': 'onWebkitKeyMessage',
21     'webkitkeyadded': 'onWebkitKeyAdded',
22     'webkitkeyerror': 'onWebkitKeyError'
23   };
24   for (eventName in eventListenerMap) {
25     var eventListenerFunction = player[eventListenerMap[eventName]];
26     if (eventListenerFunction) {
27       player.video.addEventListener(eventName, function(e) {
28         player[eventListenerMap[e.type]](e);
29       });
30     }
31   }
33   player.video.addEventListener('error', function(error) {
34     // This most likely happens on pipeline failures (e.g. when the CDM
35     // crashes).
36     Utils.timeLog('onHTMLElementError', error);
37     Utils.failTest(error);
38   });
41 // Register the necessary event handlers needed when playing encrypted content
42 // using the unprefixed API. Returns a promise that resolves to the player.
43 PlayerUtils.registerEMEEventListeners = function(player) {
44   player.video.addEventListener('encrypted', function(message) {
46     function addMediaKeySessionListeners(mediaKeySession) {
47       mediaKeySession.addEventListener('message', function(message) {
48         player.video.receivedKeyMessage = true;
49         if (Utils.isRenewalMessage(message)) {
50           Utils.timeLog('MediaKeySession onMessage - renewal', message);
51           player.video.receivedRenewalMessage = true;
52         } else {
53           if (message.messageType != 'license-request') {
54             Utils.failTest('Unexpected message type "' + message.messageType +
55                                '" received.',
56                            EME_MESSAGE_UNEXPECTED_TYPE);
57           }
58         }
59         player.onMessage(message);
60       });
61     }
63     try {
64       if (player.testConfig.sessionToLoad) {
65         Utils.timeLog('Loading session: ' + player.testConfig.sessionToLoad);
66         var session =
67             message.target.mediaKeys.createSession('persistent-license');
68         addMediaKeySessionListeners(session);
69         session.load(player.testConfig.sessionToLoad)
70             .then(
71                 function(result) {
72                   if (!result)
73                     Utils.failTest('Session not found.', EME_SESSION_NOT_FOUND);
74                 },
75                 function(error) { Utils.failTest(error, EME_LOAD_FAILED); });
76       } else {
77         Utils.timeLog('Creating new media key session for initDataType: ' +
78                       message.initDataType + ', initData: ' +
79                       Utils.getHexString(new Uint8Array(message.initData)));
80         var session = message.target.mediaKeys.createSession();
81         addMediaKeySessionListeners(session);
82         session.generateRequest(message.initDataType, message.initData)
83             .catch(function(error) {
84               // Ignore the error if a crash is expected. This ensures that
85               // the decoder actually detects and reports the error.
86               if (this.testConfig.keySystem !=
87                   'org.chromium.externalclearkey.crash') {
88                 Utils.failTest(error, EME_GENERATEREQUEST_FAILED);
89               }
90             });
91       }
92     } catch (e) {
93       Utils.failTest(e);
94     }
95   });
97   this.registerDefaultEventListeners(player);
98   player.video.receivedKeyMessage = false;
99   Utils.timeLog('Setting video media keys: ' + player.testConfig.keySystem);
100   var config = {};
101   if (player.testConfig.sessionToLoad) {
102     config = {
103         persistentState: "required",
104         sessionTypes: ["temporary", "persistent-license"]
105     };
106   }
107   return navigator.requestMediaKeySystemAccess(
108       player.testConfig.keySystem, [config])
109       .then(function(access) { return access.createMediaKeys(); })
110       .then(function(mediaKeys) {
111         return player.video.setMediaKeys(mediaKeys);
112       })
113       .then(function(result) { return player; })
114       .catch(function(error) { Utils.failTest(error, NOTSUPPORTEDERROR); });
117 // Register the necessary event handlers needed when playing encrypted content
118 // using the prefixed API. Even though the prefixed API is all synchronous,
119 // returns a promise that resolves to the player.
120 PlayerUtils.registerPrefixedEMEEventListeners = function(player) {
121  player.video.addEventListener('webkitneedkey', function(message) {
122     var initData = message.initData;
123     if (player.testConfig.sessionToLoad) {
124       Utils.timeLog('Loading session: ' + player.testConfig.sessionToLoad);
125       initData =
126           Utils.convertToUint8Array(PREFIXED_EME_API_LOAD_SESSION_HEADER +
127                                     player.testConfig.sessionToLoad);
128     }
129     Utils.timeLog(player.testConfig.keySystem +
130                   ' Generate key request, initData: ' +
131                   Utils.getHexString(initData));
132     try {
133       message.target.webkitGenerateKeyRequest(player.testConfig.keySystem,
134                                               initData);
135     } catch (e) {
136       Utils.failTest(e);
137     }
138   });
140   player.video.addEventListener('webkitkeyadded', function(message) {
141     Utils.timeLog('onWebkitKeyAdded', message);
142     message.target.receivedKeyAdded = true;
143   });
145   player.video.addEventListener('webkitkeyerror', function(error) {
146     Utils.timeLog('onWebkitKeyError',
147                   'KeySystem: ' + error.keySystem + ', sessionId: ' +
148                       error.sessionId + ', errorCode: ' + error.errorCode.code +
149                       ', systemCode: ' + error.systemCode);
150     Utils.failTest(error, PREFIXED_EME_ERROR_EVENT);
151   });
153   player.video.addEventListener('webkitkeymessage', function(message) {
154     Utils.timeLog('onWebkitKeyMessage', message);
155     message.target.receivedKeyMessage = true;
156     if (Utils.isRenewalMessagePrefixed(message.message)) {
157       Utils.timeLog('onWebkitKeyMessage - renewal', message);
158       message.target.receivedRenewalMessage = true;
159     }
160   });
162   // The prefixed API is all synchronous, so wrap the calls in a promise.
163   return new Promise(function(resolve, reject) {
164     PlayerUtils.registerDefaultEventListeners(player);
165     player.video.receivedKeyMessage = false;
166     resolve(player);
167   });
170 PlayerUtils.setVideoSource = function(player) {
171   if (player.testConfig.useMSE) {
172     Utils.timeLog('Loading media using MSE.');
173     var mediaSource =
174         MediaSourceUtils.loadMediaSourceFromTestConfig(player.testConfig);
175     player.video.src = window.URL.createObjectURL(mediaSource);
176   } else {
177     Utils.timeLog('Loading media using src.');
178     player.video.src = player.testConfig.mediaFile;
179   }
182 // Initialize the player to play encrypted content. Returns a promise that
183 // resolves to the player.
184 PlayerUtils.initEMEPlayer = function(player) {
185   return player.registerEventListeners().then(function(result) {
186     PlayerUtils.setVideoSource(player);
187     return player;
188   });
191 // Return the appropriate player based on test configuration.
192 PlayerUtils.createPlayer = function(video, testConfig) {
193   // Update keySystem if using prefixed Clear Key since it is not available as a
194   // separate key system to choose from; however it can be set in URL query.
195   var usePrefixedEME = testConfig.usePrefixedEME;
196   if (testConfig.keySystem == CLEARKEY && usePrefixedEME)
197     testConfig.keySystem = PREFIXED_CLEARKEY;
199   function getPlayerType(keySystem) {
200     switch (keySystem) {
201       case WIDEVINE_KEYSYSTEM:
202         if (usePrefixedEME)
203           return PrefixedWidevinePlayer;
204         return WidevinePlayer;
205       case PREFIXED_CLEARKEY:
206         return PrefixedClearKeyPlayer;
207       case EXTERNAL_CLEARKEY:
208       case CLEARKEY:
209         if (usePrefixedEME)
210           return PrefixedClearKeyPlayer;
211         return ClearKeyPlayer;
212       case FILE_IO_TEST_KEYSYSTEM:
213         return FileIOTestPlayer;
214       default:
215         Utils.timeLog(keySystem + ' is not a known key system');
216         if (usePrefixedEME)
217           return PrefixedClearKeyPlayer;
218         return ClearKeyPlayer;
219     }
220   }
221   var Player = getPlayerType(testConfig.keySystem);
222   return new Player(video, testConfig);