Website policies: iframes should respect the autoplay policy of the top-level document
authormrajca@apple.com <mrajca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Feb 2017 23:37:26 +0000 (23:37 +0000)
committermrajca@apple.com <mrajca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Feb 2017 23:37:26 +0000 (23:37 +0000)
https://bugs.webkit.org/show_bug.cgi?id=168333

Reviewed by Alex Christensen.

Source/WebCore:

API tests were added.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::HTMLMediaElement):

Tools:

* TestWebKitAPI/Tests/WebKit2/autoplay-check-frame.html: Added.
* TestWebKitAPI/Tests/WebKit2/autoplay-check-in-iframe.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/WebsitePolicies.mm:
(-[AutoplayPoliciesDelegate _webView:decidePolicyForNavigationAction:decisionHandler:]):
(TEST):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@212332 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/html/HTMLMediaElement.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKit2/autoplay-check-frame.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKit2/autoplay-check-in-iframe.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WebsitePolicies.mm

index 7049275..6939223 100644 (file)
@@ -1,3 +1,15 @@
+2017-02-14  Matt Rajca  <mrajca@apple.com>
+
+        Website policies: iframes should respect the autoplay policy of the top-level document
+        https://bugs.webkit.org/show_bug.cgi?id=168333
+
+        Reviewed by Alex Christensen.
+
+        API tests were added.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::HTMLMediaElement):
+
 2017-02-14  Dean Jackson  <dino@apple.com>
 
         Rename preferLowPowerWebGLRendering setting to forceWebGLUsesLowPower
index 8e907e5..a3e1f7f 100644 (file)
@@ -460,8 +460,9 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
         m_mediaSession->addBehaviorRestriction(MediaElementSession::InvisibleAutoplayNotPermitted);
 
     if (document.ownerElement() || !document.isMediaDocument()) {
-        bool shouldAudioPlaybackRequireUserGesture = document.audioPlaybackRequiresUserGesture();
-        bool shouldVideoPlaybackRequireUserGesture = document.videoPlaybackRequiresUserGesture();
+        const auto& topDocument = document.topDocument();
+        bool shouldAudioPlaybackRequireUserGesture = topDocument.audioPlaybackRequiresUserGesture();
+        bool shouldVideoPlaybackRequireUserGesture = topDocument.videoPlaybackRequiresUserGesture();
 
         if (shouldVideoPlaybackRequireUserGesture) {
             m_mediaSession->addBehaviorRestriction(MediaElementSession::RequireUserGestureForVideoRateChange);
index 1ba8b92..833bdeb 100644 (file)
@@ -1,3 +1,16 @@
+2017-02-14  Matt Rajca  <mrajca@apple.com>
+
+        Website policies: iframes should respect the autoplay policy of the top-level document
+        https://bugs.webkit.org/show_bug.cgi?id=168333
+
+        Reviewed by Alex Christensen.
+
+        * TestWebKitAPI/Tests/WebKit2/autoplay-check-frame.html: Added.
+        * TestWebKitAPI/Tests/WebKit2/autoplay-check-in-iframe.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/WebsitePolicies.mm:
+        (-[AutoplayPoliciesDelegate _webView:decidePolicyForNavigationAction:decisionHandler:]):
+        (TEST):
+
 2017-02-14  Chris Dumez  <cdumez@apple.com>
 
         HTML Form Validation bubble should take minimum font size setting into consideration
index 1e300c3..8cfb994 100644 (file)
                C99B675C1E39721A00FC6C80 /* autoplay-with-controls.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C99B675A1E3971FC00FC6C80 /* autoplay-with-controls.html */; };
                C99B675D1E39722000FC6C80 /* js-play-with-controls.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C99B675B1E3971FC00FC6C80 /* js-play-with-controls.html */; };
                C99B675F1E39736F00FC6C80 /* no-autoplay-with-controls.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C99B675E1E39735C00FC6C80 /* no-autoplay-with-controls.html */; };
+               C9C60E651E53A9DC006DA181 /* autoplay-check-frame.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C9C60E631E53A9BA006DA181 /* autoplay-check-frame.html */; };
+               C9C60E661E53A9DC006DA181 /* autoplay-check-in-iframe.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C9C60E641E53A9BA006DA181 /* autoplay-check-in-iframe.html */; };
                CD321B041E3A85FA00EB21C8 /* video-with-muted-audio-and-webaudio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD321B031E3A84B700EB21C8 /* video-with-muted-audio-and-webaudio.html */; };
                CD59F53419E9110D00CF1835 /* file-with-mse.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD59F53219E910AA00CF1835 /* file-with-mse.html */; };
                CD59F53519E9110D00CF1835 /* test-mse.mp4 in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD59F53319E910BC00CF1835 /* test-mse.mp4 */; };
                                F45B960C1E50708800CFAC5D /* autofocus-contenteditable.html in Copy Resources */,
                                F4F93F341E4E918D00E33E2E /* image-and-textarea.html in Copy Resources */,
                                F4D4F3BC1E4E511F00BB2767 /* image-and-contenteditable.html in Copy Resources */,
