Title: [215243] trunk
Revision
215243
Author
[email protected]
Date
2017-04-11 11:29:03 -0700 (Tue, 11 Apr 2017)

Log Message

Change autoplay state to "prevented" when media is paused due to restrictions.
https://bugs.webkit.org/show_bug.cgi?id=170686

Reviewed by Alex Christensen.

Source/WebCore:

Added API tests.

Currently, the autoplay state is set to "prevented" when playback is about to begin without
user interaction and there are restrictions in place. We should also be setting this flag when
autoplay is allowed but due to a change in audio tracks, for example, it gets paused.

This patch also moves some common logic into setPlaybackWithoutUserGesture without changing behavior.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::setReadyState):
(WebCore::HTMLMediaElement::play):
(WebCore::HTMLMediaElement::mediaPlayerDidAddAudioTrack):
(WebCore::HTMLMediaElement::mediaPlayerCharacteristicChanged):
(WebCore::HTMLMediaElement::setPlaybackWithoutUserGesture):
(WebCore::HTMLMediaElement::updateShouldPlay):

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit2/autoplay-muted-with-controls.html: Added test.
* TestWebKitAPI/Tests/WebKit2Cocoa/WebsitePolicies.mm:
(TEST):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (215242 => 215243)


--- trunk/Source/WebCore/ChangeLog	2017-04-11 18:27:01 UTC (rev 215242)
+++ trunk/Source/WebCore/ChangeLog	2017-04-11 18:29:03 UTC (rev 215243)
@@ -1,3 +1,26 @@
+2017-04-10  Matt Rajca  <[email protected]>
+
+        Change autoplay state to "prevented" when media is paused due to restrictions.
+        https://bugs.webkit.org/show_bug.cgi?id=170686
+
+        Reviewed by Alex Christensen.
+
+        Added API tests.
+
+        Currently, the autoplay state is set to "prevented" when playback is about to begin without
+        user interaction and there are restrictions in place. We should also be setting this flag when
+        autoplay is allowed but due to a change in audio tracks, for example, it gets paused.
+
+        This patch also moves some common logic into setPlaybackWithoutUserGesture without changing behavior.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::setReadyState):
+        (WebCore::HTMLMediaElement::play):
+        (WebCore::HTMLMediaElement::mediaPlayerDidAddAudioTrack):
+        (WebCore::HTMLMediaElement::mediaPlayerCharacteristicChanged):
+        (WebCore::HTMLMediaElement::setPlaybackWithoutUserGesture):
+        (WebCore::HTMLMediaElement::updateShouldPlay):
+
 2017-04-11  Eric Carlson  <[email protected]>
 
         [MediaStream] Set correct audio session category when capturing audio

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (215242 => 215243)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2017-04-11 18:27:01 UTC (rev 215242)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2017-04-11 18:29:03 UTC (rev 215243)
@@ -2446,21 +2446,18 @@
             m_playbackStartedTime = currentMediaTime().toDouble();
             scheduleEvent(eventNames().playEvent);
             scheduleNotifyAboutPlaying();
-        } else if (success.value() == MediaPlaybackDenialReason::UserGestureRequired) {
+        } else if (success.value() == MediaPlaybackDenialReason::UserGestureRequired)
             setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture::Prevented);
-            dispatchPlayPauseEventsIfNeedsQuirks();
 
-            if (Page* page = document().page())
-                page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidPreventMediaFromPlaying);
-        }
-
         shouldUpdateDisplayState = true;
     }
 
     // If we transition to the Future Data state and we're about to begin playing, ensure playback is actually permitted first,
     // honoring any playback denial reasons such as the requirement of a user gesture.
-    if (m_readyState == HAVE_FUTURE_DATA && oldState < HAVE_FUTURE_DATA && potentiallyPlaying() && !m_mediaSession->playbackPermitted(*this))
+    if (m_readyState == HAVE_FUTURE_DATA && oldState < HAVE_FUTURE_DATA && potentiallyPlaying() && !m_mediaSession->playbackPermitted(*this)) {
         pauseInternal();
+        setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture::Prevented);
+    }
 
     if (shouldUpdateDisplayState) {
         updateDisplayState();
@@ -3136,13 +3133,8 @@
 
     auto success = m_mediaSession->playbackPermitted(*this);
     if (!success) {
-        if (success.value() == MediaPlaybackDenialReason::UserGestureRequired) {
+        if (success.value() == MediaPlaybackDenialReason::UserGestureRequired)
             setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture::Prevented);
-            dispatchPlayPauseEventsIfNeedsQuirks();
-
-            if (Page* page = document().page())
-                page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidPreventMediaFromPlaying);
-        }
         promise.reject(NotAllowedError);
         return;
     }
