summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/encrypted-media/Google
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /testing/web-platform/tests/encrypted-media/Google
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'testing/web-platform/tests/encrypted-media/Google')
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-async-creation-with-gc.html41
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-async-setcert-with-gc.html32
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeys-with-session.html104
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeys.html59
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeysession-reference.html157
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeysession-release-noreference.html131
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeysession-release.html118
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-multiple-mediakeys.html131
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-reload.html103
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-check-init-data-type.html51
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-clear-key-invalid-license.html47
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-clearkey-update-non-ascii-input.html53
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-events.html65
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-generate-request-disallowed-input.html107
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-keystatuses-multiple-sessions.html121
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-keystatuses-multiple-updates.html87
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-keystatuses.html174
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-not-callable-after-createsession.html67
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-onencrypted.html44
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-encrypted-and-clear-sources.html130
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-multiple-sessions.html143
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-setmediakeys-after-src.html96
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-setmediakeys-before-src.html96
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-two-videos.html90
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-requestmediakeysystemaccess.html322
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-reset-src-after-setmediakeys.html67
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-session-closed-event.html51
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-again-after-playback.html48
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-again-after-resetting-src.html44
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-at-same-time.html109
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-multiple-times-with-different-mediakeys.html83
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-multiple-times-with-the-same-mediakeys.html50
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-to-multiple-video-elements.html50
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys.html59
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-syntax.html1017
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-unique-origin.html79
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-update-disallowed-input.html73
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-utils.js333
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-waiting-for-a-key.html168
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/webm/test-encrypted-different-av-keys.webmbin0 -> 221378 bytes
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/webm/test-encrypted.webmbin0 -> 223402 bytes
-rw-r--r--testing/web-platform/tests/encrypted-media/Google/webm/test.webmbin0 -> 219448 bytes
42 files changed, 4800 insertions, 0 deletions
diff --git a/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-async-creation-with-gc.html b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-async-creation-with-gc.html
new file mode 100644
index 000000000..4dd705f9f
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-async-creation-with-gc.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Test asynchronous creation of MediaKeys and MediaKeySession while running garbage collection</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test requires Chromium specific content and is being disabled.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ async_test(function(test)
+ {
+ // Run garbage collection often.
+ setInterval(asyncGC, 0);
+
+ var initDataType;
+ var initData;
+ var mediaKeySession;
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ initDataType = access.getConfiguration().initDataTypes[0];
+ initData = getInitData(initDataType);
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ mediaKeySession = mediaKeys.createSession();
+ return mediaKeySession.generateRequest(initDataType, initData);
+ }).then(function() {
+ return mediaKeySession.close();
+ }).then(function(result) {
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'Test asynchronous creation of MediaKeys and MediaKeySession while running garbage collection.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-async-setcert-with-gc.html b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-async-setcert-with-gc.html
new file mode 100644
index 000000000..4da562894
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-async-setcert-with-gc.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Test asynchronous setServerCertificate while running garbage collection</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test requires Chromium specific content and is being disabled.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ // Run garbage collection continuously.
+ setInterval(asyncGC, 0);
+
+ promise_test(function(test)
+ {
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var cert = new Uint8Array(200);
+ return mediaKeys.setServerCertificate(cert);
+ }).then(function(result) {
+ assert_false(result);
+ });
+ }, 'Test asynchronous setServerCertificate while running garbage collection.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeys-with-session.html b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeys-with-session.html
new file mode 100644
index 000000000..a892b969c
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeys-with-session.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Test MediaKeys lifetime when adding a session</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test requires Chromium specific content and is being disabled.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ // MediaKeySessions remain as long as:
+ // JavaScript has a reference to it
+ // OR (MediaKeys is around
+ // AND the session has not received a close() event)
+ // In the tests below, we do not close any session nor keep a
+ // Javascript reference to any session, so MediaKeySessions remain
+ // as long as the associated MediaKeys object is around.
+
+ // For this test, create a MediaKeySession and verify lifetime.
+ async_test(function(test)
+ {
+ var initDataType;
+ var initData;
+ var mediaKeys;
+ var startingActiveDOMObjectCount = window.internals.activeDOMObjectCount(document);
+
+ function numActiveDOMObjectsCreated()
+ {
+ return window.internals.activeDOMObjectCount(document) - startingActiveDOMObjectCount;
+ }
+
+ // Create a MediaKeys object with a session.
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ initDataType = access.getConfiguration().initDataTypes[0];
+ initData = getInitData(initDataType);
+ return access.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys = result;
+
+ // Verify MediaKeys is an ActiveDOMObject.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 1.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 4.
+ // (1 MediaKeys,
+ // 1 MediaKeysInitializer and
+ // 1 MediaKeySystemAccessInitializer (navigator.requestMediaKeySystemAccess() use above),
+ // 1 MediaKeySystemAccessInitializer (isInitDataSupported() (via getSupportedInitDataType())))
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 1, 4, 'MediaKeys.create()');
+
+ var mediaKeySession = mediaKeys.createSession();
+ return mediaKeySession.generateRequest(initDataType, initData);
+ }).then(function() {
+ // Should be 1 MediaKeys + 1 MediaKeySession.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 2.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 6.
+ // (1 MediaKeys,
+ // 1 MediaKeysInitializer and
+ // 2 MediaKeySystemAccessInitializer,
+ // 1 ContentDecryptionModuleResultPromise and
+ // 1 MediaKeySession).
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 2, 6, 'MediaKeys.createSession()');
+
+ // Run gc(), should not affect MediaKeys object nor the
+ // session since we still have a reference to it.
+
+ // When enabling oilpan GC, the in-active
+ // ScriptPromiseResolvers will be destroyed.
+ return createGCPromise();
+ }).then(function(result) {
+ assert_equals(typeof mediaKeys.createSession, 'function');
+
+ // MediaKeys + MediaKeySessions should remain.
+ // In non-Oilpan, there is also something from createGCPromise().
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 2, 3, 'After gc()');
+
+ // Drop reference to the MediaKeys object and run gc()
+ // again. Object should be collected this time. Since
+ // MediaKeySessions remain alive as long as MediaKeys is
+ // around, it is possible that gc() checks the
+ // MediaKeySession object first, and doesn't collect it
+ // since MediaKeys hasn't been collected yet. Thus run gc()
+ // twice, to ensure that the unreferenced MediaKeySession
+ // object get collected.
+ mediaKeys = null;
+ return createGCPromise();
+ }).then(function(result) {
+ return createGCPromise();
+ }).then(function(result) {
+ // No MediaKeySessions should remain.
+ // In non-Oilpan, there is also something from createGCPromise().
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 0, 1, 'After final gc()');
+
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'MediaKeys lifetime with session');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeys.html b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeys.html
new file mode 100644
index 000000000..b8e79ac8b
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeys.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Test MediaKeys lifetime</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test requires Chromium specific content and is being disabled.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ async_test(function(test)
+ {
+ // Create a MediaKeys object and free immediately.
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(result) {
+ // Do nothing with the created object
+ }).then(function(result) {
+ // No way to verify that MediaKeys object is actually
+ // collected, but make sure it doesn't crash.
+ return createGCPromise();
+ }).then(function(result) {
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'Creating and destroying MediaKeys does not crash');
+
+ async_test(function(test)
+ {
+ var mediaKeys;
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys = result;
+ return createGCPromise();
+ }).then(function(result) {
+ // Check that the object still exists.
+ assert_equals(typeof mediaKeys.createSession, 'function');
+ mediaKeys = null;
+
+ // Now that the reference is dropped, it should be
+ // collected. No way to verify that it is actually
+ // collected, but make sure it doesn't crash.
+ return createGCPromise();
+ }).then(function(result) {
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'MediaKeys is not collected as long as we have a reference');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeysession-reference.html b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeysession-reference.html
new file mode 100644
index 000000000..4b8ad1b46
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeysession-reference.html
@@ -0,0 +1,157 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Test MediaKeySession lifetime without release()</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test requires Chromium specific content and is being disabled.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ // Since MediaKeySession (and MediaKeys) are ActiveDOMObjects,
+ // we can determine when they are garbage collected.
+ // MediaKeySessions remain as long as:
+ // JavaScript has a reference to it
+ // OR (MediaKeys is around
+ // AND the session has not received a close() event)
+
+ async_test(function(test)
+ {
+ var mediaKeys;
+ var mediaKeySession1;
+ var mediaKeySession2;
+ var mediaKeySession3;
+ var initDataType;
+ var initData;
+ var startingActiveDOMObjectCount = window.internals.activeDOMObjectCount(document);
+
+ function numActiveDOMObjectsCreated()
+ {
+ return window.internals.activeDOMObjectCount(document) - startingActiveDOMObjectCount;
+ }
+
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ initDataType = access.getConfiguration().initDataTypes[0];
+ initData = getInitData(initDataType);
+ return access.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys = result;
+ assert_equals(typeof mediaKeys.createSession, 'function');
+
+ // Verify MediaKeys is an ActiveDOMObject.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 1.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 4.
+ // (1 MediaKeys,
+ // 1 MediaKeysInitializer and
+ // 1 MediaKeySystemAccessInitializer (navigator.requestMediaKeySystemAccess() use above),
+ // 1 MediaKeySystemAccessInitializer (isInitDataSupported() (via getSupportedInitDataType())))
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 1, 4, 'MediaKeys.create()');
+
+ // Create 3 sessions.
+ mediaKeySession1 = mediaKeys.createSession();
+ return mediaKeySession1.generateRequest(initDataType, initData);
+ }).then(function() {
+ assert_true(mediaKeySession1.sessionId && mediaKeySession1.sessionId.length > 0);
+
+ // Should be 1 MediaKeys + 1 MediaKeySession.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 2.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 6.
+ // (1 MediaKeys,
+ // 1 MediaKeysInitializer and
+ // 2 MediaKeySystemAccessInitializer,
+ // 1 ContentDecryptionModuleResultPromise and
+ // 1 MediaKeySession).
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 2, 6, 'MediaKeys.createSession(1)');
+
+ mediaKeySession2 = mediaKeys.createSession();
+ return mediaKeySession2.generateRequest(initDataType, initData);
+ }).then(function() {
+ assert_true(mediaKeySession2.sessionId && mediaKeySession2.sessionId.length > 0);
+
+ // Should be 1 MediaKeys + 2 MediaKeySessions.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 3.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 8.
+ // (1 MediaKeys,
+ // 1 MediaKeysInitializer and
+ // 2 MediaKeySystemAccessInitializers,
+ // 2 ContentDecryptionModuleResultPromise and
+ // 2 MediaKeySession).
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 3, 8, 'mediaKeys.createSession(2)');
+
+ mediaKeySession3 = mediaKeys.createSession();
+ return mediaKeySession3.generateRequest(initDataType, initData);
+ }).then(function() {
+ assert_true(mediaKeySession3.sessionId && mediaKeySession3.sessionId.length > 0);
+
+ // Should be 1 MediaKeys + 3 MediaKeySessions.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 4.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 10.
+ // (1 MediaKeys,
+ // 1 MediaKeysInitializer and
+ // 2 MediaKeySystemAccessInitializers,
+ // 3 ContentDecryptionModuleResultPromise and
+ // 3 MediaKeySession).
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 4, 10, 'mediaKeys.createSession(3)');
+
+ // Run gc(). All sessions should remain as we have a
+ // reference to each one. However, running gc()
+ // asynchronously should free up the last PromiseResolver.
+ return createGCPromise();
+ }).then(function(result) {
+ // Only MediaKeys + 3 MediaKeySessions should remain.
+ // In non-Oilpan, there is also something from createGCPromise().
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 4, 5, 'After gc()');
+
+ // Now drop references to 2 of the sessions. Even though we
+ // don't have a reference, MediaKeys is still around (and
+ // the sessions aren't closed), so the objects won't be
+ // collected.
+ mediaKeySession1 = null;
+ mediaKeySession2 = null;
+ return createGCPromise();
+ }).then(function(result) {
+ return createGCPromise();
+ }).then(function(result) {
+ // MediaKeys + 3 MediaKeySessions should remain.
+ // In non-Oilpan, there is also something from createGCPromise().
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 4, 5, 'After second gc()');
+
+ // Now drop the reference to MediaKeys. It and the 2
+ // unreferenced sessions should be collected. Since
+ // MediaKeySessions remain alive as long as MediaKeys is
+ // around, it is possible that gc() checks one or both
+ // MediaKeySession objects first, and doesn't collect them
+ // since MediaKeys hasn't been collected yet. Thus run gc()
+ // twice, to ensure that the unreferenced MediaKeySession
+ // objects get collected.
+ mediaKeys = null;
+ return createGCPromise();
+ }).then(function(result) {
+ return createGCPromise();
+ }).then(function(result) {
+ // Only 1 MediaKeySessions should remain.
+ // In non-Oilpan, there is also something from createGCPromise().
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 1, 2, 'After mediaKeys = null');
+
+ // Drop the reference to the last session. It should get
+ // collected now since MediaKeys is gone.
+ mediaKeySession3 = null;
+ return createGCPromise();
+ }).then(function(result) {
+ // No MediaKeySessions should remain.
+ // In non-Oilpan, there is also something from createGCPromise().
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 0, 1, 'After final gc()');
+
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'MediaKeySession lifetime without release()');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeysession-release-noreference.html b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeysession-release-noreference.html
new file mode 100644
index 000000000..a962844a3
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeysession-release-noreference.html
@@ -0,0 +1,131 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Test MediaKeySession lifetime after release() without references</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test requires Chromium specific content and is being disabled.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ // Since MediaKeySession (and MediaKeys) are ActiveDOMObjects,
+ // we can determine when they are garbage collected.
+ // MediaKeySessions remain as long as:
+ // JavaScript has a reference to it
+ // OR (MediaKeys is around
+ // AND the session has not received a close() event)
+ async_test(function(test)
+ {
+ var initDataType;
+ var initData;
+ var startingActiveDOMObjectCount = window.internals.activeDOMObjectCount(document);
+
+ function numActiveDOMObjectsCreated()
+ {
+ return window.internals.activeDOMObjectCount(document) - startingActiveDOMObjectCount;
+ }
+
+ // Create 2 sessions.
+ var mediaKeys;
+ var mediaKeySession1;
+ var mediaKeySession2;
+
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ initDataType = access.getConfiguration().initDataTypes[0];
+ initData = getInitData(initDataType);
+ return access.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys = result;
+
+ // Verify MediaKeys is an ActiveDOMObject.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 1.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 4.
+ // (1 MediaKeys,
+ // 1 MediaKeysInitializer and
+ // 1 MediaKeySystemAccessInitializer (navigator.requestMediaKeySystemAccess() use above),
+ // 1 MediaKeySystemAccessInitializer (isInitDataSupported() (via getSupportedInitDataType())))
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 1, 4, 'MediaKeys.create()');
+
+ mediaKeySession1 = mediaKeys.createSession();
+ return mediaKeySession1.generateRequest(initDataType, initData);
+ }).then(function() {
+ assert_true(mediaKeySession1.sessionId && mediaKeySession1.sessionId.length > 0);
+
+ // Should be 1 MediaKeys + 1 MediaKeySession.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 2.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 6.
+ // (1 MediaKeys,
+ // 1 MediaKeysInitializer and
+ // 2 MediaKeySystemAccessInitializer,
+ // 1 ContentDecryptionModuleResultPromise and
+ // 1 MediaKeySession).
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 2, 6, 'MediaKeys.createSession(1)');
+
+ mediaKeySession2 = mediaKeys.createSession();
+ return mediaKeySession2.generateRequest(initDataType, initData);
+ }).then(function() {
+ assert_true(mediaKeySession2.sessionId && mediaKeySession2.sessionId.length > 0);
+
+ // Should be 1 MediaKeys + 2 MediaKeySessions.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 3.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 8.
+ // (1 MediaKeys,
+ // 1 MediaKeysInitializer and
+ // 2 MediaKeySystemAccessInitializers,
+ // 2 ContentDecryptionModuleResultPromise and
+ // 2 MediaKeySession).
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 3, 8, 'mediaKeys.createSession(2)');
+ }).then(function(result) {
+ // Run gc(). All sessions should remain as we have a
+ // reference to each one.
+ return createGCPromise();
+ }).then(function(result) {
+ // Should be just 1 MediaKeys + 2 MediaKeySessions.
+ // In non-Oilpan, there is also something from createGCPromise().
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 3, 4, 'After gc()');
+
+ // Close the sessions. Once the close() event is received,
+ // they should get garbage collected as there are no JS
+ // references to them.
+ var promise = mediaKeySession1.close();
+ mediaKeySession1 = null;
+ return promise;
+ }).then(function(result) {
+ // Give time so that the close event can be processed by
+ // MediaKeySession.
+ return delayToAllowEventProcessingPromise();
+ }).then(function(result) {
+ return createGCPromise();
+ }).then(function(result) {
+ // Only MediaKeys + mediaKeySession2 should remain.
+ // In non-Oilpan, there is also something from createGCPromise().
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 2, 3, 'mediaKeySession1 not collected');
+
+ var promise = mediaKeySession2.close();
+ mediaKeySession2 = null;
+ return promise;
+ }).then(function(result) {
+ // Provide time for the mediaKeySession2 close event to be
+ // handled.
+ return delayToAllowEventProcessingPromise();
+ }).then(function(result) {
+ return createGCPromise();
+ }).then(function(result) {
+ // Only MediaKeys should remain.
+ // In non-Oilpan, there is also something from createGCPromise().
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 1, 2, 'mediaKeySession2 not collected');
+
+ assert_not_equals(mediaKeys, null);
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'MediaKeySession lifetime after release() without references');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeysession-release.html b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeysession-release.html
new file mode 100644
index 000000000..626526761
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-mediakeysession-release.html
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>MediaKeySession lifetime after release()</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test requires Chromium specific content and is being disabled.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ // Since MediaKeySession (and MediaKeys) are ActiveDOMObjects,
+ // we can determine when they are garbage collected.
+ // MediaKeySessions remain as long as:
+ // JavaScript has a reference to it
+ // OR (MediaKeys is around
+ // AND the session has not received a close() event)
+ async_test(function(test)
+ {
+ var mediaKeys;
+ var mediaKeySession1;
+ var mediaKeySession2;
+ var initDataType;
+ var initData;
+ var startingActiveDOMObjectCount = window.internals.activeDOMObjectCount(document);
+
+ function numActiveDOMObjectsCreated()
+ {
+ return window.internals.activeDOMObjectCount(document) - startingActiveDOMObjectCount;
+ }
+
+ // Create 2 sessions.
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ initDataType = access.getConfiguration().initDataTypes[0];
+ initData = getInitData(initDataType);
+ return access.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys = result;
+
+ // Verify MediaKeys is an ActiveDOMObject.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 1.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 4.
+ // (1 MediaKeys,
+ // 1 MediaKeysInitializer and
+ // 1 MediaKeySystemAccessInitializer (navigator.requestMediaKeySystemAccess() use above),
+ // 1 MediaKeySystemAccessInitializer (isInitDataSupported() (via getSupportedInitDataType())))
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 1, 4, 'MediaKeys.create()');
+
+ mediaKeySession1 = mediaKeys.createSession();
+ return mediaKeySession1.generateRequest(initDataType, initData);
+ }).then(function() {
+ // Should be 1 MediaKeys + 1 MediaKeySession.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 2.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 6.
+ // (1 MediaKeys,
+ // 1 MediaKeysInitializer,
+ // 2 MediaKeySystemAccessInitializers,
+ // 1 ContentDecryptionModuleResultPromise and
+ // 1 MediaKeySession).
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 2, 6, 'MediaKeys.createSession(1)');
+
+ mediaKeySession2 = mediaKeys.createSession();
+ return mediaKeySession2.generateRequest(initDataType, initData);
+ }).then(function() {
+ // Should be 1 MediaKeys + 2 MediaKeySessions.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 3.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 8.
+ // (1 MediaKeys,
+ // 1 MediaKeysInitializer,
+ // 2 MediaKeySystemAccessInitializers,
+ // 2 ContentDecryptionModuleResultPromise and
+ // 2 MediaKeySession).
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 3, 8, 'mediaKeys.createSession(2)');
+
+ // Close the sessions. Once completed, only the JS
+ // reference to them keeps them around.
+ return mediaKeySession1.close();
+ }).then(function(result) {
+ return mediaKeySession2.close();
+ }).then(function(result) {
+ // Since both sessions have been closed, dropping the
+ // reference to them from JS will result in the session
+ // being garbage-collected.
+ // Should be 1 MediaKeys + 2 MediaKeySessions.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 3.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 10.
+ // (1 MediaKeys,
+ // 1 MediaKeysInitializer,
+ // 2 MediaKeySystemAccessInitializers,
+ // 4 ContentDecryptionModuleResultPromise and
+ // 2 MediaKeySession).
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 3, 10, 'after close');
+
+ mediaKeySession1 = null;
+ return createGCPromise();
+ }).then(function() {
+ // Only MediaKeys + mediaKeySession2 should remain.
+ // In non-Oilpan, there is also something from createGCPromise().
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 2, 3, 'mediaKeySession1 not collected');
+
+ mediaKeySession2 = null;
+ return createGCPromise();
+ }).then(function() {
+ // Only MediaKeys should remain.
+ // In non-Oilpan, there is also something from createGCPromise().
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 1, 2, 'mediaKeySession2 not collected');
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'MediaKeySession lifetime after release()');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-multiple-mediakeys.html b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-multiple-mediakeys.html
new file mode 100644
index 000000000..42638a069
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-multiple-mediakeys.html
@@ -0,0 +1,131 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Test multiple MediaKeys lifetimes</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test requires Chromium specific content and is being disabled.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ // For this test, create several MediaKeys and verify lifetime.
+ async_test(function(test)
+ {
+ var mediaKeys;
+ var startingActiveDOMObjectCount = window.internals.activeDOMObjectCount(document);
+
+ function numActiveDOMObjectsCreated()
+ {
+ return window.internals.activeDOMObjectCount(document) - startingActiveDOMObjectCount;
+ }
+
+ // Create a MediaKeys object. Returns a promise that resolves
+ // with the new MediaKeys object.
+ function createMediaKeys()
+ {
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ return mediaKeys;
+ });
+ }
+
+ // Create a few MediaKeys objects. Only keep a reference to the
+ // last one created.
+ createMediaKeys().then(function(result) {
+ // Should be 1 MediaKeys.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 1.
+ // In Oilpan, numActiveDOMObjectsCreated() <= 4.
+ // (1 MediaKeysInitializer,
+ // 1 MediaKeySystemAccessInitializer (navigator.requestMediaKeySystemAccess() use above),
+ // 1 MediaKeySystemAccessInitializer (isInitDataSupported() (via getSupportedInitDataType())) and
+ // 1 ContentDecryptionModuleResultPromise).
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 1, 4);
+
+ return createMediaKeys();
+ }).then(function(result) {
+ // Should be 2 MediaKeys.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 2.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 8.
+ // (2 MediaKeysInitializer,
+ // 4 MediaKeySystemAccessInitializer and
+ // 2 ContentDecryptionModuleResultPromise).
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 2, 8);
+
+ return createMediaKeys();
+ }).then(function(result) {
+ // Should be 3 MediaKeys.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 3.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 12.
+ // (3 MediaKeysInitializer,
+ // 6 MediaKeySystemAccessInitializer and
+ // 3 ContentDecryptionModuleResultPromise).
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 3, 12);
+
+ return createMediaKeys();
+ }).then(function(result) {
+ // Should be 4 MediaKeys.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 4.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 16.
+ // (4 MediaKeysInitializer,
+ // 8 MediaKeySystemAccessInitializer and
+ // 4 ContentDecryptionModuleResultPromise).
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 4, 16);
+
+ return createMediaKeys();
+ }).then(function(result) {
+ // Should be 5 MediaKeys.
+ // In non-Oilpan, numActiveDOMObjectsCreate() == 5.
+ // In Oilpan, numActiveDOMObjectsCreate() <= 20.
+ // (5 MediaKeysInitializer,
+ // 10 MediaKeySystemAccessInitializer and
+ // 5 ContentDecryptionModuleResultPromise).
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 5, 20);
+
+ // |mediaKeys| refers to the most recently created MediaKeys
+ // object.
+ mediaKeys = result;
+
+ // In order for the MediaKey objects to be garbage
+ // collected, it needs time to process any pending events.
+ return delayToAllowEventProcessingPromise();
+ }).then(function(result) {
+ // In non-Oilpan, numActiveDOMObjectsCreated() == 5
+ // (5 MediaKeySession objects).
+ // In Oilpan, numActiveDOMObjectsCreated() <= 23
+ // (5 MediaKeysInitializer,
+ // 12 MediaKeySystemAccessInitializer,
+ // 5 ContentDecryptionModuleResultPromise and
+ // 1 DOMTimer (in delayToAllowEventProcessingPromise))
+ assert_between_inclusive(numActiveDOMObjectsCreated(), 5, 23);
+
+ // As we only have a reference (|mediaKeys|) to the last
+ // created MediaKeys object, the other 4 MediaKeys objects
+ // are available to be garbage collected.
+ return createGCPromise();
+ }).then(function(result) {
+ // Should be 1 MediaKeys and DOMTimer.
+ assert_less_than_equal(numActiveDOMObjectsCreated(), 2);
+ assert_equals(typeof mediaKeys.createSession, 'function');
+
+ // Release the last MediaKeys object created.
+ mediaKeys = null;
+
+ // Run gc() again to reclaim the remaining MediaKeys object.
+ return createGCPromise();
+ }).then(function(result) {
+ // Should be just a DOMTimer.
+ assert_less_than_equal(numActiveDOMObjectsCreated(), 1);
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'Multiple MediaKeys lifetime');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-reload.html b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-reload.html
new file mode 100644
index 000000000..b2f8ffb1f
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/chromium_specific_disabled/encrypted-media-lifetime-reload.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Reloading during encrypted media playback</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test requires Chromium specific content and is being disabled.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <video id="testVideo"></video>
+ <div id="log"></div>
+ <script>
+ async_test(function(test)
+ {
+ var video = document.getElementById('testVideo');
+ var content = 'webm/test-encrypted.webm';
+ var mediaKeySession = null;
+ var hasSessionUpdateSucceeded = false;
+ var encryptedEventCount = 0;
+
+ var rawKey = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
+ 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);
+
+ function onEncrypted(event)
+ {
+ assert_equals(event.target, video);
+ assert_true(event instanceof window.MediaEncryptedEvent);
+ assert_equals(event.type, 'encrypted');
+
+ // The same decryption key is used by both the audio and
+ // the video streams so only create a session once. To
+ // avoid issues when comparing the expected.txt file
+ // (which logs the events in the order they occur), create
+ // the session on the second event. This also ensures we
+ // see both events.
+ if (++encryptedEventCount != 2)
+ return;
+
+ mediaKeySession = video.mediaKeys.createSession();
+ waitForEventAndRunStep('message', mediaKeySession, onMessage, test);
+ mediaKeySession.generateRequest(event.initDataType, event.initData).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }
+
+ function onMessage(event)
+ {
+ assert_true(event instanceof window.MediaKeyMessageEvent);
+ assert_equals(event.target, mediaKeySession);
+ assert_equals(event.type, 'message');
+ assert_equals(event.messageType, 'license-request');
+
+ var keyId = extractSingleKeyIdFromMessage(event.message);
+ var jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, rawKey)));
+ mediaKeySession.update(jwkSet).then(function(result) {
+ hasSessionUpdateSucceeded = true;
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }
+
+ function onPlaying(event)
+ {
+ // Not using waitForEventAndRunStep() to avoid too many
+ // EVENT(onTimeUpdate) logs.
+ video.addEventListener('timeupdate', onTimeUpdate, true);
+ }
+
+ function onTimeUpdate(event)
+ {
+ if (event.target.currentTime < 0.2 || !hasSessionUpdateSucceeded)
+ return;
+
+ // Reload the page to catch any possible teardown issues.
+ if (location.hash == '#x') {
+ test.done();
+ return;
+ }
+
+ location.hash += 'x';
+ location.reload();
+ }
+
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getConfigurationForFile(content)).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ waitForEventAndRunStep('encrypted', video, onEncrypted, test);
+ waitForEventAndRunStep('playing', video, onPlaying, test);
+ video.src = content;
+ return video.setMediaKeys(mediaKeys);
+ }).then(function(result) {
+ video.play();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'Reloading during encrypted media playback.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-check-init-data-type.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-check-init-data-type.html
new file mode 100644
index 000000000..f71cf48a8
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-check-init-data-type.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Test support of different initDataTypes.</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function checkInitDataType(initDataType)
+ {
+ return isInitDataTypeSupported(initDataType).then(function(result) {
+ // If |initDataType| is not supported, simply succeed.
+ if (!result)
+ return Promise.resolve('Not supported');
+
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfigurationForInitDataType(initDataType))
+ .then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var mediaKeySession = mediaKeys.createSession();
+ var initData = getInitData(initDataType);
+ return mediaKeySession.generateRequest(initDataType, initData);
+ });
+ });
+ }
+
+ promise_test(function()
+ {
+ return checkInitDataType('webm');
+ }, 'Clear key support for "webm".');
+
+ promise_test(function()
+ {
+ return checkInitDataType('cenc');
+ }, 'Clear key support for "cenc".');
+
+ promise_test(function()
+ {
+ return checkInitDataType('keyids');
+ }, 'Clear key support for "keyids".');
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-clear-key-invalid-license.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-clear-key-invalid-license.html
new file mode 100644
index 000000000..f145dfad7
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-clear-key-invalid-license.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Invalid Clear Key License.</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ async_test(function(test)
+ {
+ var initDataType;
+ var initData;
+ var invalidLicense = new Uint8Array(
+ [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77]);
+
+ function handleMessage(event) {
+ event.target.update(invalidLicense).then(function(event) {
+ assert_unreached('Error: update() succeeded unexpectedly.');
+ test.done();
+ }).catch(function(error) {
+ assert_equals(error.name, 'InvalidAccessError');
+ test.done();
+ });
+ }
+
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ initDataType = access.getConfiguration().initDataTypes[0];
+ initData = getInitData(initDataType);
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var keySession = mediaKeys.createSession();
+ keySession.addEventListener('message', handleMessage, false);
+ keySession.generateRequest(initDataType, initData);
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'Invalid Clear Key License.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-clearkey-update-non-ascii-input.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-clearkey-update-non-ascii-input.html
new file mode 100644
index 000000000..cf237a7da
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-clearkey-update-non-ascii-input.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Test Clear Key handling of non-ASCII responses for update().</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ // This test passes |response| to update() as a JSON Web Key Set.
+ // CDMs other than Clear Key won't expect |response| in this format.
+
+ async_test(function(test)
+ {
+ var initDataType;
+ var initData;
+ var mediaKeySession;
+
+ function processMessage(event)
+ {
+ // |jwkSet| includes some non-ASCII characters.
+ var jwkSet = '{"keys":[{'
+ + '"kty":"oct\uDC00\uD800",'
+ + '"k":"MDEyMzQ1Njc4OTAxMjM0NQ",'
+ + '"kid":"MDEyMzQ1Njc4OTAxMjM0NQ"'
+ + '\xff\xfe}]';
+ mediaKeySession.update(stringToUint8Array(jwkSet)).then(function() {
+ forceTestFailureFromPromise(test, 'Error: update() succeeded');
+ }, function(error) {
+ assert_equals(error.name, 'InvalidAccessError');
+ test.done();
+ });
+ }
+
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ initDataType = access.getConfiguration().initDataTypes[0];
+ initData = getInitData(initDataType);
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ mediaKeySession = mediaKeys.createSession();
+ waitForEventAndRunStep('message', mediaKeySession, processMessage, test);
+ return mediaKeySession.generateRequest(initDataType, initData);
+ });
+ }, 'Clear Key update() with non-ASCII response.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-events.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-events.html
new file mode 100644
index 000000000..a2a70f169
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-events.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Verify v2 events</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ // Currently Clear Key only generates aynchronous "message" and
+ // "keychange" events.
+ async_test(function(test)
+ {
+ var initDataType;
+ var initData;
+ var mediaKeySession;
+ var rawKey = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
+ 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);
+
+ function processMessage(event)
+ {
+ assert_true(event instanceof window.MediaKeyMessageEvent);
+ assert_equals(event.target, mediaKeySession);
+ assert_equals(event.type, 'message');
+ assert_equals(event.messageType, 'license-request');
+
+ var keyId = extractSingleKeyIdFromMessage(event.message);
+ var jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, rawKey)));
+
+ waitForEventAndRunStep('keystatuseschange', mediaKeySession, test.step_func(processKeyStatusesChange), test);
+
+ mediaKeySession.update(jwkSet).catch(test.step_func(function(error) {
+ forceTestFailureFromPromise(test, error);
+ }));
+ }
+
+ function processKeyStatusesChange(event)
+ {
+ assert_true(event instanceof Event);
+ assert_equals(event.target, mediaKeySession);
+ assert_equals(event.type, 'keystatuseschange');
+ test.done();
+ }
+
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ initDataType = access.getConfiguration().initDataTypes[0];
+ initData = getInitData(initDataType);
+ return access.createMediaKeys();
+ }).then(test.step_func(function(mediaKeys) {
+ mediaKeySession = mediaKeys.createSession();
+ waitForEventAndRunStep('message', mediaKeySession, test.step_func(processMessage), test);
+ return mediaKeySession.generateRequest(initDataType, initData);
+ })).catch(test.step_func(function(error) {
+ forceTestFailureFromPromise(test, error);
+ }));
+ }, 'Verify v2 events.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-generate-request-disallowed-input.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-generate-request-disallowed-input.html
new file mode 100644
index 000000000..53e5c95b7
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-generate-request-disallowed-input.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Test handling of invalid initData for generateRequest().</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ // Create a session and call generateRequest() with |initDataType|
+ // and |initData|. generateRequest() should fail with an
+ // InvalidAccessError. Returns a promise that resolves successfully
+ // if the error happened, rejects otherwise.
+ function test_session(initDataType, initData)
+ {
+ return isInitDataTypeSupported(initDataType).then(function(result) {
+ // If |initDataType| is not supported, simply succeed.
+ if (!result)
+ return Promise.resolve('Not supported');
+
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfigurationForInitDataType(initDataType)).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var mediaKeySession = mediaKeys.createSession();
+ return mediaKeySession.generateRequest(initDataType, initData);
+ }).then(function() {
+ assert_unreached('generateRequest() succeeded');
+ }, function(error) {
+ assert_equals(error.name, 'InvalidAccessError');
+ return Promise.resolve('success');
+ });
+ })
+ }
+
+ promise_test(function()
+ {
+ var initData = new Uint8Array(70000);
+ return test_session('webm', initData);
+ }, 'generateRequest() with webm initData longer than 64Kb characters.');
+
+ promise_test(function()
+ {
+ var initData = new Uint8Array(70000);
+ return test_session('cenc', initData);
+ }, 'generateRequest() with cenc initData longer than 64Kb characters.');
+
+ promise_test(function()
+ {
+ var initData = new Uint8Array(70000);
+ return test_session('keyids', initData);
+ }, 'generateRequest() with keyids initData longer than 64Kb characters.');
+
+ promise_test(function()
+ {
+ // Invalid 'pssh' box as the size specified is larger than what
+ // is provided.
+ var initData = new Uint8Array([
+ 0x00, 0x00, 0xff, 0xff, // size = huge
+ 0x70, 0x73, 0x73, 0x68, // 'pssh'
+ 0x00, // version = 0
+ 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, 0x00 // datasize
+ ]);
+ return test_session('cenc', initData);
+ }, 'generateRequest() with invalid pssh box size.');
+
+ promise_test(function()
+ {
+ // Invalid data as type = 'psss'.
+ var initData = new Uint8Array([
+ 0x00, 0x00, 0x00, 0x20, // size = 32
+ 0x70, 0x73, 0x73, 0x73, // 'psss'
+ 0x00, // version = 0
+ 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, 0x00 // datasize
+ ]);
+ return test_session('cenc', initData);
+ }, 'generateRequest() with non pssh data.');
+
+ promise_test(function()
+ {
+ // Valid key ID size must be at least 1 character for keyids.
+ var keyId = new Uint8Array(0);
+ var initData = stringToUint8Array(createKeyIDs(keyId));
+ return test_session('keyids', initData);
+ }, 'generateRequest() with too short key ID.');
+
+ promise_test(function()
+ {
+ // Valid key ID size must be less than 512 characters for keyids.
+ var keyId = new Uint8Array(600);
+ var initData = stringToUint8Array(createKeyIDs(keyId));
+ return test_session('keyids', initData);
+ }, 'generateRequest() with too long key ID.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-keystatuses-multiple-sessions.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-keystatuses-multiple-sessions.html
new file mode 100644
index 000000000..3ee4e8c54
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-keystatuses-multiple-sessions.html
@@ -0,0 +1,121 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Verify MediaKeySession.keyStatuses with multiple sessions</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ async_test(function(test)
+ {
+ var mediaKeySession1;
+ var mediaKeySession2;
+ var initDataType;
+ var initData;
+
+ // Even though key ids are uint8, using printable values so that
+ // they can be verified easily.
+ var key1 = stringToUint8Array('123');
+ var key2 = stringToUint8Array('4567890');
+ var rawKey1 = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
+ 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);
+ var rawKey2 = new Uint8Array([0x3c, 0xae, 0xe4, 0xfc, 0x2a, 0x12, 0xef, 0x68,
+ 0x7b, 0xd2, 0x14, 0x68, 0xf1, 0x62, 0xdd, 0xeb]);
+
+ function processMessage1(event)
+ {
+ // This should only be called for session1.
+ assert_equals(event.target, mediaKeySession1);
+
+ // No keys added yet.
+ verifyKeyStatuses(mediaKeySession1.keyStatuses, { expected: [], unexpected: [key1, key2] });
+
+ // Add key1 to session1.
+ var jwkSet = stringToUint8Array(createJWKSet(createJWK(key1, rawKey1)));
+ mediaKeySession1.update(jwkSet).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }
+
+ function processKeyStatusesChange1(event)
+ {
+ // This should only be called for session1.
+ assert_equals(event.target, mediaKeySession1);
+
+ // Check that keyStatuses contains the expected key1 only.
+ dumpKeyStatuses(mediaKeySession1.keyStatuses);
+ verifyKeyStatuses(mediaKeySession1.keyStatuses, { expected: [key1], unexpected: [key2] });
+
+ // Now trigger a message event on session2.
+ mediaKeySession2.generateRequest(initDataType, initData).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }
+
+ function processMessage2(event)
+ {
+ // This should only be called for session2.
+ assert_equals(event.target, mediaKeySession2);
+
+ // session2 has no keys added yet.
+ verifyKeyStatuses(mediaKeySession2.keyStatuses, { expected: [], unexpected: [key1, key2] });
+
+ // session1 should still have 1 key.
+ verifyKeyStatuses(mediaKeySession1.keyStatuses, { expected: [key1], unexpected: [key2] });
+
+ // Add key2 to session2.
+ var jwkSet = stringToUint8Array(createJWKSet(createJWK(key2, rawKey2)));
+ mediaKeySession2.update(jwkSet).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }
+
+ function processKeyStatusesChange2(event)
+ {
+ // This should only be called for session2.
+ assert_equals(event.target, mediaKeySession2);
+
+ // Check that keyStatuses contains the expected key2 only.
+ dumpKeyStatuses(mediaKeySession2.keyStatuses);
+ verifyKeyStatuses(mediaKeySession2.keyStatuses, { expected: [key2], unexpected: [key1] });
+
+ // session1 should still have 1 key.
+ verifyKeyStatuses(mediaKeySession1.keyStatuses, { expected: [key1], unexpected: [key2] });
+
+ test.done();
+ }
+
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ initDataType = access.getConfiguration().initDataTypes[0];
+ initData = getInitData(initDataType);
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ mediaKeySession1 = mediaKeys.createSession();
+ mediaKeySession2 = mediaKeys.createSession();
+
+ // There should be no keys defined on either session.
+ verifyKeyStatuses(mediaKeySession1.keyStatuses, { expected: [], unexpected: [key1, key2] });
+ verifyKeyStatuses(mediaKeySession2.keyStatuses, { expected: [], unexpected: [key1, key2] });
+
+ // Bind all the event handlers now.
+ waitForEventAndRunStep('message', mediaKeySession1, processMessage1, test);
+ waitForEventAndRunStep('message', mediaKeySession2, processMessage2, test);
+ waitForEventAndRunStep('keystatuseschange', mediaKeySession1, processKeyStatusesChange1, test);
+ waitForEventAndRunStep('keystatuseschange', mediaKeySession2, processKeyStatusesChange2, test);
+
+ // Generate a request on session1.
+ return mediaKeySession1.generateRequest(initDataType, initData);
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'Verify MediaKeySession.keyStatuses with multiple sessions.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-keystatuses-multiple-updates.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-keystatuses-multiple-updates.html
new file mode 100644
index 000000000..809045d99
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-keystatuses-multiple-updates.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Verify MediaKeySession.keyStatuses with multiple updates</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ async_test(function(test)
+ {
+ var initDataType;
+ var initData;
+ var mediaKeySession;
+ var firstEvent;
+
+ // Even though key ids are uint8, using printable values so that
+ // they can be verified easily.
+ var key1 = stringToUint8Array('123');
+ var key2 = stringToUint8Array('4567890');
+ var rawKey1 = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
+ 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);
+ var rawKey2 = new Uint8Array([0x3c, 0xae, 0xe4, 0xfc, 0x2a, 0x12, 0xef, 0x68,
+ 0x7b, 0xd2, 0x14, 0x68, 0xf1, 0x62, 0xdd, 0xeb]);
+
+ function processMessage(event)
+ {
+ // No keys added yet.
+ verifyKeyStatuses(mediaKeySession.keyStatuses, { expected: [], unexpected: [key1, key2] });
+
+ // Add key1 to the session.
+ firstEvent = true;
+ var jwkSet = stringToUint8Array(createJWKSet(createJWK(key1, rawKey1)));
+ mediaKeySession.update(jwkSet).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }
+
+ function processKeyStatusesChange(event)
+ {
+ if (firstEvent) {
+ // Verify that the session only contains key1.
+ dumpKeyStatuses(mediaKeySession.keyStatuses);
+ verifyKeyStatuses(mediaKeySession.keyStatuses, { expected: [key1], unexpected: [key2] });
+
+ // Now add key2 to the session.
+ firstEvent = false;
+ var jwkSet = stringToUint8Array(createJWKSet(createJWK(key2, rawKey2)));
+ mediaKeySession.update(jwkSet).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ } else {
+ // Verify that the session now contains key1 and key2.
+ dumpKeyStatuses(mediaKeySession.keyStatuses);
+ verifyKeyStatuses(mediaKeySession.keyStatuses, { expected: [key1, key2] });
+
+ test.done();
+ }
+ }
+
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ initDataType = access.getConfiguration().initDataTypes[0];
+ initData = getInitData(initDataType);
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ mediaKeySession = mediaKeys.createSession();
+
+ // There should be no keys defined yet.
+ assert_equals(mediaKeySession.keyStatuses.size, 0);
+
+ waitForEventAndRunStep('message', mediaKeySession, processMessage, test);
+ waitForEventAndRunStep('keystatuseschange', mediaKeySession, processKeyStatusesChange, test);
+
+ return mediaKeySession.generateRequest(initDataType, initData);
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'Verify MediaKeySession.keyStatuses with multiple updates.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-keystatuses.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-keystatuses.html
new file mode 100644
index 000000000..043bc1322
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-keystatuses.html
@@ -0,0 +1,174 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Verify MediaKeySession.keyStatuses</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ async_test(function(test)
+ {
+ var mediaKeySession;
+ var initDataType;
+ var initData;
+ var closed = false;
+
+ // Even though key ids are uint8, using printable values so that
+ // they can be verified easily.
+ var key1String = '123';
+ var key2String = '4567890';
+ var key1 = stringToUint8Array(key1String);
+ var key2 = stringToUint8Array(key2String);
+ var rawKey1 = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
+ 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);
+ var rawKey2 = new Uint8Array([0x3c, 0xae, 0xe4, 0xfc, 0x2a, 0x12, 0xef, 0x68,
+ 0x7b, 0xd2, 0x14, 0x68, 0xf1, 0x62, 0xdd, 0xeb]);
+
+ function processMessage(event)
+ {
+ // No keys added yet.
+ assert_equals(mediaKeySession.keyStatuses.size, 0);
+
+ waitForEventAndRunStep('keystatuseschange', mediaKeySession, processKeyStatusesChange, test);
+
+ var jwkSet = stringToUint8Array(createJWKSet(createJWK(key1, rawKey1), createJWK(key2, rawKey2)));
+ mediaKeySession.update(jwkSet).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }
+
+ function checkKeyStatusFor2Keys()
+ {
+ // Two keys added, so both should show up in |keyStatuses|.
+ assert_equals(mediaKeySession.keyStatuses.size, 2);
+ dumpKeyStatuses(mediaKeySession.keyStatuses);
+
+ // Check |keyStatuses| for 2 entries.
+ var result = [];
+ for (let [keyId, status] of mediaKeySession.keyStatuses) {
+ result.push({ key: arrayBufferAsString(keyId), value: status });
+ }
+ assert_object_equals(result,
+ [{ key: key1String, value: 'usable'}, { key: key2String, value: 'usable'}],
+ 'keyStatuses fails');
+
+ // |keyStatuses| must contain both keys.
+ result = [];
+ for (var key of mediaKeySession.keyStatuses.keys()) {
+ result.push(arrayBufferAsString(key));
+ }
+ assert_array_equals(result,
+ [key1String, key2String],
+ 'keyStatuses.keys() fails');
+
+ // Both values in |mediaKeySession| should be 'usable'.
+ result = [];
+ for (var value of mediaKeySession.keyStatuses.values()) {
+ result.push(value);
+ }
+ assert_array_equals(result,
+ ['usable', 'usable'],
+ 'keyStatuses.values() fails');
+
+ // Check |keyStatuses.entries()|.
+ result = [];
+ for (var entry of mediaKeySession.keyStatuses.entries()) {
+ result.push({ key: arrayBufferAsString(entry[0]), value: entry[1] });
+ }
+ assert_object_equals(result,
+ [{ key: key1String, value: 'usable'}, { key: key2String, value: 'usable'}],
+ 'keyStatuses.entries() fails');
+
+ // forEach() should return both entries.
+ result = [];
+ mediaKeySession.keyStatuses.forEach(function(status, keyId) {
+ result.push({ key: arrayBufferAsString(keyId), value: status });
+ });
+ assert_object_equals(result,
+ [{ key: key1String, value: 'usable'}, { key: key2String, value: 'usable'}],
+ 'keyStatuses.forEach() fails');
+
+ // has() and get() should return the expected values.
+ assert_true(mediaKeySession.keyStatuses.has(key1));
+ assert_true(mediaKeySession.keyStatuses.has(key2));
+ assert_equals(mediaKeySession.keyStatuses.get(key1), 'usable');
+ assert_equals(mediaKeySession.keyStatuses.get(key2), 'usable');
+
+ // Try some invalid keyIds.
+ var invalid1 = key1.subarray(0, key1.length - 1);
+ assert_false(mediaKeySession.keyStatuses.has(invalid1));
+ assert_equals(mediaKeySession.keyStatuses.get(invalid1), undefined);
+
+ var invalid2 = key1.subarray(1);
+ assert_false(mediaKeySession.keyStatuses.has(invalid2));
+ assert_equals(mediaKeySession.keyStatuses.get(invalid2), undefined);
+
+ var invalid3 = new Uint8Array(key1);
+ invalid3[0] += 1;
+ assert_false(mediaKeySession.keyStatuses.has(invalid3));
+ assert_equals(mediaKeySession.keyStatuses.get(invalid3), undefined);
+
+ var invalid4 = new Uint8Array(key1);
+ invalid4[invalid4.length - 1] -= 1;
+ assert_false(mediaKeySession.keyStatuses.has(invalid4));
+ assert_equals(mediaKeySession.keyStatuses.get(invalid4), undefined);
+
+ var invalid5 = new Uint8Array(key1.length + 1);
+ invalid5.set(key1, 1); // First element will be 0.
+ assert_false(mediaKeySession.keyStatuses.has(invalid5));
+ assert_equals(mediaKeySession.keyStatuses.get(invalid5), undefined);
+
+ var invalid6 = new Uint8Array(key1.length + 1);
+ invalid6.set(key1, 0); // Last element will be 0.
+ assert_false(mediaKeySession.keyStatuses.has(invalid6));
+ assert_equals(mediaKeySession.keyStatuses.get(invalid6), undefined);
+ }
+
+ function processKeyStatusesChange(event)
+ {
+ if ( !closed )
+ {
+ // The first keystatuseschange (caused by update())
+ // should include both keys.
+ checkKeyStatusFor2Keys();
+
+ mediaKeySession.close().catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ closed = true;
+ }
+ else
+ {
+ // The second keystatuseschange (caused by close())
+ // should not have any keys.
+ assert_equals(mediaKeySession.keyStatuses.size, 0);
+ test.done();
+ }
+ }
+
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ initDataType = access.getConfiguration().initDataTypes[0];
+ initData = getInitData(initDataType);
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ mediaKeySession = mediaKeys.createSession();
+
+ // There should be no keys defined yet.
+ assert_equals(mediaKeySession.keyStatuses.size, 0);
+
+ waitForEventAndRunStep('message', mediaKeySession, processMessage, test);
+ return mediaKeySession.generateRequest(initDataType, initData);
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'Verify MediaKeySession.keyStatuses.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-not-callable-after-createsession.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-not-callable-after-createsession.html
new file mode 100644
index 000000000..9b92c6905
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-not-callable-after-createsession.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Test MediaKeySession not callable immediately after CreateSession().</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ // After creation, the MediaKeySession object is not
+ // callable, and we should get a InvalidStateError.
+
+ promise_test(function()
+ {
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var mediaKeySession = mediaKeys.createSession();
+
+ var arbitraryResponse = new Uint8Array([0x00, 0x11]);
+ return mediaKeySession.update(arbitraryResponse).then(function(result) {
+ assert_unreached('update() succeeded unexpectedly.');
+ }).catch(function(error) {
+ assert_equals(error.name, 'InvalidStateError');
+ });
+ });
+ }, 'Update() immediately after CreateSession().');
+
+ promise_test(function()
+ {
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var mediaKeySession = mediaKeys.createSession();
+
+ return mediaKeySession.close().then(function(result) {
+ assert_unreached('close() succeeded unexpectedly.');
+ }).catch(function(error) {
+ assert_equals(error.name, 'InvalidStateError');
+ });
+ });
+ }, 'Close() immediately after CreateSession().');
+
+ promise_test(function()
+ {
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var mediaKeySession = mediaKeys.createSession();
+
+ return mediaKeySession.remove().then(function(result) {
+ assert_unreached('remove() succeeded unexpectedly.');
+ }).catch(function(error) {
+ assert_equals(error.name, 'InvalidStateError');
+ });
+ });
+ }, 'Remove() immediately after CreateSession().');
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-onencrypted.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-onencrypted.html
new file mode 100644
index 000000000..ad408f0f3
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-onencrypted.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>onencrypted</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <video id="testVideo" controls></video>
+ <div id="log"></div>
+ <script>
+ var expectedInitData = stringToUint8Array('0123456789012345');
+
+ // Will get 2 identical events, one for audio, one for video.
+ var expectedEvents = 2;
+
+ async_test(function(test)
+ {
+ var video = document.getElementById('testVideo');
+ var content = 'webm/test-encrypted.webm';
+
+ var onEncrypted = function(event)
+ {
+ assert_equals(event.target, video);
+ assert_true(event instanceof window.MediaEncryptedEvent);
+ assert_equals(event.type, 'encrypted');
+ assert_equals(event.initDataType, 'webm');
+ assert_array_equals(new Uint8Array(event.initData), expectedInitData);
+
+ if (--expectedEvents == 0)
+ test.done();
+ };
+
+ waitForEventAndRunStep('encrypted', video, onEncrypted, test);
+ video.src = content;
+ }, 'encrypted fired on encrypted media file.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-encrypted-and-clear-sources.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-encrypted-and-clear-sources.html
new file mode 100644
index 000000000..495ba4188
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-encrypted-and-clear-sources.html
@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Multiple playbacks alternating between encrypted and clear sources.</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <video id="testVideo"></video>
+ <div id="log"></div>
+ <script>
+ async_test(function(test)
+ {
+ var video = document.getElementById('testVideo');
+ var isUpdatePromiseResolved = false;
+ var encryptedEventCount = 0;
+ var playbackCount = 0;
+
+ // Content to be played. These files must be the same format.
+ var encryptedContent = 'webm/test-encrypted.webm';
+ var unencryptedContent = 'webm/test.webm';
+
+ var rawKey = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
+ 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);
+
+ function onEncrypted(event)
+ {
+ assert_equals(event.target, video);
+ assert_true(event instanceof window.MediaEncryptedEvent);
+ assert_equals(event.type, 'encrypted');
+
+ // The same decryption key is used by both the audio and
+ // the video streams so only create a session once. To
+ // avoid issues when comparing the expected.txt file
+ // (which logs the events in the order they occur), create
+ // the session on the second event. This also ensures we
+ // see both events.
+ if (++encryptedEventCount != 2)
+ return;
+
+ assert_false(video.mediaKeys === null, "video.mediaKeys is null.");
+ var mediaKeySession = video.mediaKeys.createSession();
+ waitForEventAndRunStep('message', mediaKeySession, onMessage, test);
+ mediaKeySession.generateRequest(event.initDataType, event.initData).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }
+
+ function onMessage(event)
+ {
+ assert_true(event instanceof window.MediaKeyMessageEvent);
+ assert_equals(event.type, 'message');
+ assert_equals(event.messageType, 'license-request');
+
+ var keyId = extractSingleKeyIdFromMessage(event.message);
+ var jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, rawKey)));
+ event.target.update(jwkSet).then(function(result) {
+ isUpdatePromiseResolved = true;
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }
+
+ function onPlaying(event)
+ {
+ // Not using waitForEventAndRunStep() to avoid too many
+ // EVENT(onTimeUpdate) logs.
+ video.addEventListener('timeupdate', onTimeUpdate, true);
+ }
+
+ function onTimeUpdate(event)
+ {
+ if (event.target.currentTime < 0.2 || !isUpdatePromiseResolved)
+ return;
+
+ video.removeEventListener('timeupdate', onTimeUpdate, true);
+
+ if (playbackCount > 2) {
+ test.done();
+ return;
+ }
+
+ playbackCount++;
+
+ resetSrc().then(function(){
+ startPlayback();
+ });
+ }
+
+ function resetSrc() {
+ encryptedEventCount = 0;
+ video.removeAttribute('src');
+ video.load();
+ return video.setMediaKeys(null);
+ }
+
+ function startPlayback() {
+ // Alternate between encrypted and unencrypted files.
+ if (playbackCount % 2) {
+ // Unencrypted files don't require MediaKeys.
+ video.src = unencryptedContent;
+ video.play();
+ return;
+ }
+
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getConfigurationForFile(encryptedContent)).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ return video.setMediaKeys(mediaKeys);
+ }).then(function(result) {
+ video.src = encryptedContent;
+ assert_false(video.mediaKeys === null, "video.mediaKeys is null.");
+ video.play();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }
+
+ waitForEventAndRunStep('playing', video, onPlaying, test);
+ waitForEventAndRunStep('encrypted', video, onEncrypted, test);
+ startPlayback();
+ }, 'Multiple playbacks alternating between encrypted and clear sources.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-multiple-sessions.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-multiple-sessions.html
new file mode 100644
index 000000000..8bf94e13c
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-multiple-sessions.html
@@ -0,0 +1,143 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Clear Key Playback with Multiple Sessions</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <video id="testVideo"></video>
+ <div id="log"></div>
+ <script>
+ async_test(function(test)
+ {
+ var video = document.getElementById('testVideo');
+ var content = 'webm/test-encrypted-different-av-keys.webm';
+ var audioMediaKeySession = null;
+ var videoMediaKeySession = null;
+ var audioInitDataType = null;
+ var videoInitDataType = null;
+ var audioInitData = null;
+ var videoInitData = null;
+ var audioKeyProvided = false;
+ var videoKeyProvided = false;
+
+ // The 2 streams use different key ids and different keys.
+ var audioKeyId = '1234567890123456';
+ var audioKey = new Uint8Array([0x30, 0x30, 0x62, 0xF1, 0x68, 0x14, 0xD2, 0x7B,
+ 0x68, 0xEF, 0x12, 0x2A, 0xFC, 0xE4, 0xAE, 0x0A]);
+ var videoKeyId = '0123456789012345';
+ var videoKey = new Uint8Array([0x7A, 0x7A, 0x62, 0xF1, 0x68, 0x14, 0xD2, 0x7B,
+ 0x68, 0xEF, 0x12, 0x2A, 0xFC, 0xE4, 0xAE, 0x0A]);
+
+ function onEncrypted(event)
+ {
+ var keyId = String.fromCharCode.apply(null, new Uint8Array(event.initData));
+
+ // To avoid issues when comparing the expected.txt file
+ // (which logs the events in the order they occur), save
+ // the initData and make the calls to generateRequest()
+ // only after both "onencrypted" events are received.
+ // This prevents a "message" event from occurring before
+ // both "onencrypted" events are received.
+ var mediaKeySession = video.mediaKeys.createSession();
+ if (keyId == videoKeyId) {
+ assert_equals(videoMediaKeySession, null);
+ videoMediaKeySession = mediaKeySession;
+ videoInitDataType = event.initDataType;
+ videoInitData = event.initData;
+ // Return if audio "onencrypted" event not yet received.
+ if (audioMediaKeySession == null)
+ return;
+ } else {
+ assert_equals(keyId, audioKeyId);
+ assert_equals(audioMediaKeySession, null);
+ audioMediaKeySession = mediaKeySession;
+ audioInitDataType = event.initDataType;
+ audioInitData = event.initData;
+ // Return if video "onencrypted" event not yet received.
+ if (videoMediaKeySession == null)
+ return;
+ }
+
+ // Both sessions have been created.
+ assert_not_equals(videoMediaKeySession, null);
+ assert_not_equals(audioMediaKeySession, null);
+
+ var promises = [];
+ waitForEventAndRunStep('message', videoMediaKeySession, onMessage, test);
+ promises.push(videoMediaKeySession.generateRequest(videoInitDataType, videoInitData));
+
+ waitForEventAndRunStep('message', audioMediaKeySession, onMessage, test);
+ promises.push(audioMediaKeySession.generateRequest(audioInitDataType, audioInitData));
+
+ Promise.all(promises).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }
+
+ function onMessage(event)
+ {
+ assert_equals(event.messageType, 'license-request');
+ var keyId = extractSingleKeyIdFromMessage(event.message);
+ if (event.target == videoMediaKeySession) {
+ assert_equals(String.fromCharCode.apply(null, keyId), videoKeyId);
+ var jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, videoKey)));
+ videoMediaKeySession.update(jwkSet).then(function(result) {
+ videoKeyProvided = true;
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ } else {
+ assert_equals(event.target, audioMediaKeySession);
+ assert_equals(String.fromCharCode.apply(null, keyId), audioKeyId);
+ var jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, audioKey)));
+ audioMediaKeySession.update(jwkSet).then(function(result) {
+ audioKeyProvided = true;
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }
+ }
+
+ function onPlaying(event)
+ {
+ // Video should not start playing until both keys have been
+ // provided.
+ assert_true(videoKeyProvided);
+ assert_true(audioKeyProvided);
+
+ // Not using waitForEventAndRunStep() to avoid too many
+ // EVENT(onTimeUpdate) logs.
+ video.addEventListener('timeupdate', onTimeUpdate, true);
+ }
+
+ function onTimeUpdate(event)
+ {
+ if (event.target.currentTime < 0.2)
+ return;
+
+ test.done();
+ }
+
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getConfigurationForFile(content)).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ waitForEventAndRunStep('encrypted', video, onEncrypted, test);
+ waitForEventAndRunStep('playing', video, onPlaying, test);
+ video.src = content;
+ return video.setMediaKeys(mediaKeys);
+ }).then(function(result) {
+ video.play();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'Playback using Clear Key key system with multiple sessions.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-setmediakeys-after-src.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-setmediakeys-after-src.html
new file mode 100644
index 000000000..2a8cac486
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-setmediakeys-after-src.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Clear Key Playback</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <video id="testVideo"></video>
+ <div id="log"></div>
+ <script>
+ async_test(function(test)
+ {
+ var video = document.getElementById('testVideo');
+ var content = 'webm/test-encrypted.webm';
+ var isUpdatePromiseResolved = false;
+ var encryptedEventCount = 0;
+
+ var rawKey = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
+ 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);
+
+ function onEncrypted(event)
+ {
+ assert_equals(event.target, video);
+ assert_true(event instanceof window.MediaEncryptedEvent);
+ assert_equals(event.type, 'encrypted');
+
+ // The same decryption key is used by both the audio and
+ // the video streams so only create a session once. To
+ // avoid issues when comparing the expected.txt file
+ // (which logs the events in the order they occur), create
+ // the session on the second event. This also ensures we
+ // see both events.
+ if (++encryptedEventCount != 2)
+ return;
+
+ var mediaKeySession = video.mediaKeys.createSession();
+ waitForEventAndRunStep('message', mediaKeySession, onMessage, test);
+ mediaKeySession.generateRequest(event.initDataType, event.initData).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }
+
+ function onMessage(event)
+ {
+ assert_true(event instanceof window.MediaKeyMessageEvent);
+ assert_equals(event.type, 'message');
+ assert_equals(event.messageType, 'license-request');
+
+ var keyId = extractSingleKeyIdFromMessage(event.message);
+ var jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, rawKey)));
+ event.target.update(jwkSet).then(function(result) {
+ isUpdatePromiseResolved = true;
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }
+
+ function onPlaying(event)
+ {
+ // Not using waitForEventAndRunStep() to avoid too many
+ // EVENT(onTimeUpdate) logs.
+ video.addEventListener('timeupdate', onTimeUpdate, true);
+ }
+
+ function onTimeUpdate(event)
+ {
+ if (event.target.currentTime < 0.2 || !isUpdatePromiseResolved)
+ return;
+
+ test.done();
+ }
+
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getConfigurationForFile(content)).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+
+ waitForEventAndRunStep('encrypted', video, onEncrypted, test);
+ waitForEventAndRunStep('playing', video, onPlaying, test);
+
+ video.src = content;
+ return video.setMediaKeys(mediaKeys);
+ }).then(function(result) {
+ video.play();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'Playback using Clear Key key system, calling setMediaKeys() after setting src attribute.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-setmediakeys-before-src.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-setmediakeys-before-src.html
new file mode 100644
index 000000000..84100570c
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-setmediakeys-before-src.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Clear Key Playback</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <video id="testVideo"></video>
+ <div id="log"></div>
+ <script>
+ async_test(function(test)
+ {
+ var video = document.getElementById('testVideo');
+ var content = 'webm/test-encrypted.webm';
+ var isUpdatePromiseResolved = false;
+ var encryptedEventCount = 0;
+
+ var rawKey = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
+ 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);
+
+ function onEncrypted(event)
+ {
+ assert_equals(event.target, video);
+ assert_true(event instanceof window.MediaEncryptedEvent);
+ assert_equals(event.type, 'encrypted');
+
+ // The same decryption key is used by both the audio and
+ // the video streams so only create a session once. To
+ // avoid issues when comparing the expected.txt file
+ // (which logs the events in the order they occur), create
+ // the session on the second event. This also ensures we
+ // see both events.
+ if (++encryptedEventCount != 2)
+ return;
+
+ var mediaKeySession = video.mediaKeys.createSession();
+ waitForEventAndRunStep('message', mediaKeySession, onMessage, test);
+ mediaKeySession.generateRequest(event.initDataType, event.initData).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }
+
+ function onMessage(event)
+ {
+ assert_true(event instanceof window.MediaKeyMessageEvent);
+ assert_equals(event.type, 'message');
+ assert_equals(event.messageType, 'license-request');
+
+ var keyId = extractSingleKeyIdFromMessage(event.message);
+ var jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, rawKey)));
+ event.target.update(jwkSet).then(function(result) {
+ isUpdatePromiseResolved = true;
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }
+
+ function onPlaying(event)
+ {
+ // Not using waitForEventAndRunStep() to avoid too many
+ // EVENT(onTimeUpdate) logs.
+ video.addEventListener('timeupdate', onTimeUpdate, true);
+ }
+
+ function onTimeUpdate(event)
+ {
+ if (event.target.currentTime < 0.2 || !isUpdatePromiseResolved)
+ return;
+
+ test.done();
+ }
+
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getConfigurationForFile(content)).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+
+ waitForEventAndRunStep('encrypted', video, onEncrypted, test);
+ waitForEventAndRunStep('playing', video, onPlaying, test);
+
+ return video.setMediaKeys(mediaKeys);
+ }).then(function(result) {
+ video.src = content;
+ video.play();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'Playback using Clear Key key system, calling setMediaKeys() before setting src attribute.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-two-videos.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-two-videos.html
new file mode 100644
index 000000000..0bdc7757b
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-playback-two-videos.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Clear Key Play Two Videos At Same Time</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <video id="testVideo"></video>
+ <video id="secondVideo"></video>
+ <div id="log"></div>
+ <script>
+ // As this code doesn't wait for the 'message' event to simplify
+ // the code, specify the key ID and key used by the encrypted
+ // content.
+ var keyId = stringToUint8Array('0123456789012345');
+ var rawKey = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
+ 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);
+ var content = 'webm/test-encrypted.webm';
+
+ promise_test(function(test)
+ {
+ var promises = [
+ play_video_as_promise(document.getElementById('testVideo'), content),
+ play_video_as_promise(document.getElementById('secondVideo'), content)
+ ];
+ return Promise.all(promises);
+ }, 'Play two videos at the same time.');
+
+ function play_video_as_promise(video, content)
+ {
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getConfigurationForFile(content)).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ return video.setMediaKeys(mediaKeys);
+ }).then(function(result) {
+ video.src = content;
+ video.play();
+ return wait_for_encrypted_message(video);
+ }).then(function(result) {
+ return wait_for_timeupdate_message(video);
+ });
+ };
+
+ function wait_for_encrypted_message(video)
+ {
+ var encryptedEventCount = 0;
+ return new Promise(function(resolve) {
+ video.addEventListener('encrypted', function listener(e) {
+ // The same decryption key is used by both the audio
+ // and the video streams so only create a session once.
+ // Create the session on the second event. This also
+ // ensures we see both events.
+ if (++encryptedEventCount != 2)
+ return;
+ video.removeEventListener('encrypted', listener);
+
+ var mediaKeySession = video.mediaKeys.createSession();
+ mediaKeySession.generateRequest(e.initDataType, e.initData).then(function(result) {
+ // Don't bother waiting for the 'message' event.
+ // Just call update() since we know the keyId
+ // needed.
+ var jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, rawKey)));
+ return mediaKeySession.update(jwkSet);
+ }).then(function(result) {
+ resolve(result);
+ });
+ });
+ });
+ };
+
+ function wait_for_timeupdate_message(video)
+ {
+ return new Promise(function(resolve) {
+ video.addEventListener('timeupdate', function listener(e) {
+ if (e.target.currentTime < 0.2)
+ return;
+ video.removeEventListener('timeupdate', listener);
+ resolve(e);
+ });
+ });
+ };
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-requestmediakeysystemaccess.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-requestmediakeysystemaccess.html
new file mode 100644
index 000000000..456f37f57
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-requestmediakeysystemaccess.html
@@ -0,0 +1,322 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Test navigator.requestMediaKeySystemAccess()</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ function expect_error(keySystem, configurations, expectedError, testName) {
+ promise_test(function(test) {
+ return navigator.requestMediaKeySystemAccess(keySystem, configurations).then(function(a) {
+ assert_unreached('Unexpected requestMediaKeySystemAccess() success.');
+ }, function(e) {
+ assert_equals(e.name, expectedError);
+ });
+ }, testName);
+ }
+
+ function assert_subset(actual, expected, path) {
+ if (typeof expected == 'string') {
+ assert_equals(actual, expected, path);
+ } else {
+ if (expected.hasOwnProperty('length'))
+ assert_equals(actual.length, expected.length, path + '.length');
+ for (property in expected)
+ assert_subset(actual[property], expected[property], path + '.' + property);
+ }
+ }
+
+ function expect_config(keySystem, configurations, expectedConfiguration, testName) {
+ promise_test(function(test) {
+ return navigator.requestMediaKeySystemAccess(keySystem, configurations).then(function(a) {
+ assert_subset(a.getConfiguration(), expectedConfiguration, 'getConfiguration()');
+ });
+ }, testName);
+ }
+
+ // Tests for keySystem.
+ expect_error('', [{}], 'InvalidAccessError', 'Empty keySystem');
+ expect_error('com.example.unsupported', [{}], 'NotSupportedError', 'Unsupported keySystem');
+ expect_error('org.w3.clearkey.', [{}], 'NotSupportedError', 'keySystem ends with "."');
+ expect_error('org.w3.ClearKey', [{}], 'NotSupportedError', 'Capitalized keySystem');
+ expect_error('org.w3.clearke\u028F', [{}], 'NotSupportedError', 'Non-ASCII keySystem');
+
+ // Parent of Clear Key not supported.
+ expect_error('org', [{}], 'NotSupportedError', 'Parent of Clear Key (org)');
+ expect_error('org.', [{}], 'NotSupportedError', 'Parent of Clear Key (org.)');
+ expect_error('org.w3', [{}], 'NotSupportedError', 'Parent of Clear Key (org.w3)');
+ expect_error('org.w3.', [{}], 'NotSupportedError', 'Parent of Clear Key (org.w3.)');
+
+ // Child of Clear Key not supported.
+ expect_error('org.w3.clearkey.foo', [{}], 'NotSupportedError', 'Child of Clear Key');
+
+ // Prefixed Clear Key not supported.
+ expect_error('webkit-org.w3.clearkey', [{}], 'NotSupportedError', 'Prefixed Clear Key');
+
+ // Incomplete names.
+ expect_error('org.w3.learkey', [{}], 'NotSupportedError', 'Incomplete name org.w3.learkey');
+ expect_error('org.w3.clearke', [{}], 'NotSupportedError', 'Incomplete name org.w3.clearke');
+ expect_error('or.w3.clearkey', [{}], 'NotSupportedError', 'Incomplete name or.w3.clearkey');
+
+ // Spaces in key system name not supported.
+ expect_error(' org.w3.clearkey', [{}], 'NotSupportedError', 'Leading space in key system name');
+ expect_error('org.w3. clearkey', [{}], 'NotSupportedError', 'Extra space in key system name');
+ expect_error('org.w3.clearkey ', [{}], 'NotSupportedError', 'Trailing space in key system name');
+
+ // Extra dots in key systems names not supported.
+ expect_error('.org.w3.clearkey', [{}], 'NotSupportedError', 'Leading dot in key systems name');
+ expect_error('org.w3.clearkey.', [{}], 'NotSupportedError', 'Trailing dot in key systems name');
+ expect_error('org.w3..clearkey', [{}], 'NotSupportedError', 'Double dot in key systems name');
+ expect_error('org.w3.clear.key', [{}], 'NotSupportedError', 'Extra dot in key systems name');
+
+ // Key system name is case sensitive.
+ expect_error('org.w3.Clearkey', [{}], 'NotSupportedError', 'Key system name is case sensitive');
+ expect_error('Org.w3.clearkey', [{}], 'NotSupportedError', 'Key system name is case sensitive');
+
+ // Tests for trivial configurations.
+ expect_error('org.w3.clearkey', [], 'InvalidAccessError', 'Empty supportedConfigurations');
+ expect_config('org.w3.clearkey', [{}], {}, 'Empty configuration');
+
+ // Various combinations of supportedConfigurations.
+ // TODO(jrummell): Specifying contentType without codecs is
+ // deprecated, so this test should fail. http://crbug.com/605661.
+ expect_config('org.w3.clearkey', [{
+ initDataTypes: ['webm'],
+ audioCapabilities: [{contentType: 'audio/webm'}],
+ videoCapabilities: [{contentType: 'video/webm'}],
+ }], {
+ initDataTypes: ['webm'],
+ audioCapabilities: [{contentType: 'audio/webm'}],
+ videoCapabilities: [{contentType: 'video/webm'}],
+ }, 'Basic supported configuration');
+
+ // TODO(jrummell): Specifying contentType without codecs is
+ // deprecated, so this test should fail. http://crbug.com/605661.
+ expect_config('org.w3.clearkey', [{
+ initDataTypes: ['fakeidt', 'webm'],
+ audioCapabilities: [{contentType: 'audio/fake'}, {contentType: 'audio/webm'}],
+ videoCapabilities: [{contentType: 'video/fake'}, {contentType: 'video/webm'}],
+ }], {
+ initDataTypes: ['webm'],
+ audioCapabilities: [{contentType: 'audio/webm'}],
+ videoCapabilities: [{contentType: 'video/webm'}],
+ }, 'Partially supported configuration');
+
+ expect_config('org.w3.clearkey', [{
+ audioCapabilities: [{contentType: 'audio/webm; codecs=vorbis'}],
+ }], {
+ audioCapabilities: [{contentType: 'audio/webm; codecs=vorbis'}],
+ }, 'Supported audio codec');
+
+ expect_config('org.w3.clearkey', [{
+ audioCapabilities: [{contentType: 'audio/webm; codecs="vorbis"'}],
+ }], {
+ audioCapabilities: [{contentType: 'audio/webm; codecs="vorbis"'}],
+ }, 'ContentType formatting must be preserved');
+
+ expect_error('org.w3.clearkey', [{
+ audioCapabilities: [{contentType: 'audio/webm; codecs=fake'}],
+ }], 'NotSupportedError', 'Unsupported audio codec');
+
+ expect_error('org.w3.clearkey', [{
+ audioCapabilities: [
+ {contentType: 'audio/webm; codecs=mp4a'},
+ {contentType: 'audio/webm; codecs=mp4a.40.2'}
+ ],
+ }], 'NotSupportedError', 'Mismatched audio container/codec');
+
+ expect_config('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'video/webm; codecs=vp8'}],
+ }], {
+ videoCapabilities: [{contentType: 'video/webm; codecs=vp8'}],
+ }, 'Supported video codec');
+
+ expect_error('org.w3.clearkey', [{
+ audioCapabilities: [{contentType: 'video/webm; codecs=vp8'}],
+ }], 'NotSupportedError', 'Video codec specified in audio field');
+
+ expect_error('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'audio/webm; codecs=vorbis'}],
+ }], 'NotSupportedError', 'Audio codec specified in video field');
+
+ expect_error('org.w3.clearkey', [{
+ audioCapabilities: [{contentType: 'video/webm; codecs=fake'}],
+ }], 'NotSupportedError', 'Unsupported video codec');
+
+ expect_error('org.w3.clearkey', [{
+ audioCapabilities: [
+ {contentType: 'audio/webm; codecs=avc1'},
+ {contentType: 'audio/webm; codecs=avc1.42e01e'}
+ ],
+ }], 'NotSupportedError', 'Mismatched video container/codec');
+
+ expect_config('org.w3.clearkey', [
+ {initDataTypes: ['fakeidt']},
+ {initDataTypes: ['webm']}
+ ], {initDataTypes: ['webm']}, 'Two configurations, one supported');
+
+ expect_config('org.w3.clearkey', [
+ {initDataTypes: ['webm']},
+ {}
+ ], {initDataTypes: ['webm']}, 'Two configurations, both supported');
+
+ // Audio MIME type does not support video codecs.
+ expect_error('org.w3.clearkey', [{
+ audioCapabilities: [
+ {contentType: 'audio/webm; codecs="vp8,vorbis"'},
+ {contentType: 'audio/webm; codecs="vorbis, vp8"'},
+ {contentType: 'audio/webm; codecs="vp8"'}
+ ],
+ }], 'NotSupportedError', 'Audio MIME type does not support video codecs.');
+
+ // Video MIME type does not support audio codecs.
+ expect_error('org.w3.clearkey', [{
+ videoCapabilities: [
+ {contentType: 'video/webm; codecs="vp8,vorbis"'},
+ {contentType: 'video/webm; codecs="vorbis, vp8"'},
+ {contentType: 'video/webm; codecs="vorbis"'}
+ ],
+ }], 'NotSupportedError', 'Video MIME type does not support audio codecs.');
+
+ // WebM does not support AVC1/AAC.
+ expect_error('org.w3.clearkey', [{
+ audioCapabilities: [
+ {contentType: 'audio/webm; codecs="aac"'},
+ {contentType: 'audio/webm; codecs="avc1"'},
+ {contentType: 'audio/webm; codecs="vp8,aac"'}
+ ],
+ }], 'NotSupportedError', 'WebM audio does not support AVC1/AAC.');
+
+ expect_error('org.w3.clearkey', [{
+ videoCapabilities: [
+ {contentType: 'video/webm; codecs="aac"'},
+ {contentType: 'video/webm; codecs="avc1"'},
+ {contentType: 'video/webm; codecs="vp8,aac"'}
+ ],
+ }], 'NotSupportedError', 'WebM video does not support AVC1/AAC.');
+
+ // Extra space is allowed in contentType.
+ expect_config('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: ' video/webm; codecs="vp8"'}],
+ }], {
+ videoCapabilities: [{contentType: ' video/webm; codecs="vp8"'}],
+ }, 'Leading space in contentType');
+
+ expect_config('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'video/webm ; codecs="vp8"'}],
+ }], {
+ videoCapabilities: [{contentType: 'video/webm ; codecs="vp8"'}],
+ }, 'Space before ; in contentType');
+
+ expect_config('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'video/webm; codecs="vp8"'}],
+ }], {
+ videoCapabilities: [{contentType: 'video/webm; codecs="vp8"'}],
+ }, 'Extra spaces after ; in contentType');
+
+ // TODO(jrummell): contentType should allow white space at the
+ // end of the string. http://crbug.com/487392
+// expect_config('org.w3.clearkey', [{
+// videoCapabilities: [{contentType: 'video/webm; codecs="vp8" '}],
+// }], {
+// videoCapabilities: [{contentType: 'video/webm; codecs="vp8" '}],
+// }, 'Trailing space in contentType');
+
+ expect_config('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'video/webm; codecs=" vp8"'}],
+ }], {
+ videoCapabilities: [{contentType: 'video/webm; codecs=" vp8"'}],
+ }, 'Space at start of codecs parameter');
+
+ expect_config('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'video/webm; codecs="vp8 "'}],
+ }], {
+ videoCapabilities: [{contentType: 'video/webm; codecs="vp8 "'}],
+ }, 'Space at end of codecs parameter');
+
+ // contentType is not case sensitive (except the codec names).
+ expect_config('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'Video/webm; codecs="vp8"'}],
+ }], {
+ videoCapabilities: [{contentType: 'Video/webm; codecs="vp8"'}],
+ }, 'Video/webm');
+
+ expect_config('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'video/Webm; codecs="vp8"'}],
+ }], {
+ videoCapabilities: [{contentType: 'video/Webm; codecs="vp8"'}],
+ }, 'video/Webm');
+
+ expect_config('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'video/webm; Codecs="vp8"'}],
+ }], {
+ videoCapabilities: [{contentType: 'video/webm; Codecs="vp8"'}],
+ }, 'Codecs=');
+
+ expect_config('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'VIDEO/WEBM; codecs="vp8"'}],
+ }], {
+ videoCapabilities: [{contentType: 'VIDEO/WEBM; codecs="vp8"'}],
+ }, 'VIDEO/WEBM');
+
+ expect_config('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'video/webm; CODECS="vp8"'}],
+ }], {
+ videoCapabilities: [{contentType: 'video/webm; CODECS="vp8"'}],
+ }, 'CODECS=');
+
+ // Unrecognized attributes are not allowed.
+ // TODO(jrummell): Unrecognized attributes are ignored currently.
+ // http://crbug.com/449690
+// expect_error('org.w3.clearkey', [{
+// videoCapabilities: [{contentType: 'video/webm; foo="bar"'}],
+// }], 'NotSupportedError', 'Unrecognized foo');
+// expect_error('org.w3.clearkey', [{
+// videoCapabilities: [{contentType: 'video/webm; foo="bar"; codecs="vp8"'}],
+// }], 'NotSupportedError', 'Unrecognized foo with codecs');
+
+ // Invalid contentTypes.
+ expect_error('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'fake'}],
+ }], 'NotSupportedError', 'contentType fake');
+
+ expect_error('org.w3.clearkey', [{
+ audioCapabilities: [{contentType: 'audio/fake'}],
+ }], 'NotSupportedError', 'contentType audio/fake');
+
+ expect_error('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'video/fake'}],
+ }], 'NotSupportedError', 'contentType video/fake');
+
+ // The actual codec names are case sensitive.
+ expect_error('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'video/webm; codecs="Vp8"'}],
+ }], 'NotSupportedError', 'codecs Vp8');
+
+ expect_error('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'video/webm; codecs="VP8"'}],
+ }], 'NotSupportedError', 'codecs VP8');
+
+ // Extra comma is not allowed in codecs.
+ expect_error('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'video/webm; codecs=",vp8"'}],
+ }], 'NotSupportedError', 'Leading , in codecs');
+
+ expect_error('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'video/webm; codecs="vp8,"'}],
+ }], 'NotSupportedError', 'Trailing , in codecs');
+
+ expect_error('org.w3.clearkey', [{
+ videoCapabilities: [{contentType: 'video/webm; codecs=",vp8,"'}],
+ }], 'NotSupportedError', 'Leading and trailing , in codecs');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-reset-src-after-setmediakeys.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-reset-src-after-setmediakeys.html
new file mode 100644
index 000000000..15c91a001
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-reset-src-after-setmediakeys.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Reset src after setMediaKeys()</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <video id="testVideo"></video>
+ <div id="log"></div>
+ <script>
+ async_test(function(test)
+ {
+ var mediaKeys;
+ var encryptedEventIndex = 0;
+ var video = document.getElementById('testVideo');
+ assert_not_equals(video, null);
+
+ // Content to be played. These files must be the same format.
+ var content = 'webm/test-encrypted.webm';
+ var alternateContent = 'webm/test-encrypted-different-av-keys.webm';
+
+ var onEncrypted = function(event)
+ {
+ ++encryptedEventIndex;
+ assert_not_equals(video.mediaKeys, null);
+ assert_true(video.mediaKeys === mediaKeys);
+
+ // This event is fired once for the audio stream and once
+ // for the video stream each time .src is set.
+ if (encryptedEventIndex == 2) {
+ // Finished first video; set src to a different video.
+ video.src = alternateContent;
+ } else if (encryptedEventIndex == 4) {
+ // Finished second video.
+ test.done();
+ }
+ };
+
+ // Create a MediaKeys object and assign it to video.
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getConfigurationForFile(content))
+ .then(function(access) {
+ assert_equals(access.keySystem, 'org.w3.clearkey');
+ return access.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys = result;
+ assert_not_equals(mediaKeys, null);
+ return video.setMediaKeys(mediaKeys);
+ }).then(function(result) {
+ assert_not_equals(video.mediaKeys, null, 'not set initially');
+ assert_true(video.mediaKeys === mediaKeys);
+
+ // Set src to a video.
+ waitForEventAndRunStep('encrypted', video, onEncrypted, test);
+ video.src = content;
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'Reset src after setMediaKeys().');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-session-closed-event.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-session-closed-event.html
new file mode 100644
index 000000000..577047a25
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-session-closed-event.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Test MediaKeySession closed event</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ async_test(function(test)
+ {
+ var initDataType;
+ var initData;
+ var mediaKeySession;
+
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ initDataType = access.getConfiguration().initDataTypes[0];
+ initData = getInitData(initDataType);
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ mediaKeySession = mediaKeys.createSession();
+ return mediaKeySession.generateRequest(initDataType, initData);
+ }).then(function() {
+ // Wait for the session to be closed.
+ mediaKeySession.closed.then(function(result) {
+ assert_equals(result, undefined);
+ // Now that the session is closed, verify that the
+ // closed attribute immediately returns a fulfilled
+ // promise.
+ return mediaKeySession.closed;
+ }).then(function(result) {
+ assert_equals(result, undefined);
+ test.done();
+ });
+
+ // release() should result in the closed promise being
+ // fulfilled.
+ return mediaKeySession.close();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'Test MediaKeySession closed event.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-again-after-playback.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-again-after-playback.html
new file mode 100644
index 000000000..29f53b31d
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-again-after-playback.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>setMediaKeys() again after playback</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <video id="testVideo"></video>
+ <div id="log"></div>
+ <script>
+ promise_test(function(test)
+ {
+ var video = document.getElementById('testVideo');
+ var keyId = stringToUint8Array('0123456789012345');
+ var rawKey = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
+ 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);
+ var content = 'webm/test-encrypted.webm';
+ var duration = 0.2;
+
+ return createMediaKeys(keyId, rawKey).then(function(mediaKeys) {
+ return video.setMediaKeys(mediaKeys);
+ }).then(function() {
+ return playVideoAndWaitForTimeupdate(video, content, duration);
+ }).then(function() {
+ // Now create a second MediaKeys.
+ return createMediaKeys(keyId, rawKey);
+ }).then(function(mediaKeys) {
+ // video is currently playing, so should not be able to
+ // change MediaKeys now.
+ assert_false(video.ended);
+ return video.setMediaKeys(mediaKeys);
+ }).then(function() {
+ assert_unreached('Able to change MediaKeys while playing.');
+ }, function(error) {
+ // Error expected.
+ assert_equals(error.name, 'InvalidStateError');
+ return Promise.resolve('success');
+ });
+ }, 'setMediaKeys() again after playback');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-again-after-resetting-src.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-again-after-resetting-src.html
new file mode 100644
index 000000000..8f6891b79
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-again-after-resetting-src.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>setMediaKeys() again after resetting src</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <video id="testVideo"></video>
+ <div id="log"></div>
+ <script>
+ promise_test(function(test)
+ {
+ var video = document.getElementById('testVideo');
+ var keyId = stringToUint8Array('0123456789012345');
+ var rawKey = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
+ 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);
+ var content = 'webm/test-encrypted.webm';
+ var duration = 0.2;
+
+ return createMediaKeys(keyId, rawKey).then(function(mediaKeys) {
+ return video.setMediaKeys(mediaKeys);
+ }).then(function() {
+ return playVideoAndWaitForTimeupdate(video, content, duration);
+ }).then(function() {
+ // Now create a second MediaKeys and repeat.
+ return createMediaKeys(keyId, rawKey);
+ }).then(function(mediaKeys) {
+ // MediaKeys is use by previous video, so clear .src
+ // so that MediaKeys can be assigned.
+ video.src = '';
+ return video.setMediaKeys(mediaKeys);
+ }).then(function() {
+ return playVideoAndWaitForTimeupdate(video, content, duration);
+ });
+ }, 'setMediaKeys() again after resetting src');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-at-same-time.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-at-same-time.html
new file mode 100644
index 000000000..01fd7b194
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-at-same-time.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Set MediaKeys multiple times in parallel</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <video id="video"></video>
+ <div id="log"></div>
+ <script>
+ // Wait for an 'encrypted' event as a promise.
+ function wait_for_encrypted_event(video)
+ {
+ return new Promise(function(resolve) {
+ video.addEventListener('encrypted', function listener(e) {
+ video.removeEventListener('encrypted', listener);
+ resolve();
+ });
+ });
+ };
+
+ // Return a promise that calls setMediaKeys() and returns 1 if
+ // resolved, 0 if rejected. If |must_succeed| is true, then
+ // setMediaKeys() should not fail.
+ function setMediaKeys_as_count(video, mediaKeys, must_succeed)
+ {
+ return video.setMediaKeys(mediaKeys).then(function() {
+ return 1;
+ }, function() {
+ assert_false(must_succeed);
+ return 0;
+ });
+ };
+
+ // Return the sum of the results from |promises|. Each promise
+ // must return a number.
+ function count_promise_results(promises)
+ {
+ var count = 0;
+ var result = Promise.resolve(null);
+
+ promises.forEach(function(promise) {
+ result = result.then(function() {
+ return promise;
+ }).then(function(i) {
+ count += i;
+ });
+ });
+
+ return result.then(function() { return count; });
+ };
+
+ promise_test(function(test)
+ {
+ var video = document.getElementById('video');
+ var content = 'webm/test-encrypted.webm';
+ var access;
+ var mediaKeys1;
+ var mediaKeys2;
+ var mediaKeys3;
+ var mediaKeys4;
+ var mediaKeys5;
+
+ // Start a video now so that it is waiting for MediaKeys
+ // in order to continue.
+ video.src = content;
+ video.play();
+ return wait_for_encrypted_event(video).then(function() {
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getConfigurationForFile(content));
+ }).then(function(result) {
+ access = result;
+ return access.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys1 = result;
+ return access.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys2 = result;
+ return access.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys3 = result;
+ return access.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys4 = result;
+ return access.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys5 = result;
+ // Create 5 calls to setMediaKeys(). The first one must
+ // succeed, the others are optional.
+ var p1 = setMediaKeys_as_count(video, mediaKeys1, true);
+ var p2 = setMediaKeys_as_count(video, mediaKeys2, false);
+ var p3 = setMediaKeys_as_count(video, mediaKeys3, false);
+ var p4 = setMediaKeys_as_count(video, mediaKeys4, false);
+ var p5 = setMediaKeys_as_count(video, mediaKeys5, false);
+ return count_promise_results([p1, p2, p3, p4, p5]);
+ }).then(function(count) {
+ // At least one of the setMediaKeys() calls should have
+ // succeeded.
+ assert_greater_than(count, 0);
+ });
+ }, 'Set MediaKeys multiple times in parallel.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-multiple-times-with-different-mediakeys.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-multiple-times-with-different-mediakeys.html
new file mode 100644
index 000000000..31cc61079
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-multiple-times-with-different-mediakeys.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>setMediaKeys() multiple times with different MediaKeys.</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <video id="video"></video>
+ <div id="log"></div>
+ <script>
+ promise_test(function(test)
+ {
+ var video = document.getElementById('video');
+ var content = 'webm/test-encrypted.webm';
+ var keySystemAccess;
+ var mediaKeys1;
+ var mediaKeys2;
+
+ assert_equals(video.mediaKeys, null);
+
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getConfigurationForFile(content)).then(function(access) {
+ keySystemAccess = access;
+ // Create a mediaKeys.
+ return keySystemAccess.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys1 = result;
+ assert_not_equals(mediaKeys1, null);
+ // Create a second mediaKeys.
+ return keySystemAccess.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys2 = result;
+ assert_not_equals(mediaKeys2, null);
+ // Set mediaKeys1 on video.
+ return video.setMediaKeys(mediaKeys1);
+ }).then(function() {
+ assert_true(video.mediaKeys === mediaKeys1);
+ // Set mediaKeys2 on video (switching MediaKeys).
+ return video.setMediaKeys(mediaKeys2);
+ }).then(function() {
+ assert_true(video.mediaKeys === mediaKeys2);
+ // Clear mediaKeys from video.
+ return video.setMediaKeys(null);
+ }).then(function() {
+ assert_equals(video.mediaKeys, null);
+ // Set mediaKeys1 on video again.
+ return video.setMediaKeys(mediaKeys1);
+ }).then(function() {
+ assert_true(video.mediaKeys === mediaKeys1);
+ // Load the media element to create the WebMediaPlayer.
+ video.src = content;
+ // Set mediaKeys2 on video (switching MediaKeys) not
+ // supported after WebMediaPlayer is created.
+ return video.setMediaKeys(mediaKeys2);
+ }).then(function() {
+ assert_unreached('Switching mediaKeys after setting src should have failed.');
+ }, function(error) {
+ assert_true(video.mediaKeys === mediaKeys1);
+ assert_equals(error.name, 'InvalidStateError');
+ assert_not_equals(error.message, '');
+ // Return something so the promise resolves properly.
+ return Promise.resolve();
+ }).then(function() {
+ // Set null mediaKeys on video (clearing MediaKeys) not
+ // supported after WebMediaPlayer is created.
+ return video.setMediaKeys(null);
+ }).then(function() {
+ assert_unreached('Clearing mediaKeys after setting src should have failed.');
+ }, function(error) {
+ assert_true(video.mediaKeys === mediaKeys1);
+ assert_equals(error.name, 'InvalidStateError');
+ assert_not_equals(error.message, '');
+ return Promise.resolve();
+ });
+ }, 'setMediaKeys() multiple times with different MediaKeys.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-multiple-times-with-the-same-mediakeys.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-multiple-times-with-the-same-mediakeys.html
new file mode 100644
index 000000000..64ed315e0
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-multiple-times-with-the-same-mediakeys.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>setMediaKeys() multiple times with the same MediaKeys.</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <video id="video"></video>
+ <div id="log"></div>
+ <script>
+ promise_test(function(test)
+ {
+ var video = document.getElementById('video');
+ var content = 'webm/test-encrypted.webm';
+ var mediaKeys;
+
+ assert_equals(video.mediaKeys, null);
+
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getConfigurationForFile(content)).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys = result;
+ assert_not_equals(mediaKeys, null);
+ // Set mediaKeys on video should work.
+ return video.setMediaKeys(mediaKeys);
+ }).then(function() {
+ assert_true(video.mediaKeys === mediaKeys);
+ // Set mediaKeys on video again should return a resolved
+ // promise.
+ return video.setMediaKeys(mediaKeys);
+ }).then(function() {
+ assert_true(video.mediaKeys === mediaKeys);
+ // Load the media element to create the WebMediaPlayer.
+ video.src = content;
+ // Set mediaKeys again on video should still return a
+ // resolved promise.
+ return video.setMediaKeys(mediaKeys);
+ }).then(function() {
+ assert_true(video.mediaKeys === mediaKeys);
+ });
+ }, 'setMediaKeys() multiple times with the same MediaKeys.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-to-multiple-video-elements.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-to-multiple-video-elements.html
new file mode 100644
index 000000000..fb8386e8c
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys-to-multiple-video-elements.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>setMediaKeys() on multiple video elements.</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <video id="video1"></video>
+ <video id="video2"></video>
+ <div id="log"></div>
+ <script>
+ promise_test(function(test)
+ {
+ var video1 = document.getElementById('video1');
+ var video2 = document.getElementById('video2');
+ var mediaKeys;
+
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys = result;
+ // Assignment to video1 should work.
+ return video1.setMediaKeys(mediaKeys);
+ }).then(function() {
+ // Assignment to video2 should fail.
+ return video2.setMediaKeys(mediaKeys);
+ }).then(function() {
+ assert_unreached('Second setMediaKeys should have failed.');
+ }, function(error) {
+ assert_equals(error.name, 'QuotaExceededError');
+ assert_not_equals(error.message, '');
+ // Return something so the promise resolves properly.
+ return Promise.resolve();
+ }).then(function() {
+ // Now clear it from video1.
+ return video1.setMediaKeys(null);
+ }).then(function() {
+ // Should be assignable to video2.
+ return video2.setMediaKeys(mediaKeys);
+ });
+ }, 'setMediaKeys() on multiple video elements.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys.html
new file mode 100644
index 000000000..96b0fed97
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-setmediakeys.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>setMediaKeys</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <video id="video"></video>
+ <div id="log"></div>
+ <script>
+ async_test(function(test)
+ {
+ var mediaKeys;
+ var video = document.getElementById('video');
+ assert_not_equals(video, null);
+
+ // Test MediaKeys assignment.
+ assert_equals(video.mediaKeys, null);
+ assert_equals(typeof video.setMediaKeys, 'function');
+
+ // Try setting mediaKeys to null.
+ video.setMediaKeys(null).then(function(result) {
+ assert_equals(video.mediaKeys, null);
+
+ // Try setting mediaKeys to the wrong type of object.
+ return video.setMediaKeys(new Date());
+ }).then(function(result) {
+ assert_unreached('setMediaKeys did not fail when setting to Date()');
+ }, function(error) {
+ // TypeError expected.
+ assert_equals(error.name, 'TypeError');
+
+ // Create a MediaKeys object and assign it to video.
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration());
+ }).then(function(access) {
+ assert_equals(access.keySystem, 'org.w3.clearkey');
+ return access.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys = result;
+ assert_not_equals(mediaKeys, null);
+ assert_equals(typeof mediaKeys.createSession, 'function');
+ return video.setMediaKeys(mediaKeys);
+ }).then(function(result) {
+ assert_not_equals(video.mediaKeys, null);
+ assert_true(video.mediaKeys === mediaKeys);
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error);
+ });
+ }, 'Setting MediaKeys on a video object.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-syntax.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-syntax.html
new file mode 100644
index 000000000..5c4c667cb
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-syntax.html
@@ -0,0 +1,1017 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Test EME syntax</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <script>
+ // Since promises catch any exception and convert it into a
+ // rejected Promise, there is no current way to have the W3C
+ // test framework report a failed test. For now, simply force
+ // a timeout to indicate failure.
+ // FIXME: Once W3C test framework handles Promises, fix this.
+
+ // 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));
+ }
+ }
+
+ var kRequestMediaKeySystemAccessExceptionsTestCases = [
+ // Too few parameters.
+ {
+ exception: 'TypeError',
+ func: function() { return navigator.requestMediaKeySystemAccess(); }
+ },
+ {
+ exception: 'TypeError',
+ func: function() { return navigator.requestMediaKeySystemAccess('org.w3.clearkey'); }
+ },
+ // Invalid key systems. Note that JavaScript converts all these
+ // values into strings by calling toString(), so they fail due
+ // to the key system not being supported, not due to the type.
+ {
+ exception: 'NotSupportedError',
+ func: function() { return navigator.requestMediaKeySystemAccess(null, [{}]); }
+ },
+ {
+ exception: 'NotSupportedError',
+ func: function() { return navigator.requestMediaKeySystemAccess(undefined, [{}]); }
+ },
+ {
+ exception: 'NotSupportedError',
+ func: function() { return navigator.requestMediaKeySystemAccess(1, [{}]); }
+ },
+ {
+ exception: 'InvalidAccessError',
+ func: function() { return navigator.requestMediaKeySystemAccess(new Uint8Array(0), [{}]); }
+ },
+ {
+ exception: 'InvalidAccessError',
+ func: function() { return navigator.requestMediaKeySystemAccess('', [{}]); }
+ },
+ {
+ exception: 'NotSupportedError',
+ func: function() { return navigator.requestMediaKeySystemAccess('unsupported', [{}]); }
+ },
+ // Non-ASCII names.
+ {
+ exception: 'NotSupportedError',
+ func: function() { return navigator.requestMediaKeySystemAccess('org.w3\u263A.clearkey', [{}]); }
+ },
+ // Empty sequence of MediaKeySystemConfiguration.
+ {
+ exception: 'InvalidAccessError',
+ func: function() { return navigator.requestMediaKeySystemAccess('org.w3.clearkey', []); }
+ },
+ // Invalid sequences of MediaKeySystemConfigurations.
+ {
+ exception: 'TypeError',
+ func: function() { return navigator.requestMediaKeySystemAccess('org.w3.clearkey', {}); }
+ },
+ {
+ exception: 'TypeError',
+ func: function() { return navigator.requestMediaKeySystemAccess('org.w3.clearkey', "invalid"); }
+ },
+ {
+ exception: 'TypeError',
+ func: function() { return navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}, 6]); }
+ },
+ {
+ exception: 'TypeError',
+ func: function() { return navigator.requestMediaKeySystemAccess('org.w3.clearkey', ["invalid", "upsupported"]); }
+ }
+ ];
+
+ async_test(function(test)
+ {
+ var createPromises = kRequestMediaKeySystemAccessExceptionsTestCases.map(function(testCase) {
+ return test_exception(testCase);
+ });
+
+ Promise.all(createPromises).then(function(result) {
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error, 'requestMediaKeySystemAccess() tests failed');
+ });
+ }, 'Test Navigator.requestMediaKeySystemAccess() exceptions.');
+
+ async_test(function(test)
+ {
+ assert_equals(typeof navigator.requestMediaKeySystemAccess, 'function');
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}]).then(function(access) {
+ assert_not_equals(access, null);
+ assert_equals(typeof access, 'object');
+ assert_equals(access.keySystem, 'org.w3.clearkey');
+ assert_equals(typeof access.getConfiguration, 'function');
+ assert_equals(typeof access.createMediaKeys, 'function');
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error, 'requestMediaKeySystemAccess() tests failed');
+ });
+ }, 'Test Navigator.requestMediaKeySystemAccess().');
+
+ async_test(function(test)
+ {
+ var access;
+
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}]).then(function(result) {
+ access = result;
+ assert_equals(access.keySystem, 'org.w3.clearkey');
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ assert_not_equals(mediaKeys, null);
+ assert_equals(typeof mediaKeys, 'object');
+ assert_equals(typeof mediaKeys.createSession, 'function');
+ assert_equals(typeof mediaKeys.setServerCertificate, 'function');
+
+ // Test creation of a second MediaKeys.
+ // The extra parameter is ignored.
+ return access.createMediaKeys('extra');
+ }).then(function(mediaKeys) {
+ assert_not_equals(mediaKeys, null);
+ assert_equals(typeof mediaKeys, 'object');
+ assert_equals(typeof mediaKeys.createSession, 'function');
+ assert_equals(typeof mediaKeys.setServerCertificate, 'function');
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error, 'create() tests failed');
+ });
+ }, 'Test MediaKeySystemAccess createMediaKeys().');
+
+ var kCreateSessionExceptionsTestCases = [
+ // Tests in this set use a shortened parameter name due to
+ // format_value() only returning the first 60 characters as the
+ // result. With a longer name the first 60 characters is not
+ // enough to determine which test failed.
+
+ // Invalid parameters.
+ {
+ exception: 'TypeError',
+ func: function(mk) { return mk.createSession(); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk) { return mk.createSession(''); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk) { return mk.createSession(null); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk) { return mk.createSession(undefined); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk) { return mk.createSession(1); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk) { return mk.createSession(new Uint8Array(0)); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk) { return mk.createSession('TEMPORARY'); }
+ }
+ ];
+
+ // This function checks that calling createSession() with an
+ // unsupported session type doesn't create a MediaKeySession object.
+ // Since requestMediaKeySystemAccess() is called without specifying
+ // persistent sessions, only temporary sessions will be allowed.
+ function test_unsupported_sessionType(mediaKeys)
+ {
+ var mediaKeySession = 'test';
+
+ try {
+ mediaKeySession = mediaKeys.createSession('persistent-license');
+ assert_unreached('Session should not be created.');
+ } catch (error) {
+ assert_equals(error.name, 'NotSupportedError');
+ assert_not_equals(error.message, "");
+
+ // Since createSession() failed, |mediaKeySession| is not
+ // touched.
+ assert_equals(mediaKeySession, 'test');
+ }
+ }
+
+ async_test(function(test)
+ {
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}]).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var sessionPromises = kCreateSessionExceptionsTestCases.map(function(testCase) {
+ return test_exception(testCase, mediaKeys);
+ });
+ sessionPromises = sessionPromises.concat(test_unsupported_sessionType(mediaKeys));
+
+ assert_not_equals(sessionPromises.length, 0);
+ return Promise.all(sessionPromises);
+ }).then(function(result) {
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error, 'createSession() tests failed');
+ });
+ }, 'Test MediaKeys createSession() exceptions.');
+
+ var kGenerateRequestExceptionsTestCases = [
+ // Tests in this set use a shortened parameter name due to
+ // format_value() only returning the first 60 characters as the
+ // result. With a longer name the first 60 characters is not
+ // enough to determine which test failed. Even with the
+ // shortened name, the error message for the last couple of
+ // tests is the same.
+ // Too few parameters.
+ {
+ exception: 'TypeError',
+ func: function(mk1) { return mk1.createSession().generateRequest(); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk2) { return mk2.createSession().generateRequest(''); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk3) { return mk3.createSession().generateRequest(null); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk4) { return mk4.createSession().generateRequest(undefined); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk5) { return mk5.createSession().generateRequest(1); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk6) { return mk6.createSession().generateRequest(new Uint8Array(0)); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk7, _, initData) { return mk7.createSession().generateRequest(initData); }
+ },
+ // Invalid parameters.
+ {
+ exception: 'InvalidAccessError',
+ func: function(mk8, _, initData) { return mk8.createSession().generateRequest('', initData); }
+ },
+ // Not supported initDataTypes.
+ {
+ exception: 'NotSupportedError',
+ func: function(mk9, _, initData) { return mk9.createSession().generateRequest(null, initData); }
+ },
+ {
+ exception: 'NotSupportedError',
+ func: function(mk10, _, initData) { return mk10.createSession().generateRequest(undefined, initData); }
+ },
+ {
+ exception: 'NotSupportedError',
+ func: function(mk11, _, initData) { return mk11.createSession().generateRequest(1, initData); }
+ },
+ {
+ exception: 'InvalidAccessError',
+ func: function(mk12, _, initData) { return mk12.createSession().generateRequest(new Uint8Array(0), initData); }
+ },
+ {
+ exception: 'NotSupportedError',
+ func: function(mk13, _, initData) { return mk13.createSession().generateRequest('unsupported', initData); }
+ },
+ {
+ exception: 'NotSupportedError',
+ func: function(mk14, _, initData) { return mk14.createSession().generateRequest('video/webm', initData); }
+ },
+ {
+ exception: 'NotSupportedError',
+ func: function(mk15, _, initData) { return mk15.createSession().generateRequest('video/mp4', initData); }
+ },
+ {
+ exception: 'NotSupportedError',
+ func: function(mk16, _, initData) { return mk16.createSession().generateRequest('video/cenc', initData); }
+ },
+ {
+ exception: 'NotSupportedError',
+ func: function(mk17, _, initData) { return mk17.createSession().generateRequest('web\u263A', initData); }
+ }
+ ];
+
+ var kTypeSpecificGenerateRequestExceptionsTestCases = [
+ // Tests in this set use a shortened parameter name due to
+ // format_value() only returning the first 60 characters as the
+ // result. With a longer name the first 60 characters is not
+ // enough to determine which test failed. Even with the
+ // shortened name, the error message for the last couple of
+ // tests is the same.
+
+ // Too few parameters.
+ {
+ exception: 'TypeError',
+ func: function(mk1, type) { return mk1.createSession().generateRequest(type); }
+ },
+ // Invalid parameters.
+ {
+ exception: 'TypeError',
+ func: function(mk2, type) { return mk2.createSession().generateRequest(type, ''); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk3, type) { return mk3.createSession().generateRequest(type, null); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk4, type) { return mk4.createSession().generateRequest(type, undefined); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk5, type) { return mk5.createSession().generateRequest(type, 1); }
+ },
+ {
+ exception: 'InvalidAccessError',
+ func: function(mk6, type) { return mk6.createSession().generateRequest(type, new Uint8Array(0)); }
+ }
+ ];
+
+ async_test(function(test)
+ {
+ var isWebmSupported;
+ var isCencSupported;
+
+ isInitDataTypeSupported('webm').then(function(result) {
+ isWebmSupported = result;
+ return isInitDataTypeSupported('cenc');
+ }).then(function(result) {
+ isCencSupported = result;
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}]);
+ }).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var initData = stringToUint8Array('init data');
+ var sessionPromises = kGenerateRequestExceptionsTestCases.map(function(testCase) {
+ return test_exception(testCase, mediaKeys, '', initData);
+ });
+
+ // Test that WebM sessions generate the expected error, if
+ // supported.
+ if (isWebmSupported) {
+ var WebmSessionPromises = kTypeSpecificGenerateRequestExceptionsTestCases.map(function(testCase) {
+ return test_exception(testCase, mediaKeys, 'webm', getInitData('webm'));
+ });
+ sessionPromises = sessionPromises.concat(WebmSessionPromises);
+ }
+
+ // Repeat for MP4, if supported.
+ if (isCencSupported) {
+ var mp4SessionPromises = kTypeSpecificGenerateRequestExceptionsTestCases.map(function(testCase) {
+ return test_exception(testCase, mediaKeys, 'cenc', getInitData('cenc'));
+ });
+ sessionPromises = sessionPromises.concat(mp4SessionPromises);
+ }
+
+ assert_not_equals(sessionPromises.length, 0);
+ return Promise.all(sessionPromises);
+ }).then(function(result) {
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error, 'generateRequest() tests failed');
+ });
+ }, 'Test MediaKeys generateRequest() exceptions.');
+
+ var kLoadExceptionsTestCases = [
+ // Too few parameters.
+ {
+ exception: 'TypeError',
+ func: function(mk1) { return mk1.createSession('temporary').load(); }
+ },
+ // 'temporary' sessions are never allowed, so always return
+ // 'InvalidAccessError'.
+ {
+ exception: 'InvalidAccessError',
+ func: function(mk3) { return mk3.createSession('temporary').load(''); }
+ },
+ {
+ exception: 'InvalidAccessError',
+ func: function(mk4) { return mk4.createSession('temporary').load(1); }
+ },
+ {
+ exception: 'InvalidAccessError',
+ func: function(mk5) { return mk5.createSession('temporary').load('!@#$%^&*()'); }
+ },
+ {
+ exception: 'InvalidAccessError',
+ func: function(mk6) { return mk6.createSession('temporary').load('1234'); }
+ }
+ ];
+
+ async_test(function(test)
+ {
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}]).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var initData = stringToUint8Array('init data');
+ var sessionPromises = kLoadExceptionsTestCases.map(function(testCase) {
+ return test_exception(testCase, mediaKeys);
+ });
+
+ assert_not_equals(sessionPromises.length, 0);
+ return Promise.all(sessionPromises);
+ }).then(function(result) {
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error, 'load() tests failed');
+ });
+ }, 'Test MediaKeys load() exceptions.');
+
+ // All calls to |func| in this group are supposed to succeed.
+ // However, the spec notes that some things are optional for
+ // Clear Key. In particular, support for persistent sessions
+ // is optional. Since some implementations won't support some
+ // features, a NotSupportedError is treated as a success
+ // if |isNotSupportedAllowed| is true.
+ var kCreateSessionTestCases = [
+ // Use the default sessionType.
+ {
+ func: function(mk) { return mk.createSession(); },
+ isNotSupportedAllowed: false
+ },
+ // Try variations of sessionType.
+ {
+ func: function(mk) { return mk.createSession('temporary'); },
+ isNotSupportedAllowed: false
+ },
+ {
+ func: function(mk) { return mk.createSession(undefined); },
+ isNotSupportedAllowed: false
+ },
+ {
+ // Since this is optional, some Clear Key implementations
+ // will succeed, others will return a "NotSupportedError".
+ // Both are allowed results.
+ func: function(mk) { return mk.createSession('persistent-license'); },
+ isNotSupportedAllowed: true
+ },
+ // Try additional parameter, which should be ignored.
+ {
+ func: function(mk) { return mk.createSession('temporary', 'extra'); },
+ isNotSupportedAllowed: false
+ }
+ ];
+
+ // This function checks that calling |testCase.func| creates a
+ // MediaKeySession object with some default values. It also
+ // allows for an NotSupportedError to be generated and treated as a
+ // success, if allowed. See comment above kCreateSessionTestCases.
+ function test_createSession(testCase, mediaKeys)
+ {
+ var mediaKeySession;
+ try {
+ mediaKeySession = testCase.func.call(null, mediaKeys);
+ } catch (e) {
+ assert_true(testCase.isNotSupportedAllowed);
+ return;
+ }
+
+ assert_equals(typeof mediaKeySession, 'object');
+ assert_equals(typeof mediaKeySession.addEventListener, 'function');
+ assert_equals(typeof mediaKeySession.sessionId, 'string');
+ assert_equals(typeof mediaKeySession.expiration, 'number');
+ assert_equals(typeof mediaKeySession.closed, 'object');
+ assert_equals(typeof mediaKeySession.keyStatuses, 'object');
+ assert_equals(typeof mediaKeySession.onkeystatuseschange, 'object');
+ assert_equals(typeof mediaKeySession.onmessage, 'object');
+ assert_equals(typeof mediaKeySession.generateRequest, 'function');
+ assert_equals(typeof mediaKeySession.load, 'function');
+ assert_equals(typeof mediaKeySession.update, 'function');
+ assert_equals(typeof mediaKeySession.close, 'function');
+ assert_equals(typeof mediaKeySession.remove, 'function');
+ assert_equals(mediaKeySession.sessionId, '');
+ assert_equals(typeof mediaKeySession.onopen, 'undefined');
+ assert_equals(typeof mediaKeySession.onclose, 'undefined');
+ assert_equals(typeof mediaKeySession.onerror, 'undefined');
+ }
+
+ async_test(function(test)
+ {
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}]).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ kCreateSessionTestCases.map(function(testCase) {
+ test_createSession(testCase, mediaKeys);
+ });
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error, 'createSession() tests failed');
+ });
+ }, 'Test MediaKeys createSession().');
+
+ // This function checks that calling generateRequest() works for
+ // various sessions. |testCase.func| creates a MediaKeySession
+ // object, and then generateRequest() is called on that object. It
+ // allows for an NotSupportedError to be generated and treated as a
+ // success, if allowed. See comment above kCreateSessionTestCases.
+ function test_generateRequest(testCase, mediaKeys, type, initData)
+ {
+ try {
+ var mediaKeySession = testCase.func.call(null, mediaKeys);
+ return mediaKeySession.generateRequest(type, initData);
+ } catch (e) {
+ assert_true(testCase.isNotSupportedAllowed);
+ }
+ }
+
+ async_test(function(test)
+ {
+ var isWebmSupported;
+ var isCencSupported;
+
+ isInitDataTypeSupported('webm').then(function(result) {
+ isWebmSupported = result;
+ return isInitDataTypeSupported('cenc');
+ }).then(function(result) {
+ isCencSupported = result;
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}]);
+ }).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var sessionPromises = [];
+
+ // Test that WebM sessions generate the expected error, if
+ // supported.
+ if (isWebmSupported) {
+ var WebmSessionPromises = kCreateSessionTestCases.map(function(testCase) {
+ return test_generateRequest(testCase, mediaKeys, 'webm', getInitData('webm'));
+ });
+ sessionPromises = sessionPromises.concat(WebmSessionPromises);
+ }
+
+ // Repeat for MP4, if supported.
+ if (isCencSupported) {
+ var mp4SessionPromises = kCreateSessionTestCases.map(function(testCase) {
+ return test_generateRequest(testCase, mediaKeys, 'cenc', getInitData('cenc'));
+ });
+ sessionPromises = sessionPromises.concat(mp4SessionPromises);
+ }
+
+ assert_not_equals(sessionPromises.length, 0);
+ return Promise.all(sessionPromises);
+ }).then(function(result) {
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error, 'generateRequest() tests failed');
+ });
+ }, 'Test MediaKeys generateRequest().');
+
+ var kUpdateSessionExceptionsTestCases = [
+ // Tests in this set use a shortened parameter name due to
+ // format_value() only returning the first 60 characters as the
+ // result. With a longer name (mediaKeySession) the first 60
+ // characters is not enough to determine which test failed.
+
+ // Too few parameters.
+ {
+ exception: 'TypeError',
+ func: function(s) { return s.update(); }
+ },
+ // Invalid parameters.
+ {
+ exception: 'TypeError',
+ func: function(s) { return s.update(''); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(s) { return s.update(null); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(s) { return s.update(undefined); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(s) { return s.update(1); }
+ },
+ {
+ exception: 'InvalidAccessError',
+ func: function(s) { return s.update(new Uint8Array(0)); }
+ }
+ ];
+
+ async_test(function(test)
+ {
+ var isWebmSupported;
+ var isCencSupported;
+
+ isInitDataTypeSupported('webm').then(function(result) {
+ isWebmSupported = result;
+ return isInitDataTypeSupported('cenc');
+ }).then(function(result) {
+ isCencSupported = result;
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}]);
+ }).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var promises = [];
+
+ if (isWebmSupported) {
+ var WebmSessionPromises = kUpdateSessionExceptionsTestCases.map(function(testCase) {
+ var mediaKeySession = mediaKeys.createSession();
+ return mediaKeySession.generateRequest('webm', getInitData('webm')).then(function(result) {
+ return test_exception(testCase, mediaKeySession);
+ });
+ });
+ promises = promises.concat(WebmSessionPromises);
+ }
+
+ if (isCencSupported) {
+ var mp4SessionPromises = kUpdateSessionExceptionsTestCases.map(function(testCase) {
+ var mediaKeySession = mediaKeys.createSession();
+ return mediaKeySession.generateRequest('cenc', getInitData('cenc')).then(function(result) {
+ return test_exception(testCase, mediaKeySession);
+ });
+ });
+ promises = promises.concat(mp4SessionPromises);
+ }
+
+ assert_not_equals(promises.length, 0);
+ return Promise.all(promises);
+ }).then(function(result) {
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error, 'update() tests failed');
+ });
+ }, 'Test MediaKeySession update() exceptions.');
+
+ function create_update_test(mediaKeys, type, initData)
+ {
+ var mediaKeySession = mediaKeys.createSession();
+ var promise = mediaKeySession.generateRequest(type, initData).then(function(result) {
+ var validLicense = stringToUint8Array(createJWKSet(createJWK(stringToUint8Array('123'), stringToUint8Array('1234567890abcdef'))));
+ return mediaKeySession.update(validLicense);
+ }).then(function(result) {
+ // Call update() with a different license and an extra
+ // parameter. The extra parameter is ignored.
+ var validLicense = stringToUint8Array(createJWKSet(createJWK(stringToUint8Array('4567890'), stringToUint8Array('01234567890abcde'))));
+ return mediaKeySession.update(validLicense, 'extra');
+ });
+ return promise;
+ }
+
+ async_test(function(test)
+ {
+ var isWebmSupported;
+ var isCencSupported;
+
+ isInitDataTypeSupported('webm').then(function(result) {
+ isWebmSupported = result;
+ return isInitDataTypeSupported('cenc');
+ }).then(function(result) {
+ isCencSupported = result;
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}]);
+ }).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var promises = [];
+
+ if (isWebmSupported) {
+ promises.push(create_update_test(mediaKeys, 'webm', getInitData('webm')));
+ }
+
+ if (isCencSupported) {
+ promises.push(create_update_test(mediaKeys, 'cenc', getInitData('cenc')));
+ }
+
+ assert_not_equals(promises.length, 0);
+ return Promise.all(promises);
+ }).then(function(result) {
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error, 'update() tests failed');
+ });
+ }, 'Test MediaKeySession update().');
+
+ function create_close_exception_test(mediaKeys, type, initData)
+ {
+ var mediaKeySession = mediaKeys.createSession();
+ return mediaKeySession.close().then(function(result) {
+ assert_unreached('close() should not succeed if session uninitialized');
+ }).catch(function(error) {
+ assert_equals(error.name, 'InvalidStateError');
+ // Return something so the promise resolves.
+ return Promise.resolve();
+ });
+ }
+
+ async_test(function(test)
+ {
+ var isWebmSupported;
+ var isCencSupported;
+
+ isInitDataTypeSupported('webm').then(function(result) {
+ isWebmSupported = result;
+ return isInitDataTypeSupported('cenc');
+ }).then(function(result) {
+ isCencSupported = result;
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}]);
+ }).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var promises = [];
+
+ if (isWebmSupported) {
+ promises.push(create_close_exception_test(mediaKeys, 'webm', getInitData('webm')));
+ }
+
+ if (isCencSupported) {
+ promises.push(create_close_exception_test(mediaKeys, 'cenc', getInitData('cenc')));
+ }
+
+ assert_not_equals(promises.length, 0);
+ return Promise.all(promises);
+ }).then(function(result) {
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error, 'close() exception tests failed');
+ });
+ }, 'Test MediaKeySession close() exceptions.');
+
+
+ function create_close_test(mediaKeys, type, initData)
+ {
+ var mediaKeySession = mediaKeys.createSession();
+ var promise = mediaKeySession.generateRequest(type, initData).then(function(result) {
+ return mediaKeySession.close();
+ }).then(function(result) {
+ // Call close() again with an extra parameter. The extra
+ // parameter is ignored.
+ return mediaKeySession.close('extra');
+ });
+ return promise;
+ }
+
+ async_test(function(test)
+ {
+ var isWebmSupported;
+ var isCencSupported;
+
+ isInitDataTypeSupported('webm').then(function(result) {
+ isWebmSupported = result;
+ return isInitDataTypeSupported('cenc');
+ }).then(function(result) {
+ isCencSupported = result;
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}]);
+ }).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var promises = [];
+
+ if (isWebmSupported) {
+ promises.push(create_close_test(mediaKeys, 'webm', getInitData('webm')));
+ }
+
+ if (isCencSupported) {
+ promises.push(create_close_test(mediaKeys, 'cenc', getInitData('cenc')));
+ }
+
+ assert_not_equals(promises.length, 0);
+ return Promise.all(promises);
+ }).then(function(result) {
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error, 'close() tests failed');
+ });
+ }, 'Test MediaKeySession close().');
+
+ function create_remove_exception_test(mediaKeys, type, initData)
+ {
+ // remove() on an uninitialized session should fail.
+ var mediaKeySession = mediaKeys.createSession('temporary');
+ return mediaKeySession.remove().then(function(result) {
+ assert_unreached('remove() should not succeed if session uninitialized');
+ }, function(error) {
+ assert_equals(error.name, 'InvalidStateError');
+
+ // remove() on a temporary session should fail.
+ return mediaKeySession.generateRequest(type, initData);
+ }).then(function(result) {
+ return mediaKeySession.remove();
+ }).then(function(result) {
+ assert_unreached('remove() should not succeed for temporary sessions');
+ }, function(error) {
+ assert_equals(error.name, 'InvalidAccessError');
+ });
+ }
+
+ async_test(function(test)
+ {
+ var isWebmSupported;
+ var isCencSupported;
+
+ isInitDataTypeSupported('webm').then(function(result) {
+ isWebmSupported = result;
+ return isInitDataTypeSupported('cenc');
+ }).then(function(result) {
+ isCencSupported = result;
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}]);
+ }).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var promises = [];
+
+ if (isWebmSupported) {
+ promises.push(create_remove_exception_test(mediaKeys, 'webm', getInitData('webm')));
+ }
+
+ if (isCencSupported) {
+ promises.push(create_remove_exception_test(mediaKeys, 'cenc', getInitData('cenc')));
+ }
+
+ assert_not_equals(promises.length, 0);
+ return Promise.all(promises);
+ }).then(function(result) {
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error, 'remove() exception tests failed');
+ });
+ }, 'Test MediaKeySession remove() exceptions.');
+
+ function create_remove_test(mediaKeys, type, initData)
+ {
+ // Clear Key may not support persistent-license sessions.
+ var mediaKeySession;
+ try {
+ mediaKeySession = mediaKeys.createSession('persistent-license');
+ } catch (error) {
+ // Not supported, so return a resolved promise.
+ assert_equals(error.name, 'NotSupportedError');
+ return Promise.resolve();
+ }
+ return mediaKeySession.generateRequest(type, initData).then(function(result) {
+ return mediaKeySession.remove();
+ });
+ }
+
+ async_test(function(test)
+ {
+ var isWebmSupported;
+ var isCencSupported;
+
+ isInitDataTypeSupported('webm').then(function(result) {
+ isWebmSupported = result;
+ return isInitDataTypeSupported('cenc');
+ }).then(function(result) {
+ isCencSupported = result;
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}]);
+ }).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var promises = [];
+
+ if (isWebmSupported) {
+ promises.push(create_remove_test(mediaKeys, 'webm', getInitData('webm')));
+ }
+
+ if (isCencSupported) {
+ promises.push(create_remove_test(mediaKeys, 'cenc', getInitData('cenc')));
+ }
+
+ assert_not_equals(promises.length, 0);
+ return Promise.all(promises);
+ }).then(function(result) {
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error, 'remove() tests failed');
+ });
+ }, 'Test MediaKeySession remove().');
+
+ var kSetServerCertificateExceptionsTestCases = [
+ // Too few parameters.
+ {
+ exception: 'TypeError',
+ func: function(mk) { return mk.setServerCertificate(); }
+ },
+ // Invalid parameters.
+ {
+ exception: 'TypeError',
+ func: function(mk) { return mk.setServerCertificate(''); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk) { return mk.setServerCertificate(null); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk) { return mk.setServerCertificate(undefined); }
+ },
+ {
+ exception: 'TypeError',
+ func: function(mk) { return mk.setServerCertificate(1); }
+ },
+ // Empty array.
+ {
+ exception: 'InvalidAccessError',
+ func: function(mk) { return mk.setServerCertificate(new Uint8Array(0)); }
+ }
+ ];
+
+ async_test(function(test)
+ {
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}]).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var promises = kSetServerCertificateExceptionsTestCases.map(function(testCase) {
+ return test_exception(testCase, mediaKeys);
+ });
+
+ assert_not_equals(promises.length, 0);
+ return Promise.all(promises);
+ }).then(function(result) {
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error, 'setServerCertificate() exception tests failed');
+ });
+ }, 'Test MediaKeys setServerCertificate() exceptions.');
+
+ // All calls to |func| in this group are expected to resolve.
+ var kSetServerCertificateTestCases = [
+ {
+ // Pass in ArrayBufferView
+ func: function(mk) {
+ var cert = new Uint8Array(200);
+ assert_true(ArrayBuffer.isView(cert));
+ return mk.setServerCertificate(cert);
+ },
+ expected: false,
+ },
+ {
+ // Pass in ArrayBuffer
+ func: function(mk) {
+ var buffer = new ArrayBuffer(200);
+ assert_false(ArrayBuffer.isView(buffer));
+ return mk.setServerCertificate(buffer);
+ },
+ expected: false,
+ }
+ ];
+
+ async_test(function(test)
+ {
+ var expected_result;
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}]).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ var promises = kSetServerCertificateTestCases.map(function(testCase) {
+ return testCase.func.call(null, mediaKeys);
+ });
+ expected_result = kSetServerCertificateTestCases.map(function(testCase) {
+ return testCase.expected;
+ });
+
+ assert_not_equals(promises.length, 0);
+ return Promise.all(promises);
+ }).then(function(result) {
+ assert_array_equals(result, expected_result);
+ test.done();
+ }).catch(function(error) {
+ forceTestFailureFromPromise(test, error, 'setServerCertificate() test failed');
+ });
+ }, 'Test MediaKeys setServerCertificate().');
+
+
+ // FIXME: Add syntax checks for MediaKeys.IsTypeSupported().
+ // FIXME: Add syntax checks for MediaKeyError and MediaKeySession events.
+ // FIXME: Add HTMLMediaElement syntax checks, e.g. setMediaKeys, mediakeys, onencrypted.
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-unique-origin.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-unique-origin.html
new file mode 100644
index 000000000..ffb67679f
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-unique-origin.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Unique origin is unable to create MediaKeys</title>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ // When the sandbox attribute is present on an iframe, it will
+ // treat the content as being from a unique origin. So try to
+ // call createMediaKeys() inside an iframe and it should fail.
+
+ function load_iframe(src, sandbox) {
+ return new Promise(function(resolve) {
+ var iframe = document.createElement('iframe');
+ iframe.onload = function() { resolve(iframe); };
+ iframe.sandbox = sandbox;
+ iframe.src = src;
+ document.documentElement.appendChild(iframe);
+ });
+ }
+
+ function wait_for_message() {
+ return new Promise(function(resolve) {
+ self.addEventListener('message', function listener(e) {
+ resolve(e.data);
+ self.removeEventListener('message', listener);
+ });
+ });
+ }
+
+ promise_test(function(test) {
+ var script = 'data:text/html,' +
+ '<script>' +
+ ' window.onmessage = function(e) {' +
+ ' navigator.requestMediaKeySystemAccess(\'org.w3.clearkey\', [{' +
+ ' initDataTypes: [ \'keyids\' ],' +
+ ' audioCapabilities: [' +
+ ' { contentType: \'audio/mp4; codecs="mp4a.40.2"\' },' +
+ ' { contentType: \'audio/webm; codecs="opus"\' }' +
+ ' ]' +
+ ' }]).then(function(access) {' +
+ ' return access.createMediaKeys();' +
+ ' }).then(function(mediaKeys) {' +
+ ' window.parent.postMessage({result: \'allowed\'}, \'*\');' +
+ ' }, function(error) {' +
+ ' window.parent.postMessage({result: \'failed\'}, \'*\');' +
+ ' });' +
+ ' };' +
+ '<\/script>';
+
+ // Verify that this page can create a MediaKeys first.
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{
+ initDataTypes: [ 'keyids' ],
+ audioCapabilities: [
+ { contentType: 'audio/mp4; codecs="mp4a.40.2"' },
+ { contentType: 'audio/webm; codecs="opus"' }
+ ]
+ }]).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ // Success, so now create the iframe and try there.
+ return load_iframe(script, 'allow-scripts')
+ }).then(function(iframe) {
+ iframe.contentWindow.postMessage({}, '*');
+ return wait_for_message();
+ }).then(function(message) {
+ assert_equals(message.result, 'failed');
+ });
+ }, 'Unique origin is unable to create MediaKeys');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-update-disallowed-input.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-update-disallowed-input.html
new file mode 100644
index 000000000..e829a885c
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-update-disallowed-input.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Test handling of invalid responses for update().</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ // This test passes |response| to update() as a JSON Web Key Set.
+ // CDMs other than Clear Key won't expect |response| in this format.
+
+ async_test(function(test)
+ {
+ var initDataType;
+ var initData;
+ var mediaKeySession;
+
+ function repeat(pattern, count) {
+ var result = '';
+ while (count > 1) {
+ if (count & 1) result += pattern;
+ count >>= 1;
+ pattern += pattern;
+ }
+ return result + pattern;
+ }
+
+ function createReallyLongJWKSet()
+ {
+ // This is just a standard JWKSet with a lot of
+ // extra items added to the end. Key ID and key
+ // doesn't really matter.
+ var jwkSet = '{"keys":[{'
+ + '"kty":"oct",'
+ + '"k":"MDEyMzQ1Njc4OTAxMjM0NQ",'
+ + '"kid":"MDEyMzQ1Njc4OTAxMjM0NQ"'
+ + '}]';
+ return jwkSet + repeat(',"test":"unknown"', 4000) + '}';
+ }
+
+ function processMessage(event)
+ {
+ var jwkSet = createReallyLongJWKSet();
+ assert_greater_than(jwkSet.length, 65536);
+ var jwkSetArray = stringToUint8Array(jwkSet);
+ mediaKeySession.update(jwkSetArray).then(function() {
+ forceTestFailureFromPromise(test, 'Error: update() succeeded');
+ }, function(error) {
+ assert_equals(error.name, 'InvalidAccessError');
+ test.done();
+ });
+ }
+
+ navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
+ initDataType = access.getConfiguration().initDataTypes[0];
+ initData = getInitData(initDataType);
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ mediaKeySession = mediaKeys.createSession();
+ waitForEventAndRunStep('message', mediaKeySession, processMessage, test);
+ return mediaKeySession.generateRequest(initDataType, initData);
+ });
+ }, 'update() with response longer than 64Kb characters.');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-utils.js b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-utils.js
new file mode 100644
index 000000000..5fbcdf689
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-utils.js
@@ -0,0 +1,333 @@
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+
+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);
+}
+
+// Returns a promise that is fulfilled with true if |initDataType| is supported,
+// or false if not.
+function isInitDataTypeSupported(initDataType)
+{
+ return navigator.requestMediaKeySystemAccess(
+ "org.w3.clearkey", getSimpleConfigurationForInitDataType(initDataType))
+ .then(function() { return true; }, function() { return false; });
+}
+
+function getInitData(initDataType)
+{
+ 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 = 52
+ 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, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // key
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x00, 0x00, 0x00, 0x00 // datasize
+ ]);
+ }
+
+ if (initDataType == 'keyids') {
+ var keyId = new Uint8Array([
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+ ]);
+ return stringToUint8Array(createKeyIDs(keyId));
+ }
+
+ throw 'initDataType ' + initDataType + ' not supported.';
+}
+
+// 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 MediaKeySystemConfiguration for |mediaFile| that specifies
+// both audio and video capabilities for the specified file..
+function getConfigurationForFile(mediaFile)
+{
+ if (mediaFile.toLowerCase().endsWith('webm')) {
+ return [ {
+ initDataTypes: [ 'webm' ],
+ audioCapabilities: [ { contentType: 'audio/webm; codecs="opus"' } ],
+ videoCapabilities: [ { contentType: 'video/webm; codecs="vp8"' } ]
+ } ];
+ }
+
+ // NOTE: Supporting other mediaFormats is not currently implemented as
+ // Chromium only tests with WebM files.
+ throw 'mediaFile ' + mediaFile + ' not supported.';
+}
+
+function waitForEventAndRunStep(eventName, element, func, stepTest)
+{
+ var eventCallback = function(event) {
+ if (func)
+ func(event);
+ }
+ if (stepTest)
+ eventCallback = stepTest.step_func(eventCallback);
+
+ element.addEventListener(eventName, eventCallback, true);
+}
+
+// Copied from LayoutTests/resources/js-test.js.
+// See it for details of why this is necessary.
+function asyncGC(callback)
+{
+ GCController.collectAll();
+ setTimeout(callback, 0);
+}
+
+function createGCPromise()
+{
+ // Run gc() as a promise.
+ return new Promise(
+ function(resolve, reject) {
+ asyncGC(resolve);
+ });
+}
+
+function delayToAllowEventProcessingPromise()
+{
+ return new Promise(
+ function(resolve, reject) {
+ setTimeout(resolve, 0);
+ });
+}
+
+function stringToUint8Array(str)
+{
+ var result = new Uint8Array(str.length);
+ for(var i = 0; i < str.length; i++) {
+ result[i] = str.charCodeAt(i);
+ }
+ return result;
+}
+
+function arrayBufferAsString(buffer)
+{
+ // MediaKeySession.keyStatuses iterators return an ArrayBuffer,
+ // so convert it into a printable string.
+ return String.fromCharCode.apply(null, new Uint8Array(buffer));
+}
+
+function dumpKeyStatuses(keyStatuses)
+{
+ 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);
+ });
+}
+
+// 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);
+
+ // All |keys.expected| should be found.
+ expected.map(function(key) {
+ assert_true(keyStatuses.has(key));
+ assert_equals(keyStatuses.get(key), 'usable');
+ });
+
+ // All |keys.unexpected| should not be found.
+ unexpected.map(function(key) {
+ assert_false(keyStatuses.has(key));
+ assert_equals(keyStatuses.get(key), undefined);
+ });
+}
+
+// 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, "/"));
+}
+
+// For Clear Key, the License Format is a JSON Web Key (JWK) Set, which contains
+// a set of cryptographic keys represented by JSON. These helper functions help
+// wrap raw keys into a JWK set.
+// See:
+// https://w3c.github.io/encrypted-media/#clear-key-license-format
+// http://tools.ietf.org/html/draft-ietf-jose-json-web-key
+//
+// Creates a JWK from raw key ID and key.
+// |keyId| and |key| are expected to be ArrayBufferViews, not base64-encoded.
+function createJWK(keyId, key)
+{
+ var jwk = '{"kty":"oct","alg":"A128KW","kid":"';
+ jwk += base64urlEncode(keyId);
+ jwk += '","k":"';
+ jwk += base64urlEncode(key);
+ jwk += '"}';
+ return jwk;
+}
+
+// Creates a JWK Set from multiple JWKs.
+function createJWKSet()
+{
+ var jwkSet = '{"keys":[';
+ for (var i = 0; i < arguments.length; i++) {
+ if (i != 0)
+ jwkSet += ',';
+ jwkSet += arguments[i];
+ }
+ jwkSet += ']}';
+ return jwkSet;
+}
+
+// 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 forceTestFailureFromPromise(test, error, message)
+{
+ // Promises convert exceptions into rejected Promises. Since there is
+ // currently no way to report a failed test in the test harness, errors
+ // are reported using force_timeout().
+ if (message)
+ consoleWrite(message + ': ' + error.message);
+ else if (error)
+ consoleWrite(error);
+
+ test.force_timeout();
+ test.done();
+}
+
+function extractSingleKeyIdFromMessage(message)
+{
+ var json = JSON.parse(String.fromCharCode.apply(null, new Uint8Array(message)));
+ // Decode the first element of 'kids'.
+ assert_equals(1, json.kids.length);
+ var decoded_key = base64urlDecode(json.kids[0]);
+ // Convert to an Uint8Array and return it.
+ return stringToUint8Array(decoded_key);
+}
+
+// Create a MediaKeys object for Clear Key with 1 session. KeyId and key
+// required for the video are already known and provided. Returns a promise
+// that resolves to the MediaKeys object created.
+function createMediaKeys(keyId, key)
+{
+ var mediaKeys;
+ var mediaKeySession;
+ var request = stringToUint8Array(createKeyIDs(keyId));
+ var jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, key)));
+
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfigurationForInitDataType('keyids')).then(function(access) {
+ return access.createMediaKeys();
+ }).then(function(result) {
+ mediaKeys = result;
+ mediaKeySession = mediaKeys.createSession();
+ return mediaKeySession.generateRequest('keyids', request);
+ }).then(function() {
+ return mediaKeySession.update(jwkSet);
+ }).then(function() {
+ return Promise.resolve(mediaKeys);
+ });
+}
+
+// Play the specified |content| on |video|. Returns a promise that is resolved
+// after the video plays for |duration| seconds.
+function playVideoAndWaitForTimeupdate(video, content, duration)
+{
+ video.src = content;
+ video.play();
+ return new Promise(function(resolve) {
+ video.addEventListener('timeupdate', function listener(event) {
+ if (event.target.currentTime < duration)
+ return;
+ video.removeEventListener('timeupdate', listener);
+ resolve('success');
+ });
+ });
+}
diff --git a/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-waiting-for-a-key.html b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-waiting-for-a-key.html
new file mode 100644
index 000000000..2af37cfb9
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-waiting-for-a-key.html
@@ -0,0 +1,168 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>Waiting for a key.</title>
+ <script src="encrypted-media-utils.js"></script>
+<!--
+ Test has been migrated to the root directory and is being disabled here.
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+-->
+ </head>
+ <body>
+ <video id="testVideo"></video>
+ <div id="log"></div>
+ <script>
+ // For debugging timeouts, keep track of the number of the
+ // various events received.
+ var debugEncryptedEventCount = 0;
+ var debugWaitingForKeyEventCount = 0;
+ var debugTimeUpdateEventCount = 0;
+ var debugMessage = '';
+
+ promise_test(function(test)
+ {
+ var video = document.getElementById('testVideo');
+ var content = 'webm/test-encrypted.webm';
+ var initData;
+ var initDataType;
+ var mediaKeySession;
+
+ test.timeout = function()
+ {
+ var message = 'timeout. message = ' + debugMessage
+ + ', encrypted: ' + debugEncryptedEventCount
+ + ', waitingforkey: ' + debugWaitingForKeyEventCount
+ + ', timeupdate: ' + debugTimeUpdateEventCount;
+ test.force_timeout();
+ test.timeout_id = null;
+ test.set_status(2, message);
+ test.done();
+ };
+
+ // As this code doesn't wait for the 'message' event to avoid
+ // race conditions with 'waitingforkey', specify the key ID and
+ // key used by the encrypted content.
+ var keyId = stringToUint8Array('0123456789012345');
+ var rawKey = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
+ 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);
+
+ return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getConfigurationForFile(content)).then(function(access) {
+ debugMessage = 'createMediaKeys()';
+ return access.createMediaKeys();
+ }).then(function(mediaKeys) {
+ debugMessage = 'setMediaKeys()';
+ return video.setMediaKeys(mediaKeys);
+ }).then(function() {
+ video.src = content;
+ video.play();
+ debugMessage = 'wait_for_encrypted_event()';
+ return wait_for_encrypted_event(video);
+ }).then(function(e) {
+ // Received the 'encrypted' event(s), so keep a copy of
+ // the initdata for use when creating the session later.
+ initData = e.initData;
+ initDataType = e.initDataType;
+
+ // Wait until the video indicates that it needs a key to
+ // continue.
+ debugMessage = 'wait_for_waitingforkey_event()';
+ return wait_for_waitingforkey_event(video);
+ }).then(function() {
+ // Make sure the video is NOT paused and not progressing
+ // before a key is provided. This requires the video
+ // to NOT have a clear lead.
+ assert_false(video.paused);
+ assert_equals(video.currentTime, 0);
+
+ // Create a session.
+ mediaKeySession = video.mediaKeys.createSession();
+ debugMessage = 'generateRequest()';
+ return mediaKeySession.generateRequest(initDataType, initData);
+ }).then(function() {
+ // generateRequest() will cause a 'message' event to
+ // occur specifying the keyId that is needed, but we
+ // ignore it since we already know what keyId is needed.
+ // Add the key needed to decrypt.
+ var jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, rawKey)));
+ debugMessage = 'update()';
+ return mediaKeySession.update(jwkSet);
+ }).then(function() {
+ // Video should start playing now that it can decrypt the
+ // streams, so wait until a little bit of the video has
+ // played.
+ debugMessage = 'wait_for_timeupdate_event()';
+ return wait_for_timeupdate_event(video);
+ });
+
+ // Typical test duration is 6 seconds on release builds
+ // (12 seconds on debug). Since the test is timing out anyway,
+ // make the duration 5 seconds so that the timeout function
+ // is actually called (instead of simply aborting the test).
+ }, 'Waiting for a key.', { timeout: 5000 });
+
+ // Wait for a pair of 'encrypted' events. Promise resolved on
+ // second event.
+ function wait_for_encrypted_event(video)
+ {
+ var encryptedEventCount = 0;
+ return new Promise(function(resolve) {
+ video.addEventListener('encrypted', function listener(e) {
+ assert_equals(e.target, video);
+ assert_true(e instanceof window.MediaEncryptedEvent);
+ assert_equals(e.type, 'encrypted');
+
+ // The same decryption key is used by both the audio
+ // and the video streams so wait for the second event
+ // to ensure we see both events.
+ ++debugEncryptedEventCount;
+ if (++encryptedEventCount != 2)
+ return;
+
+ video.removeEventListener('encrypted', listener);
+ resolve(e);
+ });
+ });
+ };
+
+ // Wait for a 'waitingforkey' event. Promise resolved when the
+ // event is received.
+ function wait_for_waitingforkey_event(video)
+ {
+ var waitingForKeyEventCount = 0;
+ return new Promise(function(resolve) {
+ video.addEventListener('waitingforkey', function listener(e) {
+ assert_equals(e.target, video);
+ assert_equals(e.type, 'waitingforkey');
+
+ ++debugWaitingForKeyEventCount;
+ ++waitingForKeyEventCount;
+ // TODO(jrummell): waitingforkey event should only
+ // occur once. http://crbug.com/461903
+// assert_equals(waitingForKeyEventCount, 1, 'Multiple waitingforkey events');
+
+ video.removeEventListener('waitingforkey', listener);
+ resolve(e);
+ });
+ });
+ };
+
+ // Wait for a 'timeupdate' event. Promise resolved if |video| has
+ // played for more than 0.2 seconds.
+ function wait_for_timeupdate_event(video)
+ {
+ return new Promise(function(resolve) {
+ video.addEventListener('timeupdate', function listener(e) {
+ assert_equals(e.target, video);
+ ++debugTimeUpdateEventCount;
+ if (video.currentTime < 0.2)
+ return;
+ video.removeEventListener('timeupdate', listener);
+ resolve(e);
+ });
+ });
+ };
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/encrypted-media/Google/webm/test-encrypted-different-av-keys.webm b/testing/web-platform/tests/encrypted-media/Google/webm/test-encrypted-different-av-keys.webm
new file mode 100644
index 000000000..5a29f659b
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/webm/test-encrypted-different-av-keys.webm
Binary files differ
diff --git a/testing/web-platform/tests/encrypted-media/Google/webm/test-encrypted.webm b/testing/web-platform/tests/encrypted-media/Google/webm/test-encrypted.webm
new file mode 100644
index 000000000..8d44931e8
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/webm/test-encrypted.webm
Binary files differ
diff --git a/testing/web-platform/tests/encrypted-media/Google/webm/test.webm b/testing/web-platform/tests/encrypted-media/Google/webm/test.webm
new file mode 100644
index 000000000..6c2138d4e
--- /dev/null
+++ b/testing/web-platform/tests/encrypted-media/Google/webm/test.webm
Binary files differ