+                               C9C60E651E53A9DC006DA181 /* autoplay-check-frame.html in Copy Resources */,
+                               C9C60E661E53A9DC006DA181 /* autoplay-check-in-iframe.html in Copy Resources */,
                                F47728991E4AE3C1007ABF6A /* full-page-contenteditable.html in Copy Resources */,
                                C99B675F1E39736F00FC6C80 /* no-autoplay-with-controls.html in Copy Resources */,
                                C99B675D1E39722000FC6C80 /* js-play-with-controls.html in Copy Resources */,
                C99B675A1E3971FC00FC6C80 /* autoplay-with-controls.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "autoplay-with-controls.html"; sourceTree = "<group>"; };
                C99B675B1E3971FC00FC6C80 /* js-play-with-controls.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "js-play-with-controls.html"; sourceTree = "<group>"; };
                C99B675E1E39735C00FC6C80 /* no-autoplay-with-controls.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "no-autoplay-with-controls.html"; sourceTree = "<group>"; };
+               C9C60E631E53A9BA006DA181 /* autoplay-check-frame.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "autoplay-check-frame.html"; sourceTree = "<group>"; };
+               C9C60E641E53A9BA006DA181 /* autoplay-check-in-iframe.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "autoplay-check-in-iframe.html"; sourceTree = "<group>"; };
                CD225C071C45A69200140761 /* ParsedContentRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParsedContentRange.cpp; sourceTree = "<group>"; };
                CD321B031E3A84B700EB21C8 /* video-with-muted-audio-and-webaudio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "video-with-muted-audio-and-webaudio.html"; sourceTree = "<group>"; };
                CD5393C71757BA9700C07123 /* MD5.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MD5.cpp; sourceTree = "<group>"; };
                                93D3D19B17B1A7B000C7C415 /* all-content-in-one-iframe.html */,
                                F6B7BE9617469B7E008A3445 /* associate-form-controls.html */,
                                76E182DE15475A8300F1FADD /* auto-submitting-form.html */,
+                               C9C60E631E53A9BA006DA181 /* autoplay-check-frame.html */,
+                               C9C60E641E53A9BA006DA181 /* autoplay-check-in-iframe.html */,
                                C95984F21E36BC55002C0D45 /* autoplay-check.html */,
                                C95984F31E36BC55002C0D45 /* autoplay-no-audio-check.html */,
                                C99B675A1E3971FC00FC6C80 /* autoplay-with-controls.html */,
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/autoplay-check-frame.html b/Tools/TestWebKitAPI/Tests/WebKit2/autoplay-check-frame.html
new file mode 100644 (file)
index 0000000..2c43fda
--- /dev/null
@@ -0,0 +1,16 @@
+<html>
+    <head>
+        <script>
+            function pageLoaded() {
+                document.getElementById("video").play().then(function() {
+                    window.parent.postMessage('autoplayed', '*');
+                }).catch(function() {
+                    window.parent.postMessage('did-not-play', '*');
+                });
+            }
+        </script>
+    </head>
+    <body onload="pageLoaded()">
+        <video id="video" playsinline src="test.mp4" />
+    </body>
+</html>
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/autoplay-check-in-iframe.html b/Tools/TestWebKitAPI/Tests/WebKit2/autoplay-check-in-iframe.html
new file mode 100644 (file)
index 0000000..f1a3cbc
--- /dev/null
@@ -0,0 +1,16 @@
+<html>
+    <head>
+        <script>
+            function pageLoaded() {
+                window.onmessage = function(event) {
+                    try {
+                        window.webkit.messageHandlers.testHandler.postMessage(event.data);
+                    } catch(e) { }
+                };
+            }
+        </script>
+    </head>
+    <body onload="pageLoaded()">
+        <iframe src="autoplay-check-frame.html"></iframe>
+    </body>
+</html>
index 59725e5..020b029 100644 (file)
@@ -158,7 +158,7 @@ TEST(WebKit2, WebsitePoliciesContentBlockersEnabled)
 }
 
 @interface AutoplayPoliciesDelegate : NSObject <WKNavigationDelegate, WKUIDelegate>
