- Revision
- 233485
- Author
- [email protected]
- Date
- 2018-07-03 15:57:14 -0700 (Tue, 03 Jul 2018)
Log Message
Don't allow autoplay when the element is suspended
https://bugs.webkit.org/show_bug.cgi?id=187299
<rdar://problem/41044691>
Reviewed by Youenn Fablet.
Block autoplay when a media element is suspended. Add more release logging to the methods
that handle autoplay attempts to help diagnose future media playback problems.
* html/HTMLMediaElement.cpp:
(WebCore::convertEnumerationToString): Convert PlaybackWithoutUserGesture to a string.
(WebCore::HTMLMediaElement::dispatchPlayPauseEventsIfNeedsQuirks): Add logging.
(WebCore::HTMLMediaElement::hardwareMutedStateDidChange): Ditto.
(WebCore::HTMLMediaElement::handleAutoplayEvent): Ditto.
(WebCore::HTMLMediaElement::userDidInterfereWithAutoplay): Ditto.
(WebCore::HTMLMediaElement::setPlaybackWithoutUserGesture): Ditto.
* html/HTMLMediaElement.h:
(WTF::LogArgument<WebCore::HTMLMediaElement::PlaybackWithoutUserGesture>::toString):
* html/MediaElementSession.cpp:
(WebCore::MediaElementSession::playbackPermitted const): Playback is not permitted when the
element is suspended.
* html/MediaElementSession.h:
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (233484 => 233485)
--- trunk/Source/WebCore/ChangeLog 2018-07-03 22:44:54 UTC (rev 233484)
+++ trunk/Source/WebCore/ChangeLog 2018-07-03 22:57:14 UTC (rev 233485)
@@ -1,3 +1,29 @@
+2018-07-03 Eric Carlson <[email protected]>
+
+ Don't allow autoplay when the element is suspended
+ https://bugs.webkit.org/show_bug.cgi?id=187299
+ <rdar://problem/41044691>
+
+ Reviewed by Youenn Fablet.
+
+ Block autoplay when a media element is suspended. Add more release logging to the methods
+ that handle autoplay attempts to help diagnose future media playback problems.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::convertEnumerationToString): Convert PlaybackWithoutUserGesture to a string.
+ (WebCore::HTMLMediaElement::dispatchPlayPauseEventsIfNeedsQuirks): Add logging.
+ (WebCore::HTMLMediaElement::hardwareMutedStateDidChange): Ditto.
+ (WebCore::HTMLMediaElement::handleAutoplayEvent): Ditto.
+ (WebCore::HTMLMediaElement::userDidInterfereWithAutoplay): Ditto.
+ (WebCore::HTMLMediaElement::setPlaybackWithoutUserGesture): Ditto.
+ * html/HTMLMediaElement.h:
+ (WTF::LogArgument<WebCore::HTMLMediaElement::PlaybackWithoutUserGesture>::toString):
+
+ * html/MediaElementSession.cpp:
+ (WebCore::MediaElementSession::playbackPermitted const): Playback is not permitted when the
+ element is suspended.
+ * html/MediaElementSession.h:
+
2018-07-03 Zalan Bujtas <[email protected]>
[LFC] Generate anonymous inline box for text content.
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (233484 => 233485)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2018-07-03 22:44:54 UTC (rev 233484)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2018-07-03 22:57:14 UTC (rev 233485)
@@ -283,14 +283,29 @@
MAKE_STATIC_STRING_IMPL("NETWORK_LOADING"),
MAKE_STATIC_STRING_IMPL("NETWORK_NO_SOURCE"),
};
- static_assert(static_cast<size_t>(HTMLMediaElementEnums::NETWORK_EMPTY) == 0, "HTMLMediaElement::NETWORK_EMPTY is not 0 as expected");
- static_assert(static_cast<size_t>(HTMLMediaElementEnums::NETWORK_IDLE) == 1, "HTMLMediaElement::NETWORK_IDLE is not 1 as expected");
- static_assert(static_cast<size_t>(HTMLMediaElementEnums::NETWORK_LOADING) == 2, "HTMLMediaElement::NETWORK_LOADING is not 2 as expected");
- static_assert(static_cast<size_t>(HTMLMediaElementEnums::NETWORK_NO_SOURCE) == 3, "HTMLMediaElement::NETWORK_NO_SOURCE is not 3 as expected");
+ static_assert(static_cast<size_t>(HTMLMediaElementEnums::NETWORK_EMPTY) == 0, "HTMLMediaElementEnums::NETWORK_EMPTY is not 0 as expected");
+ static_assert(static_cast<size_t>(HTMLMediaElementEnums::NETWORK_IDLE) == 1, "HTMLMediaElementEnums::NETWORK_IDLE is not 1 as expected");
+ static_assert(static_cast<size_t>(HTMLMediaElementEnums::NETWORK_LOADING) == 2, "HTMLMediaElementEnums::NETWORK_LOADING is not 2 as expected");
+ static_assert(static_cast<size_t>(HTMLMediaElementEnums::NETWORK_NO_SOURCE) == 3, "HTMLMediaElementEnums::NETWORK_NO_SOURCE is not 3 as expected");
ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
return values[static_cast<size_t>(enumerationValue)];
}
+String convertEnumerationToString(HTMLMediaElement::PlaybackWithoutUserGesture enumerationValue)
+{
+ static const NeverDestroyed<String> values[] = {
+ MAKE_STATIC_STRING_IMPL("None"),
+ MAKE_STATIC_STRING_IMPL("Started"),
+ MAKE_STATIC_STRING_IMPL("Prevented"),
+ MAKE_STATIC_STRING_IMPL("NETWORK_NO_SOURCE"),
+ };
+ static_assert(static_cast<size_t>(HTMLMediaElement::PlaybackWithoutUserGesture::None) == 0, "PlaybackWithoutUserGesture::None is not 0 as expected");
+ static_assert(static_cast<size_t>(HTMLMediaElement::PlaybackWithoutUserGesture::Started) == 1, "PlaybackWithoutUserGesture::Started is not 1 as expected");
+ static_assert(static_cast<size_t>(HTMLMediaElement::PlaybackWithoutUserGesture::Prevented) == 2, "PlaybackWithoutUserGesture::Prevented is not 2 as expected");
+ ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
+ return values[static_cast<size_t>(enumerationValue)];
+}
+
typedef HashMap<Document*, HashSet<HTMLMediaElement*>> DocumentElementSetMap;
static DocumentElementSetMap& documentToElementSetMap()
{
@@ -2439,6 +2454,7 @@
if (!needsAutoplayPlayPauseEventsQuirk(document) && !needsAutoplayPlayPauseEventsQuirk(document.topDocument()))
return;
+ ALWAYS_LOG(LOGIDENTIFIER);
scheduleEvent(eventNames().playingEvent);
scheduleEvent(eventNames().pauseEvent);
}
@@ -3731,6 +3747,7 @@
if (effectiveMuted() || !volume())
return;
+ INFO_LOG(LOGIDENTIFIER);
userDidInterfereWithAutoplay();
}
#endif
@@ -7635,6 +7652,7 @@
{
if (Page* page = document().page()) {
bool hasAudio = this->hasAudio() && !muted() && volume();
+ ALWAYS_LOG(LOGIDENTIFIER, "hasAudio = ", hasAudio);
page->chrome().client().handleAutoplayEvent(event, hasAudio ? AutoplayEventFlags::HasAudio : OptionSet<AutoplayEventFlags>());
}
}
@@ -7648,15 +7666,18 @@
if (currentTime() - m_playbackWithoutUserGestureStartedTime->toDouble() > AutoplayInterferenceTimeThreshold)
return;
+ ALWAYS_LOG(LOGIDENTIFIER);
handleAutoplayEvent(AutoplayEvent::UserDidInterfereWithPlayback);
setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture::None);
}
-void HTMLMediaElement::setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture playbackWithoutUserGesture)
+void HTMLMediaElement::setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture reason)
{
- m_playbackWithoutUserGesture = playbackWithoutUserGesture;
+ ALWAYS_LOG(LOGIDENTIFIER, reason);
- switch (playbackWithoutUserGesture) {
+ m_playbackWithoutUserGesture = reason;
+
+ switch (reason) {
case PlaybackWithoutUserGesture::Started:
m_playbackWithoutUserGestureStartedTime = currentMediaTime();
break;
@@ -7668,7 +7689,6 @@
dispatchPlayPauseEventsIfNeedsQuirks();
handleAutoplayEvent(AutoplayEvent::DidPreventMediaFromPlaying);
-
break;
}
}
Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (233484 => 233485)
--- trunk/Source/WebCore/html/HTMLMediaElement.h 2018-07-03 22:44:54 UTC (rev 233484)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h 2018-07-03 22:57:14 UTC (rev 233485)
@@ -559,6 +559,8 @@
WEBCORE_EXPORT void didBecomeFullscreenElement() override;
WEBCORE_EXPORT void willExitFullscreen();
+ enum class PlaybackWithoutUserGesture { None, Started, Prevented };
+
protected:
HTMLMediaElement(const QualifiedName&, Document&, bool createdByParser);
virtual void finishInitialization();
@@ -802,7 +804,6 @@
void dispatchPlayPauseEventsIfNeedsQuirks();
SuccessOr<MediaPlaybackDenialReason> canTransitionFromAutoplayToPlay() const;
- enum class PlaybackWithoutUserGesture { None, Started, Prevented };
void setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture);
void userDidInterfereWithAutoplay();
void handleAutoplayEvent(AutoplayEvent);
@@ -1167,8 +1168,22 @@
#endif
};
+String convertEnumerationToString(HTMLMediaElement::PlaybackWithoutUserGesture);
+
} // namespace WebCore
+namespace WTF {
+
+template <>
+struct LogArgument<WebCore::HTMLMediaElement::PlaybackWithoutUserGesture> {
+ static String toString(const WebCore::HTMLMediaElement::PlaybackWithoutUserGesture reason)
+ {
+ return convertEnumerationToString(reason);
+ }
+};
+
+} // namespace WTF
+
#if ENABLE(VIDEO_TRACK) && !defined(NDEBUG)
namespace WTF {
Modified: trunk/Source/WebCore/html/MediaElementSession.cpp (233484 => 233485)
--- trunk/Source/WebCore/html/MediaElementSession.cpp 2018-07-03 22:44:54 UTC (rev 233484)
+++ trunk/Source/WebCore/html/MediaElementSession.cpp 2018-07-03 22:57:14 UTC (rev 233485)
@@ -256,8 +256,10 @@
SuccessOr<MediaPlaybackDenialReason> MediaElementSession::playbackPermitted() const
{
- if (m_element.isSuspended())
- return { };
+ if (m_element.isSuspended()) {
+ ALWAYS_LOG(LOGIDENTIFIER, "Returning FALSE because element is suspended");
+ return MediaPlaybackDenialReason::InvalidState;
+ }
auto& document = m_element.document();
if (document.isMediaDocument() && !document.ownerElement())
Modified: trunk/Source/WebCore/html/MediaElementSession.h (233484 => 233485)
--- trunk/Source/WebCore/html/MediaElementSession.h 2018-07-03 22:44:54 UTC (rev 233484)
+++ trunk/Source/WebCore/html/MediaElementSession.h 2018-07-03 22:57:14 UTC (rev 233485)
@@ -45,6 +45,7 @@
UserGestureRequired,
FullscreenRequired,
PageConsentRequired,
+ InvalidState,
};
class Document;