Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / test / data / media / encrypted_media_utils.js
blob28480528bdc9fb1b954a36068a4d9c28760ed82f
1 // Copyright 2013 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 var keySystem = QueryString.keysystem;
6 var mediaFile = QueryString.mediafile;
7 var mediaType = QueryString.mediatype || 'video/webm; codecs="vorbis, vp8"';
8 var useMSE = QueryString.usemse == 1;
10 // Default key used to encrypt many media files used in browser tests.
11 var KEY = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
12 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);
13 // KEY_ID constant used as init data while encrypting test media files.
14 var KEY_ID = getInitDataFromKeyId("0123456789012345");
15 // Heart beat message header.
16 var HEART_BEAT_HEADER = 'HEARTBEAT';
17 var FILE_IO_TEST_RESULT_HEADER = 'FILEIOTESTRESULT';
18 var EXTERNAL_CLEAR_KEY_KEY_SYSTEM = "org.chromium.externalclearkey";
19 var EXTERNAL_CLEAR_KEY_FILE_IO_TEST_KEY_SYSTEM =
20 "org.chromium.externalclearkey.fileiotest";
21 // Note that his URL has been normalized from the one in clear_key_cdm.cc.
22 var EXTERNAL_CLEAR_KEY_HEARTBEAT_URL =
23 'http://test.externalclearkey.chromium.org/';
25 function hasPrefix(msg, prefix) {
26 if (msg.length < prefix.length)
27 return false;
28 for (var i = 0; i < prefix.length; ++i) {
29 if (String.fromCharCode(msg[i]) != prefix[i])
30 return false;
32 return true;
35 function isHeartbeatMessage(msg) {
36 return hasPrefix(msg, HEART_BEAT_HEADER);
39 function isFileIOTestMessage(msg) {
40 return hasPrefix(msg, FILE_IO_TEST_RESULT_HEADER);
43 function loadEncryptedMediaFromURL(video) {
44 return loadEncryptedMedia(video, mediaFile, keySystem, KEY, useMSE);
47 function loadEncryptedMedia(video, mediaFile, keySystem, key, useMSE,
48 appendSourceCallbackFn) {
49 var keyRequested = false;
50 var sourceOpened = false;
51 // Add properties to enable verification that events occurred.
52 video.receivedKeyAdded = false;
53 video.receivedHeartbeat = false;
54 video.isHeartbeatExpected = keySystem === EXTERNAL_CLEAR_KEY_KEY_SYSTEM;
55 video.receivedKeyMessage = false;
57 if (!(video && mediaFile && keySystem && key)) {
58 failTest('Missing parameters in loadEncryptedMedia().');
59 return;
62 function onNeedKey(e) {
63 if (keyRequested)
64 return;
65 keyRequested = true;
66 console.log('onNeedKey', e);
67 try {
68 video.webkitGenerateKeyRequest(keySystem, e.initData);
70 catch(error) {
71 setResultInTitle(error.name);
75 function onKeyAdded(e) {
76 e.target.receivedKeyAdded = true;
79 function onKeyMessage(e) {
80 video.receivedKeyMessage = true;
81 if (!e.keySystem) {
82 failTest('keymessage without a keySystem: ' + e.keySystem);
83 return;
86 if (!e.sessionId) {
87 failTest('keymessage without a sessionId: ' + e.sessionId);
88 return;
91 if (!e.message) {
92 failTest('keymessage without a message: ' + e.message);
93 return;
96 if (isHeartbeatMessage(e.message)) {
97 console.log('onKeyMessage - heartbeat', e);
98 e.target.receivedHeartbeat = true;
99 verifyHeartbeatMessage(e);
100 return;
103 if (isFileIOTestMessage(e.message)) {
104 var success = getFileIOTestResult(e);
105 console.log('onKeyMessage - CDM file IO test: ' +
106 (success ? 'Success' : 'Fail'));
107 if (success)
108 setResultInTitle("FILEIOTESTSUCCESS");
109 else
110 setResultInTitle("FAILED");
111 return;
114 // For FileIOTest key system, no need to start playback.
115 if (e.keySystem == EXTERNAL_CLEAR_KEY_FILE_IO_TEST_KEY_SYSTEM)
116 return;
118 // No tested key system returns defaultURL in for key request messages.
119 if (e.defaultURL) {
120 failTest('keymessage unexpectedly has defaultURL: ' + e.defaultURL);
121 return;
124 // keymessage in response to generateKeyRequest. Reply with key.
125 console.log('onKeyMessage - key request', e);
126 var initData = e.message;
127 if (mediaType.indexOf('mp4') != -1)
128 initData = KEY_ID; // Temporary hack for Clear Key in v0.1.
129 video.webkitAddKey(keySystem, key, initData);
132 function verifyHeartbeatMessage(e) {
133 String.prototype.startsWith = function(prefix) {
134 return this.indexOf(prefix) === 0;
137 function isExternalClearKey(keySystem) {
138 return keySystem == EXTERNAL_CLEAR_KEY_KEY_SYSTEM ||
139 keySystem.startsWith(EXTERNAL_CLEAR_KEY_KEY_SYSTEM + '.');
142 // Only External Clear Key sends a HEARTBEAT message.
143 if (!isExternalClearKey(e.keySystem)) {
144 failTest('Unexpected heartbeat from ' + e.keySystem);
145 return;
148 if (e.defaultURL != EXTERNAL_CLEAR_KEY_HEARTBEAT_URL) {
149 failTest('Heartbeat message with unexpected defaultURL: ' + e.defaultURL);
150 return;
154 function getFileIOTestResult(e) {
155 // Only External Clear Key sends a FILEIOTESTRESULT message.
156 if (e.keySystem != EXTERNAL_CLEAR_KEY_FILE_IO_TEST_KEY_SYSTEM) {
157 failTest('Unexpected CDM file IO test result from ' + e.keySystem);
158 return false;
161 // The test result is either '0' or '1' appended to the header.
162 if (e.message.length != FILE_IO_TEST_RESULT_HEADER.length + 1)
163 return false;
165 var result_index = FILE_IO_TEST_RESULT_HEADER.length;
166 return String.fromCharCode(e.message[result_index]) == 1;
169 video.addEventListener('webkitneedkey', onNeedKey);
170 video.addEventListener('webkitkeymessage', onKeyMessage);
171 video.addEventListener('webkitkeyerror', function() {
172 setResultInTitle("KeyError");
174 video.addEventListener('webkitkeyadded', onKeyAdded);
175 installTitleEventHandler(video, 'error');
177 if (useMSE) {
178 var mediaSource = loadMediaSource(mediaFile, mediaType,
179 appendSourceCallbackFn);
180 video.src = window.URL.createObjectURL(mediaSource);
181 } else {
182 video.src = mediaFile;
186 function getInitDataFromKeyId(keyID) {
187 var init_key_id = new Uint8Array(keyID.length);
188 for(var i = 0; i < keyID.length; i++) {
189 init_key_id[i] = keyID.charCodeAt(i);
191 return init_key_id;