media: Require SecureContext for EME APIs

In this CL requestMediaKeySystemAccess() requires SecureContext. On
non-SecureContext, this API will not be visible.

Some notes for future reference:

1. file:// is always treated as SecureContext.
2. file:// is not a unique origin. The origin string is "file://"
3. LoadFromData is treated as non-SecureContext. See the updated [1]
   in this CL.
4. LoadFromData is also treated as unique origin. This is what [1]
   used to test without this CL.
5. allowFileAccessFromFileURLs has nothing to do with SecureContext.
   Rather it controls whether you can load other files from file://.
   - So if you run a simple html page on file://, and that file
     doesn't depend on any other file, you don't need
     allowFileAccessFromFileURLs. This is why for [2] we don't
     really need allowFileAccessFromFileURLs.
   - If the html page depends on other js files, without
     allowFileAccessFromFileURLs, those js files will not be loaded.
     This will cause a lot of test failures. That's why in content
     shell, we have allowFileAccessFromFileURLs enabled by default.

[1]
third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-unique-origin.html
[2] android_webview/test/shell/assets/key-system-test.html

BUG=672605
TEST=Manually tested and made sure EME APIs are not available on
insecure origins.

Review-Url: https://codereview.chromium.org/2678433003
Cr-Commit-Position: refs/heads/master@{#449344}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/KeySystemTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/KeySystemTest.java
index 3bda004..d00a3da9 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/KeySystemTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/KeySystemTest.java
@@ -50,36 +50,8 @@
         mAwContents = testContainerView.getAwContents();
         enableJavaScriptOnUiThread(mAwContents);
 
-        loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
-                getKeySystemTestPage(), "text/html", false);
-    }
-
-    private String getKeySystemTestPage() {
-        // requestMediaKeySystemAccess() provides 2 different configurations
-        // as encrypted webm is only supported on Lollipop+. mp4 is proprietary,
-        // and may not be supported on all Android devices.
-        return "<html> <script>"
-                + "var result;"
-                + "function success(keySystemAccess) {"
-                + "  result = 'supported';"
-                + "}"
-                + "function failure(error){"
-                + "  result = error.name;"
-                + "}"
-                + "function isKeySystemSupported(keySystem) {"
-                + "  navigator.requestMediaKeySystemAccess("
-                + "     keySystem, "
-                + "     [{audioCapabilities:"
-                + "         [{contentType: 'audio/webm; codec=\"vorbis\"'}]}, "
-                + "      {videoCapabilities:"
-                + "         [{contentType: 'video/mp4; codecs=\"avc1.4D000C\"'}]}])"
-                + "  .then(success, failure);"
-                + "}"
-                + "function areProprietaryCodecsSupported() {"
-                + "  var video = document.createElement('video');"
-                + "  return video.canPlayType('video/mp4; codecs=\"avc1\"');"
-                + "}"
-                + "</script> </html>";
+        loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
+                "file:///android_asset/key-system-test.html");
     }
 
     private String isKeySystemSupported(String keySystem) throws Exception {
diff --git a/android_webview/test/BUILD.gn b/android_webview/test/BUILD.gn
index e341ddf0..a638337 100644
--- a/android_webview/test/BUILD.gn
+++ b/android_webview/test/BUILD.gn
@@ -75,6 +75,7 @@
     "shell/assets/full_screen_video_inside_div_test.html",
     "shell/assets/full_screen_video_test.html",
     "shell/assets/full_screen_video_test_not_preloaded.html",
+    "shell/assets/key-system-test.html",
     "shell/assets/platform-media-codec-test.html",
     "shell/assets/video.3gp",
     "shell/assets/video.webm",
diff --git a/android_webview/test/shell/assets/key-system-test.html b/android_webview/test/shell/assets/key-system-test.html
new file mode 100644
index 0000000..0de0b9f
--- /dev/null
+++ b/android_webview/test/shell/assets/key-system-test.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+
+<html>
+<script>
+
+var result;
+
+function success(keySystemAccess) {
+  result = 'supported';
+}
+
+function failure(error) {
+  result = error.name;
+}
+
+function isKeySystemSupported(keySystem) {
+  // requestMediaKeySystemAccess() provides 2 different configurations
+  // as encrypted webm is only supported on Lollipop+. mp4 is proprietary,
+  // and may not be supported on all Android devices.
+  navigator
+      .requestMediaKeySystemAccess(
+          keySystem,
+          [
+            {
+              audioCapabilities :
+                  [ {contentType : 'audio/webm; codec=\"vorbis\"'} ]
+            },
+            {
+              videoCapabilities :
+                  [ {contentType : 'video/mp4; codecs=\"avc1.4D000C\"'} ]
+            }
+          ])
+      .then(success, failure);
+}
+
+function areProprietaryCodecsSupported() {
+  var video = document.createElement('video');
+  return video.canPlayType('video/mp4; codecs=\"avc1\"');
+}
+
+</script>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/old-powerful-features-on-insecure-origin-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/old-powerful-features-on-insecure-origin-expected.txt
index e04c515fc..5db49111 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/old-powerful-features-on-insecure-origin-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/old-powerful-features-on-insecure-origin-expected.txt
@@ -1,17 +1,16 @@
 CONSOLE WARNING: Use of the Application Cache is deprecated on insecure origins. Support will be removed in the future. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.
-CONSOLE WARNING: line 27: The devicemotion event is deprecated on insecure origins, and support will be removed in the future. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.
-CONSOLE WARNING: line 32: The deviceorientation event is deprecated on insecure origins, and support will be removed in the future. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.
-CONSOLE WARNING: line 42: getCurrentPosition() and watchPosition() no longer work on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.
-CONSOLE WARNING: line 61: getUserMedia() no longer works on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.
-CONSOLE WARNING: line 36: Using requestMediaKeySystemAccess() on insecure origins is deprecated and will be removed in M58, around April 2017. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.
+CONSOLE WARNING: line 26: The devicemotion event is deprecated on insecure origins, and support will be removed in the future. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.
+CONSOLE WARNING: line 31: The deviceorientation event is deprecated on insecure origins, and support will be removed in the future. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.
+CONSOLE WARNING: line 36: getCurrentPosition() and watchPosition() no longer work on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.
+CONSOLE WARNING: line 55: getUserMedia() no longer works on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.
 This is a testharness.js-based test.
 PASS device motion 
 PASS device orientation 
-PASS requestMediaKeySystemAccess 
 PASS getCurrentPosition 
 PASS watchPosition 
 PASS navigator.webkitGetUserMedia 
 PASS navigator.mediaDevices.getUserMedia 
 PASS appcache 
+PASS requestMediaKeySystemAccess 
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/old-powerful-features-on-insecure-origin.html b/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/old-powerful-features-on-insecure-origin.html
index 528fb97..e041c398 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/old-powerful-features-on-insecure-origin.html
+++ b/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/old-powerful-features-on-insecure-origin.html
@@ -16,7 +16,6 @@
     if (!window.internals)
         assert_unreached('window.internals is required for this test');
 
-
     // Tests for APIs that are deprecated, but still allowed, on
     // insecure origins
     async_test(function() {
@@ -32,11 +31,6 @@
         window.addEventListener('deviceorientation', this.step_func_done());
     }, 'device orientation');
 
-    promise_test(function(test) {
-        return navigator.requestMediaKeySystemAccess('org.w3.clearkey',
-            [{ videoCapabilities: [{contentType: 'video/webm; codecs="vp9"'}] }]);
-    }, 'requestMediaKeySystemAccess');
-
     // Tests for APIs that have been turned off on insecure origins
     async_test(function() {
         navigator.geolocation.getCurrentPosition(
@@ -87,6 +81,10 @@
 
         applicationCache.addEventListener('cached', cached, false);
     }, 'appcache');
+
+    test(function() {
+      assert_false('requestMediaKeySystemAccess' in navigator);
+    }, 'requestMediaKeySystemAccess');
 }
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-unique-origin.html b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-unique-origin.html
index 4492bde..bfadd30 100644
--- a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-unique-origin.html
+++ b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-unique-origin.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
     <head>
-        <title>Unique origin is unable to create MediaKeys</title>
+        <title>requestMediaKeySystemAccess() is not available on unique origin</title>
         <script src="../../resources/testharness.js"></script>
         <script src="../../resources/testharnessreport.js"></script>
     </head>
@@ -31,22 +31,15 @@
             }
 
             promise_test(function(test) {
+                // TODO(xhwang): Also check other EME APIs.
                 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\'}, \'*\');' +
-                    '        });' +
+                    '        if (\'requestMediaKeySystemAccess\' in navigator) {' +
+                    '            window.parent.postMessage({result: \'available\'}, \'*\');' +
+                    '        } else { ' +
+                    '            window.parent.postMessage({result: \'unavailable\'}, \'*\');' +
+                    '        }' +
                     '    };' +
                     '<\/script>';
 
@@ -66,9 +59,9 @@
                     iframe.contentWindow.postMessage({}, '*');
                     return wait_for_message();
                 }).then(function(message) {
-                    assert_equals(message.result, 'failed');
+                    assert_equals(message.result, 'unavailable');
                 });
