Implementation for feature policy - fullscreen
Disable fullscreen API unless enabled through feature policy.
BUG=666761
Review-Url: https://codereview.chromium.org/2499373002
Cr-Commit-Position: refs/heads/master@{#436651}
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-disabled-expected.txt b/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-disabled-expected.txt
new file mode 100644
index 0000000..b3040c2a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-disabled-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+PASS Fullscreen disabled on URL: resources/feature-policy-fullscreen.html with allowfullscreen = false
+PASS Fullscreen disabled on URL: http://localhost:8000/feature-policy/resources/feature-policy-fullscreen.html with allowfullscreen = false
+FAIL Fullscreen disabled on URL: resources/feature-policy-fullscreen.html with allowfullscreen = true assert_false: Document.fullscreenEnabled: expected false got true
+FAIL Fullscreen disabled on URL: http://localhost:8000/feature-policy/resources/feature-policy-fullscreen.html with allowfullscreen = true assert_false: Document.fullscreenEnabled: expected false got true
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-disabled.php b/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-disabled.php
new file mode 100644
index 0000000..fade4c3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-disabled.php
@@ -0,0 +1,43 @@
+<?php
+// Copyright 2016 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.
+
+// This test ensures that fullscreen feature when disabled may not be called by
+// any iframe even when allowfullscreen is set.
+
+Header("Feature-Policy: {\"fullscreen\": []}");
+?>
+
+<!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<iframe id="f1"></iframe>
+<iframe id="f2" allowfullscreen></iframe>
+<script>
+var srcs = [
+ "resources/feature-policy-fullscreen.html",
+ "http://localhost:8000/feature-policy/resources/feature-policy-fullscreen.html"
+];
+var f1 = document.getElementById('f1');
+var f2 = document.getElementById('f2');
+
+function loadFrames(iframe) {
+ for (var src of srcs) {
+ promise_test(function() {
+ iframe.src = src;
+ return new Promise(function(resolve, reject) {
+ window.addEventListener('message', function(e) {
+ resolve(e.data);
+ }, { once: true });
+ }).then(function(data) {
+ assert_false(data.enabled, 'Document.fullscreenEnabled:');
+ assert_equals(data.type, 'error', 'Document.requestFullscreen():');
+ });
+ }, 'Fullscreen disabled on URL: ' + src + ' with allowfullscreen = ' + iframe.allowFullscreen);
+ }
+}
+
+loadFrames(f1);
+loadFrames(f2);
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-enabledforall.php b/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-enabledforall.php
new file mode 100644
index 0000000..18f970a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-enabledforall.php
@@ -0,0 +1,49 @@
+<?php
+// Copyright 2016 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.
+
+// This test ensures that fullscreen feature when enabled for all works across
+// origins when allowfullscreen is set. No iframe may call it when
+// allowfullscreen is not set.
+
+Header("Feature-Policy: {\"fullscreen\": [\"*\"]}");
+?>
+
+<!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<iframe id="f1"></iframe>
+<iframe id="f2" allowfullscreen></iframe>
+<script>
+var srcs = [
+ "resources/feature-policy-fullscreen.html",
+ "http://localhost:8000/feature-policy/resources/feature-policy-fullscreen.html"
+];
+var f1 = document.getElementById('f1');
+var f2 = document.getElementById('f2');
+
+function loadFrames(iframe) {
+ for (var src of srcs) {
+ promise_test(function(t) {
+ iframe.src = src;
+ return new Promise(function(resolve, reject) {
+ window.addEventListener('message', function(e) {
+ resolve(e.data);
+ }, { once: true });
+ }).then(function(data) {
+ if (iframe.id === "f2") {
+ assert_true(data.enabled, 'Document.fullscreenEnabled:');
+ assert_equals(data.type, 'change', 'Document.requestFullscreen():');
+ } else {
+ assert_false(data.enabled, 'Document.fullscreenEnabled:');
+ assert_equals(data.type, 'error', 'Document.requestFullscreen():');
+ }
+ });
+ }, 'Fullscreen enabled for all on URL: ' + src + ' with allowfullscreen = ' + iframe.allowFullscreen);
+ }
+}
+
+loadFrames(f1);
+loadFrames(f2);
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-enabledforself.php b/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-enabledforself.php
new file mode 100644
index 0000000..42296132
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-enabledforself.php
@@ -0,0 +1,49 @@
+<?php
+// Copyright 2016 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.
+
+// This test ensures that fullscreen feature when enabled for self only works
+// in the same orgin but not cross origins when allowfullscreen is set. No
+// iframe may call it when allowfullscreen is not set.
+
+Header("Feature-Policy: {\"fullscreen\": [\"self\"]}");
+?>
+
+<!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<iframe id="f1"></iframe>
+<iframe id="f2" allowfullscreen></iframe>
+<script>
+var srcs = [
+ "resources/feature-policy-fullscreen.html",
+ "http://localhost:8000/feature-policy/resources/feature-policy-fullscreen.html"
+];
+var f1 = document.getElementById('f1');
+var f2 = document.getElementById('f2');
+
+function loadFrames(iframe) {
+ for (var src of srcs) {
+ promise_test(function(t) {
+ iframe.src = src;
+ return new Promise(function(resolve, reject) {
+ window.addEventListener('message', function(e) {
+ resolve(e.data);
+ }, { once: true });
+ }).then(function(data) {
+ if (src === srcs[0] || iframe.id === "f2") {
+ assert_true(data.enabled, 'Document.fullscreenEnabled:');
+ assert_equals(data.type, 'change', 'Document.requestFullscreen():');
+ } else {
+ assert_false(data.enabled, 'Document.fullscreenEnabled:');
+ assert_equals(data.type, 'error', 'Document.requestFullscreen():');
+ }
+ });
+ }, 'Fullscreen enabled for self on URL: ' + src + ' with allowfullscreen = ' + iframe.allowFullscreen);
+ }
+}
+
+loadFrames(f1);
+loadFrames(f2);
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/resources/feature-policy-fullscreen.html b/third_party/WebKit/LayoutTests/http/tests/feature-policy/resources/feature-policy-fullscreen.html
new file mode 100644
index 0000000..1fe1b74
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/feature-policy/resources/feature-policy-fullscreen.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<title>Feature-Policy Fullscreen</title>
+<div>Fullscreen</div>
+<script>
+document.onwebkitfullscreenerror = function() {
+ parent.postMessage({ type: 'error', enabled: document.webkitFullscreenEnabled }, '*');
+};
+
+document.onwebkitfullscreenchange = function() {
+ document.webkitExitFullscreen();
+ parent.postMessage({ type: 'change', enabled: document.webkitFullscreenEnabled }, '*');
+};
+
+document.addEventListener('keypress', function() {
+ document.querySelector('div').webkitRequestFullscreen();
+});
+
+window.onload = function() {
+ focus();
+ eventSender.keyDown('a', []);
+}
+</script>
diff --git a/third_party/WebKit/LayoutTests/virtual/feature-policy/http/tests/feature-policy/fullscreen-disabled-expected.txt b/third_party/WebKit/LayoutTests/virtual/feature-policy/http/tests/feature-policy/fullscreen-disabled-expected.txt
new file mode 100644
index 0000000..ca7eb48
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/feature-policy/http/tests/feature-policy/fullscreen-disabled-expected.txt
@@ -0,0 +1,11 @@
+CONSOLE WARNING: line 15: Fullscreen API is disabled by feature policy for this frame
+CONSOLE WARNING: line 6: Fullscreen API is disabled by feature policy for this frame
+CONSOLE WARNING: line 15: Fullscreen API is disabled by feature policy for this frame
+CONSOLE WARNING: line 6: Fullscreen API is disabled by feature policy for this frame
+This is a testharness.js-based test.
+PASS Fullscreen disabled on URL: resources/feature-policy-fullscreen.html with allowfullscreen = false
+PASS Fullscreen disabled on URL: http://localhost:8000/feature-policy/resources/feature-policy-fullscreen.html with allowfullscreen = false
+PASS Fullscreen disabled on URL: resources/feature-policy-fullscreen.html with allowfullscreen = true
+PASS Fullscreen disabled on URL: http://localhost:8000/feature-policy/resources/feature-policy-fullscreen.html with allowfullscreen = true
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/Source/core/dom/Fullscreen.cpp b/third_party/WebKit/Source/core/dom/Fullscreen.cpp
index 5ff6e9a..c168a417 100644
--- a/third_party/WebKit/Source/core/dom/Fullscreen.cpp
+++ b/third_party/WebKit/Source/core/dom/Fullscreen.cpp
@@ -29,6 +29,7 @@
#include "core/dom/Fullscreen.h"
+#include "bindings/core/v8/ConditionalFeatures.h"
#include "core/dom/Document.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/StyleEngine.h"
@@ -99,10 +100,43 @@
}
// https://fullscreen.spec.whatwg.org/#fullscreen-is-supported
-bool fullscreenIsSupported(const Document& document) {
+// TODO(lunalu): update the placement of the feature policy code once it is in
+// https://fullscreen.spec.whatwg.org/.
+bool fullscreenIsSupported(Document& document) {
+ LocalFrame* frame = document.frame();
+ if (!frame)
+ return false;
+
// Fullscreen is supported if there is no previously-established user
// preference, security risk, or platform limitation.
- return !document.settings() || document.settings()->fullscreenSupported();
+ bool fullscreenSupported =
+ !document.settings() || document.settings()->fullscreenSupported();
+
+ if (!RuntimeEnabledFeatures::featurePolicyEnabled()) {
+ return fullscreenSupported;
+ }
+
+ // TODO(lunalu): clean all of this up once iframe attributes are supported
+ // for feature policy.
+ if (Frame* parent = frame->tree().parent()) {
+ // If FeaturePolicy is enabled, check the fullscreen is not disabled by
+ // policy in the parent frame.
+ if (fullscreenSupported &&
+ parent->securityContext()->getFeaturePolicy()->isFeatureEnabled(
+ kFullscreenFeature)) {
+ return true;
+ }
+ }
+ // Even if the iframe allowfullscreen attribute is not present, allow
+ // fullscreen to be enabled by feature policy.
+ else if (isFeatureEnabledInFrame(kFullscreenFeature, frame)) {
+ return true;
+ }
+
+ document.addConsoleMessage(ConsoleMessage::create(
+ JSMessageSource, WarningMessageLevel,
+ "Fullscreen API is disabled by feature policy for this frame"));
+ return false;
}
// https://fullscreen.spec.whatwg.org/#fullscreen-element-ready-check
diff --git a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp
index be49368..31b3967 100644
--- a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp
+++ b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp
@@ -36,6 +36,8 @@
"domain", FeaturePolicy::FeatureDefault::EnableForAll};
const FeaturePolicy::Feature kDocumentWrite{
"docwrite", FeaturePolicy::FeatureDefault::EnableForAll};
+const FeaturePolicy::Feature kFullscreenFeature{
+ "fullscreen", FeaturePolicy::FeatureDefault::EnableForSelf};
const FeaturePolicy::Feature kGeolocationFeature{
"geolocation", FeaturePolicy::FeatureDefault::EnableForSelf};
const FeaturePolicy::Feature kMidiFeature{
@@ -112,9 +114,9 @@
DEFINE_STATIC_LOCAL(
Vector<const FeaturePolicy::Feature*>, defaultFeatureList,
({&kDocumentCookie, &kDocumentDomain, &kDocumentWrite,
- &kGeolocationFeature, &kMidiFeature, &kNotificationsFeature,
- &kPaymentFeature, &kPushFeature, &kSyncScript, &kSyncXHR, &kUsermedia,
- &kVibrateFeature, &kWebRTC}));
+ &kGeolocationFeature, &kFullscreenFeature, &kMidiFeature,
+ &kNotificationsFeature, &kPaymentFeature, &kPushFeature, &kSyncScript,
+ &kSyncXHR, &kUsermedia, &kVibrateFeature, &kWebRTC}));
return defaultFeatureList;
}
diff --git a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.h b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.h
index 062d6e5..47b22e6b7 100644
--- a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.h
+++ b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.h
@@ -191,6 +191,7 @@
extern const PLATFORM_EXPORT FeaturePolicy::Feature kDocumentDomain;
extern const PLATFORM_EXPORT FeaturePolicy::Feature kDocumentWrite;
extern const PLATFORM_EXPORT FeaturePolicy::Feature kGeolocationFeature;
+extern const PLATFORM_EXPORT FeaturePolicy::Feature kFullscreenFeature;
extern const PLATFORM_EXPORT FeaturePolicy::Feature kMidiFeature;
extern const PLATFORM_EXPORT FeaturePolicy::Feature kNotificationsFeature;
extern const PLATFORM_EXPORT FeaturePolicy::Feature kPaymentFeature;