@@ -3169,13 +3161,8 @@
 
     auto success = m_mediaSession->playbackPermitted(*this);
     if (!success) {
-        if (success.value() == MediaPlaybackDenialReason::UserGestureRequired) {
+        if (success.value() == MediaPlaybackDenialReason::UserGestureRequired)
             setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture::Prevented);
-            dispatchPlayPauseEventsIfNeedsQuirks();
-
-            if (Page* page = document().page())
-                page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidPreventMediaFromPlaying);
-        }
         return;
     }
     if (ScriptController::processingUserGestureForMedia())
@@ -3610,8 +3597,10 @@
 
 void HTMLMediaElement::mediaPlayerDidAddAudioTrack(AudioTrackPrivate& track)
 {
-    if (isPlaying() && !m_mediaSession->playbackPermitted(*this))
+    if (isPlaying() && !m_mediaSession->playbackPermitted(*this)) {
         pauseInternal();
+        setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture::Prevented);
+    }
 
     addAudioTrack(AudioTrack::create(*this, track));
 }
@@ -4757,8 +4746,10 @@
         mediaControls()->reset();
     updateRenderer();
 
-    if (!paused() && !m_mediaSession->playbackPermitted(*this))
+    if (!paused() && !m_mediaSession->playbackPermitted(*this)) {
         pauseInternal();
+        setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture::Prevented);
+    }
 
 #if ENABLE(MEDIA_SESSION)
     document().updateIsPlayingMedia(m_elementID);
@@ -7181,8 +7172,16 @@
         m_playbackWithoutUserGestureStartedTime = currentMediaTime();
         break;
     case PlaybackWithoutUserGesture::None:
+        m_playbackWithoutUserGestureStartedTime = std::nullopt;
+        break;
     case PlaybackWithoutUserGesture::Prevented:
         m_playbackWithoutUserGestureStartedTime = std::nullopt;
+
+        dispatchPlayPauseEventsIfNeedsQuirks();
+
+        if (Page* page = document().page())
+            page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidPreventMediaFromPlaying);
+
         break;
     }
 }
@@ -7358,9 +7357,10 @@
 
 void HTMLMediaElement::updateShouldPlay()
 {
-    if (!paused() && !m_mediaSession->playbackPermitted(*this))
+    if (!paused() && !m_mediaSession->playbackPermitted(*this)) {
         pauseInternal();
-    else if (canTransitionFromAutoplayToPlay())
+        setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture::Prevented);
+    } else if (canTransitionFromAutoplayToPlay())
         play();
 }
 

Modified: trunk/Tools/ChangeLog (215242 => 215243)


--- trunk/Tools/ChangeLog	2017-04-11 18:27:01 UTC (rev 215242)
+++ trunk/Tools/ChangeLog	2017-04-11 18:29:03 UTC (rev 215243)
@@ -1,3 +1,15 @@
+2017-04-10  Matt Rajca  <[email protected]>
+
+        Change autoplay state to "prevented" when media is paused due to restrictions.
+        https://bugs.webkit.org/show_bug.cgi?id=170686
+
+        Reviewed by Alex Christensen.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKit2/autoplay-muted-with-controls.html: Added test.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/WebsitePolicies.mm:
+        (TEST):
+
 2017-04-11  Yusuke Suzuki  <[email protected]>
 
         [WebCore][JSC] ResourceUsageData.{timeOfNextEdenCollection,timeOfNextFullCollection} should be MonotonicTime

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (215242 => 215243)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2017-04-11 18:27:01 UTC (rev 215242)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2017-04-11 18:29:03 UTC (rev 215243)
@@ -544,6 +544,7 @@
 		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 */; };
 		C99BDF891E80980400C7170E /* autoplay-zero-volume-check.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C99BDF881E8097E300C7170E /* autoplay-zero-volume-check.html */; };