-            }, 'Unique origin is unable to create MediaKeys');
+            }, 'requestMediaKeySystemAccess() is not available on unique origin');
         </script>
     </body>
 </html>
diff --git a/third_party/WebKit/Source/core/frame/Deprecation.cpp b/third_party/WebKit/Source/core/frame/Deprecation.cpp
index cd5cf67..cbba6d4 100644
--- a/third_party/WebKit/Source/core/frame/Deprecation.cpp
+++ b/third_party/WebKit/Source/core/frame/Deprecation.cpp
@@ -324,14 +324,6 @@
              "secure origin, such as HTTPS. See https://goo.gl/rStTGz for more "
              "details.";
 
-    case UseCounter::EncryptedMediaInsecureOrigin:
-      return String::format(
-          "Using requestMediaKeySystemAccess() on insecure origins is "
-          "deprecated and will be removed in %s. You should consider "
-          "switching your application to a secure origin, such as HTTPS. See "
-          "https://goo.gl/rStTGz for more details.",
-          milestoneString(M58));
-
     case UseCounter::MediaSourceAbortRemove:
       return "Using SourceBuffer.abort() to abort remove()'s asynchronous "
              "range removal is deprecated due to specification change. Support "
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h
index c5548f7..5392204 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -569,8 +569,6 @@
     FullscreenInsecureOrigin = 766,
     DialogInSandboxedContext = 767,
     SVGSMILAnimationInImageRegardlessOfCache = 768,