-@property (nonatomic) _WKWebsiteAutoplayPolicy autoplayPolicy;
+@property (nonatomic, copy) _WKWebsiteAutoplayPolicy(^autoplayPolicyForURL)(NSURL *);
 @end
 
 @implementation AutoplayPoliciesDelegate
@@ -173,7 +173,8 @@ TEST(WebKit2, WebsitePoliciesContentBlockersEnabled)
 - (void)_webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy, _WKWebsitePolicies *))decisionHandler
 {
     _WKWebsitePolicies *websitePolicies = [[[_WKWebsitePolicies alloc] init] autorelease];
-    websitePolicies.autoplayPolicy = _autoplayPolicy;
+    if (_autoplayPolicyForURL)
+        websitePolicies.autoplayPolicy = _autoplayPolicyForURL(navigationAction.request.URL);
     decisionHandler(WKNavigationActionPolicyAllow, websitePolicies);
 }
 
@@ -195,26 +196,54 @@ TEST(WebKit2, WebsitePoliciesAutoplayEnabled)
     NSURLRequest *requestWithAudio = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"autoplay-check" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
     NSURLRequest *requestWithoutAudio = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"autoplay-no-audio-check" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
     
-    [delegate setAutoplayPolicy:_WKWebsiteAutoplayPolicyAllowWithoutSound];
+    [delegate setAutoplayPolicyForURL:^(NSURL *) {
+        return _WKWebsiteAutoplayPolicyAllowWithoutSound;
+    }];
     [webView loadRequest:requestWithAudio];
     [webView waitForMessage:@"did-not-play"];
 
     [webView loadRequest:requestWithoutAudio];
     [webView waitForMessage:@"autoplayed"];
 
-    [delegate setAutoplayPolicy:_WKWebsiteAutoplayPolicyDeny];
+    [delegate setAutoplayPolicyForURL:^(NSURL *) {
+        return _WKWebsiteAutoplayPolicyDeny;
+    }];
     [webView loadRequest:requestWithAudio];
     [webView waitForMessage:@"did-not-play"];
 
     [webView loadRequest:requestWithoutAudio];
     [webView waitForMessage:@"did-not-play"];
 
-    [delegate setAutoplayPolicy:_WKWebsiteAutoplayPolicyAllow];
+    [delegate setAutoplayPolicyForURL:^(NSURL *) {
+        return _WKWebsiteAutoplayPolicyAllow;
+    }];
     [webView loadRequest:requestWithAudio];
     [webView waitForMessage:@"autoplayed"];
 
     [webView loadRequest:requestWithoutAudio];
     [webView waitForMessage:@"autoplayed"];
+
+    NSURLRequest *requestWithAudioInIFrame = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"autoplay-check-in-iframe" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+
+    // If the top-level document allows autoplay, any iframes should also autoplay.
+    [delegate setAutoplayPolicyForURL:^(NSURL *url) {
+        if ([url.lastPathComponent isEqualToString:@"autoplay-check-in-iframe.html"])
+            return _WKWebsiteAutoplayPolicyAllow;
+        return _WKWebsiteAutoplayPolicyDeny;
+    }];
+
+    [webView loadRequest:requestWithAudioInIFrame];
+    [webView waitForMessage:@"autoplayed"];
+
+    // If the top-level document disallows autoplay, any iframes should also not autoplay.
+    [delegate setAutoplayPolicyForURL:^(NSURL *url) {
+        if ([url.lastPathComponent isEqualToString:@"autoplay-check-in-iframe.html"])
+            return _WKWebsiteAutoplayPolicyDeny;
+        return _WKWebsiteAutoplayPolicyAllow;
+    }];
+
+    [webView loadRequest:requestWithAudioInIFrame];
+    [webView waitForMessage:@"did-not-play"];
 }
 
 #if PLATFORM(MAC)
@@ -230,7 +259,9 @@ TEST(WebKit2, DISABLED_WebsitePoliciesPlayAfterPreventedAutoplay)
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 336, 276) configuration:configuration.get()]);
 
     auto delegate = adoptNS([[AutoplayPoliciesDelegate alloc] init]);
-    [delegate setAutoplayPolicy:_WKWebsiteAutoplayPolicyDeny];
+    [delegate setAutoplayPolicyForURL:^(NSURL *) {
+        return _WKWebsiteAutoplayPolicyDeny;
+    }];
     [webView setNavigationDelegate:delegate.get()];
 
     WKPageUIClientV9 uiClient;