+		C9BF06EF1E9C132500595E3E /* autoplay-muted-with-controls.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C9BF06EE1E9C130400595E3E /* autoplay-muted-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 */; };
@@ -662,6 +663,7 @@
 			dstPath = TestWebKitAPI.resources;
 			dstSubfolderSpec = 7;
 			files = (
+				C9BF06EF1E9C132500595E3E /* autoplay-muted-with-controls.html in Copy Resources */,
 				F4DEF6ED1E9B4DB60048EF61 /* image-in-link-and-input.html in Copy Resources */,
 				1A9E52C913E65EF4006917F5 /* 18-characters.html in Copy Resources */,
 				379028B914FAC24C007E6B43 /* acceptsFirstMouse.html in Copy Resources */,
@@ -1388,6 +1390,7 @@
 		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>"; };
 		C99BDF881E8097E300C7170E /* autoplay-zero-volume-check.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "autoplay-zero-volume-check.html"; sourceTree = "<group>"; };
+		C9BF06EE1E9C130400595E3E /* autoplay-muted-with-controls.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "autoplay-muted-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>"; };
@@ -2150,6 +2153,7 @@
 				C9C60E631E53A9BA006DA181 /* autoplay-check-frame.html */,
 				C9C60E641E53A9BA006DA181 /* autoplay-check-in-iframe.html */,
 				C95984F21E36BC55002C0D45 /* autoplay-check.html */,
+				C9BF06EE1E9C130400595E3E /* autoplay-muted-with-controls.html */,
 				C95984F31E36BC55002C0D45 /* autoplay-no-audio-check.html */,
 				C99B675A1E3971FC00FC6C80 /* autoplay-with-controls.html */,
 				C99BDF881E8097E300C7170E /* autoplay-zero-volume-check.html */,

Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2/autoplay-muted-with-controls.html (0 => 215243)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2/autoplay-muted-with-controls.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2/autoplay-muted-with-controls.html	2017-04-11 18:29:03 UTC (rev 215243)
@@ -0,0 +1,23 @@
+<html>
+    <head>
+        <script>
+            function pageLoaded() {
+                try {
+                    window.webkit.messageHandlers.testHandler.postMessage("loaded");
+                } catch(e) { }
+            }
+
+            function beganPlaying() {
+                document.getElementById("video").muted = false;
+            }
+
+            function play() {
+                document.getElementById("video").play();
+            }
+        </script>
+    </head>
+    <body _onload_="pageLoaded()">
+        <button _onclick_="play()">Play</button>
+        <video id="video" _onplaying_="beganPlaying()" muted autoplay src="" />
+    </body>
+</html>

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WebsitePolicies.mm (215242 => 215243)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WebsitePolicies.mm	2017-04-11 18:27:01 UTC (rev 215242)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WebsitePolicies.mm	2017-04-11 18:29:03 UTC (rev 215243)
@@ -342,6 +342,22 @@
     [webView mouseUpAtPoint:playButtonClickPoint];
     [webView waitForMessage:@"played"];
     ASSERT_TRUE(receivedAutoplayEvent == std::nullopt);
+
+    receivedAutoplayEvent = std::nullopt;
+    [webView loadHTMLString:@"" baseURL:nil];
+
+    [delegate setAutoplayPolicyForURL:^(NSURL *) {
+        return _WKWebsiteAutoplayPolicyAllowWithoutSound;
+    }];
+
+    NSURLRequest *autoplayMutedRequest = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"autoplay-muted-with-controls" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    [webView loadRequest:autoplayMutedRequest];
+    [webView waitForMessage:@"loaded"];
+    runUntilReceivesAutoplayEvent(kWKAutoplayEventDidPreventFromAutoplaying);
+
+    [webView mouseDownAtPoint:playButtonClickPoint simulatePressure:NO];
+    [webView mouseUpAtPoint:playButtonClickPoint];
+    runUntilReceivesAutoplayEvent(kWKAutoplayEventDidPlayMediaPreventedFromAutoplaying);
 }
 
 TEST(WebKit2, WebsitePoliciesPlayingWithoutInterference)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to