-    EncryptedMediaSecureOrigin = 770,
-    EncryptedMediaInsecureOrigin = 771,
     PerformanceFrameTiming = 772,
     V8Element_Animate_Method = 773,
     // The above items are available in M44 branch.
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.idl b/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.idl
index 7998203..37b49db 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.idl
+++ b/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.idl
@@ -1,10 +1,9 @@
 // Copyright 2014 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-
 partial interface HTMLMediaElement {
     readonly attribute MediaKeys mediaKeys;
-    [CallWith=ScriptState] Promise setMediaKeys(MediaKeys? mediaKeys);
+    [SecureContext, CallWith=ScriptState] Promise setMediaKeys(MediaKeys? mediaKeys);
     attribute EventHandler onencrypted;
     attribute EventHandler onwaitingforkey;
 };
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.idl b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.idl
index 0863a83..a716f07 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.idl
+++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.idl
@@ -31,6 +31,7 @@
 [
     ActiveScriptWrappable,
     DependentLifetime,
+    SecureContext,
 ] interface MediaKeys {
     [CallWith=ScriptState, RaisesException] MediaKeySession createSession(optional MediaKeySessionType sessionType = "temporary");
 
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp b/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp
index ae354cf..96c4f007 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp
+++ b/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp
@@ -339,19 +339,6 @@
                          "The supportedConfigurations parameter is empty."));
   }
 
-  // Note: This method should only be exposed to secure contexts as indicated
-  // by the [SecureContext] IDL attribute. Since that will break some existing
-  // sites, we simply keep track of sites that aren't secure and output a
-  // deprecation message.
-  if (executionContext->isSecureContext()) {
-    UseCounter::count(executionContext, UseCounter::EncryptedMediaSecureOrigin);
-  } else {
-    Deprecation::countDeprecation(executionContext,
-                                  UseCounter::EncryptedMediaInsecureOrigin);
-    // TODO(ddorwin): Implement the following:
-    // Reject promise with a new DOMException whose name is NotSupportedError.
-  }
-
   // 3. Let document be the calling context's Document.
   //    (Done at the begining of this function.)
   if (!document->page()) {
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.idl b/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.idl
index 62c96b7..2ea077a 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.idl
+++ b/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.idl
@@ -5,5 +5,5 @@
 // https://w3c.github.io/encrypted-media/#navigator-extension-requestmediakeysystemaccess
 
 partial interface Navigator {
-    [CallWith=ScriptState] Promise<MediaKeySystemAccess> requestMediaKeySystemAccess(DOMString keySystem, sequence<MediaKeySystemConfiguration> supportedConfigurations);
+    [SecureContext, CallWith=ScriptState] Promise<MediaKeySystemAccess> requestMediaKeySystemAccess(DOMString keySystem, sequence<MediaKeySystemConfiguration> supportedConfigurations);
 };