Diff
Modified: trunk/Source/WebCore/ChangeLog (213160 => 213161)
--- trunk/Source/WebCore/ChangeLog 2017-02-28 19:37:04 UTC (rev 213160)
+++ trunk/Source/WebCore/ChangeLog 2017-02-28 19:42:20 UTC (rev 213161)
@@ -1,3 +1,27 @@
+2017-02-24 Matt Rajca <mra...@apple.com>
+
+ Media: notify clients when autoplayed media ends without being paused
+ https://bugs.webkit.org/show_bug.cgi?id=168852
+
+ Reviewed by Alex Christensen.
+
+ Added API tests.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::setReadyState):
+ Set state accordingly if we autoplayed or if playback was prevented.
+ (WebCore::HTMLMediaElement::play):
+ Update state if playback was prevented.
+ (WebCore::HTMLMediaElement::playInternal):
+ Update state if playback began without user interaction.
+ (WebCore::HTMLMediaElement::pauseInternal):
+ Update state.
+ (WebCore::HTMLMediaElement::mediaPlayerTimeChanged):
+ If playback ends and it began without user interaction, send a DidPlayMediaWithoutInterference event.
+ (WebCore::HTMLMediaElement::stopWithoutDestroyingMediaPlayer): Ditto.
+ * html/HTMLMediaElement.h:
+ * page/AutoplayEvent.h:
+
2017-02-27 Dave Hyatt <hy...@apple.com>
Update flexbox to Blink's tip of tree
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (213160 => 213161)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2017-02-28 19:37:04 UTC (rev 213160)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2017-02-28 19:42:20 UTC (rev 213161)
@@ -2416,11 +2416,12 @@
if (success) {
m_paused = false;
invalidateCachedTime();
+ m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::Started;
m_playbackStartedTime = currentMediaTime().toDouble();
scheduleEvent(eventNames().playEvent);
scheduleNotifyAboutPlaying();
} else if (success.value() == MediaPlaybackDenialReason::UserGestureRequired) {
- m_preventedFromPlayingWithoutUserGesture = true;
+ m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::Prevented;
if (Page* page = document().page())
page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidPreventMediaFromPlaying);
@@ -3104,7 +3105,7 @@
auto success = m_mediaSession->playbackPermitted(*this);
if (!success) {
if (success.value() == MediaPlaybackDenialReason::UserGestureRequired) {
- m_preventedFromPlayingWithoutUserGesture = true;
+ m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::Prevented;
if (Page* page = document().page())
page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidPreventMediaFromPlaying);
@@ -3136,7 +3137,7 @@
auto success = m_mediaSession->playbackPermitted(*this);
if (!success) {
if (success.value() == MediaPlaybackDenialReason::UserGestureRequired) {
- m_preventedFromPlayingWithoutUserGesture = true;
+ m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::Prevented;
if (Page* page = document().page())
page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidPreventMediaFromPlaying);
@@ -3207,11 +3208,14 @@
} else if (m_readyState >= HAVE_FUTURE_DATA)
scheduleResolvePendingPlayPromises();
- if (ScriptController::processingUserGestureForMedia() && m_preventedFromPlayingWithoutUserGesture) {
- if (Page* page = document().page())
- page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidPlayMediaPreventedFromPlaying);
- m_preventedFromPlayingWithoutUserGesture = false;
- }
+ if (ScriptController::processingUserGestureForMedia()) {
+ if (m_playbackWithoutUserGesture == PlaybackWithoutUserGesture::Prevented) {
+ if (Page* page = document().page())
+ page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidPlayMediaPreventedFromPlaying);
+ m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::None;
+ }
+ } else
+ m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::Started;
m_autoplaying = false;
updatePlayState();
@@ -3252,6 +3256,7 @@
}
m_autoplaying = false;
+ m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::None;
if (!m_paused) {
m_paused = true;
@@ -4401,6 +4406,12 @@
scheduleEvent(eventNames().endedEvent);
if (!wasSeeking)
addBehaviorRestrictionsOnEndIfNecessary();
+
+ if (m_playbackWithoutUserGesture == PlaybackWithoutUserGesture::Started) {
+ if (Page* page = document().page())
+ page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidEndMediaPlaybackWithoutUserInterference);
+ }
+ m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::None;
}
// If the media element has a current media controller, then report the controller state
// for the media element's current media controller.
@@ -5157,6 +5168,12 @@
setPausedInternal(true);
m_mediaSession->clientWillPausePlayback();
+ if (m_playbackWithoutUserGesture == PlaybackWithoutUserGesture::Started) {
+ if (Page* page = document().page())
+ page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidEndMediaPlaybackWithoutUserInterference);
+ }
+ m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::None;
+
userCancelledLoad();
updateRenderer();
Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (213160 => 213161)
--- trunk/Source/WebCore/html/HTMLMediaElement.h 2017-02-28 19:37:04 UTC (rev 213160)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h 2017-02-28 19:42:20 UTC (rev 213161)
@@ -974,7 +974,6 @@
bool m_creatingControls : 1;
bool m_receivedLayoutSizeChanged : 1;
bool m_hasEverNotifiedAboutPlaying : 1;
- bool m_preventedFromPlayingWithoutUserGesture : 1;
bool m_hasEverHadAudio : 1;
bool m_hasEverHadVideo : 1;
@@ -991,6 +990,9 @@
bool m_haveVisibleTextTrack : 1;
bool m_processingPreferenceChange : 1;
+ enum class PlaybackWithoutUserGesture { None, Started, Prevented };
+ PlaybackWithoutUserGesture m_playbackWithoutUserGesture;
+
String m_subtitleTrackLanguage;
MediaTime m_lastTextTrackUpdateTime { -1, 1 };
Modified: trunk/Source/WebCore/page/AutoplayEvent.h (213160 => 213161)
--- trunk/Source/WebCore/page/AutoplayEvent.h 2017-02-28 19:37:04 UTC (rev 213160)
+++ trunk/Source/WebCore/page/AutoplayEvent.h 2017-02-28 19:42:20 UTC (rev 213161)
@@ -30,6 +30,7 @@
enum class AutoplayEvent {
DidPreventMediaFromPlaying,
DidPlayMediaPreventedFromPlaying,
+ DidEndMediaPlaybackWithoutUserInterference,
};
} // namespace WebCore
Modified: trunk/Source/WebKit2/ChangeLog (213160 => 213161)
--- trunk/Source/WebKit2/ChangeLog 2017-02-28 19:37:04 UTC (rev 213160)
+++ trunk/Source/WebKit2/ChangeLog 2017-02-28 19:42:20 UTC (rev 213161)
@@ -1,3 +1,12 @@
+2017-02-24 Matt Rajca <mra...@apple.com>
+
+ Media: notify clients when autoplayed media ends without being paused
+ https://bugs.webkit.org/show_bug.cgi?id=168852
+
+ Reviewed by Alex Christensen.
+
+ * UIProcess/API/C/WKPageUIClient.h:
+
2017-02-28 Csaba Osztrogonác <o...@webkit.org>
Remove EFL leftover from WebPageProxy.messages.in
Modified: trunk/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h (213160 => 213161)
--- trunk/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h 2017-02-28 19:37:04 UTC (rev 213160)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h 2017-02-28 19:42:20 UTC (rev 213161)
@@ -51,6 +51,7 @@
enum {
kWKAutoplayEventDidPreventFromAutoplaying,
kWKAutoplayEventDidPlayMediaPreventedFromAutoplaying,
+ kWKAutoplayEventDidEndMediaPlaybackWithoutUserInterference,
};
typedef uint32_t WKAutoplayEvent;
Modified: trunk/Tools/ChangeLog (213160 => 213161)
--- trunk/Tools/ChangeLog 2017-02-28 19:37:04 UTC (rev 213160)
+++ trunk/Tools/ChangeLog 2017-02-28 19:42:20 UTC (rev 213161)
@@ -1,3 +1,14 @@
+2017-02-24 Matt Rajca <mra...@apple.com>
+
+ Media: notify clients when autoplayed media ends without being paused
+ https://bugs.webkit.org/show_bug.cgi?id=168852
+
+ Reviewed by Alex Christensen.
+
+ * TestWebKitAPI/Tests/WebKit2/js-play-with-controls.html:
+ * TestWebKitAPI/Tests/WebKit2Cocoa/WebsitePolicies.mm:
+ (TEST): Added.
+
2017-02-28 Jonathan Bedard <jbed...@apple.com>
webkitpy: jsc-ews should run when Makefiles and build scripts are changed
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2/js-play-with-controls.html (213160 => 213161)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit2/js-play-with-controls.html 2017-02-28 19:37:04 UTC (rev 213160)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2/js-play-with-controls.html 2017-02-28 19:42:20 UTC (rev 213161)
@@ -11,10 +11,22 @@
function play() {
document.getElementById("video").play();
}
+
+ function beganPlaying() {
+ try {
+ window.webkit.messageHandlers.testHandler.postMessage("playing");
+ } catch(e) { }
+ }
+
+ function endedPlaying() {
+ try {
+ window.webkit.messageHandlers.testHandler.postMessage("ended");
+ } catch(e) { }
+ }
</script>
</head>
<body _onload_="pageLoaded()">
<button _onclick_="play()">Play</button>
- <video id="video" src="" />
+ <video id="video" _onplaying_=beganPlaying() _onended_=endedPlaying() src="" />
</body>
</html>
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WebsitePolicies.mm (213160 => 213161)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WebsitePolicies.mm 2017-02-28 19:37:04 UTC (rev 213160)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WebsitePolicies.mm 2017-02-28 19:42:20 UTC (rev 213161)
@@ -316,6 +316,41 @@
[webView waitForMessage:@"played"];
ASSERT_TRUE(receivedAutoplayEvent == std::nullopt);
}
+
+TEST(WebKit2, WebsitePoliciesPlayingWithoutInterference)
+{
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 336, 276) configuration:configuration.get()]);
+
+ auto delegate = adoptNS([[AutoplayPoliciesDelegate alloc] init]);
+ [delegate setAutoplayPolicyForURL:^(NSURL *) {
+ return _WKWebsiteAutoplayPolicyAllow;
+ }];
+ [webView setNavigationDelegate:delegate.get()];
+
+ WKPageUIClientV9 uiClient;
+ memset(&uiClient, 0, sizeof(uiClient));
+
+ uiClient.base.version = 9;
+ uiClient.handleAutoplayEvent = handleAutoplayEvent;
+
+ WKPageSetPageUIClient([webView _pageForTesting], &uiClient.base);
+
+ receivedAutoplayEvent = std::nullopt;
+ NSURLRequest *jsPlayRequest = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"js-play-with-controls" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+ [webView loadRequest:jsPlayRequest];
+ [webView waitForMessage:@"playing"];
+
+ ASSERT_TRUE(receivedAutoplayEvent == std::nullopt);
+
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
+ runUntilReceivesAutoplayEvent(kWKAutoplayEventDidEndMediaPlaybackWithoutUserInterference);
+
+ receivedAutoplayEvent = std::nullopt;
+ [webView loadRequest:jsPlayRequest];
+ [webView waitForMessage:@"ended"];
+ runUntilReceivesAutoplayEvent(kWKAutoplayEventDidEndMediaPlaybackWithoutUserInterference);
+}
#endif
#endif