Add a setting and restriction which will pause invisible autoplaying video
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Dec 2015 22:09:58 +0000 (22:09 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Dec 2015 22:09:58 +0000 (22:09 +0000)
commit1361bdf5c3e7f831073cea7fb0b9cb81149f46a3
tree9e6563745f67be41baca07b4429687023df9fd58
parent7e044346903295f6879f7bd5ab6a966d2a47ae90
Add a setting and restriction which will pause invisible autoplaying video
https://bugs.webkit.org/show_bug.cgi?id=151412

Reviewed by Eric Carlson.

Source/WebCore:

Test: media/video-restricted-invisible-autoplay-not-allowed.html

Drive-by fix: m_autoplaying is reset in many places by calling pause() or play(), where those
calls did not originate from an explicit request to pause or play, e.g., during an interruption.
This causes m_autoplaying to be set to false, thus breaking resumption of autoplaying when the
interruption ends. Update PlatformMediaSession to remember its client's "autoplaying" state and
restore it when an interruption ends.

Add a means to register for viewport visibility notifications to FrameView, RenderView,
and RenderElement. Elements who wish to recieve these notifications must do so through their
renderer, and thus will have to re-register whenever a new renderer is attached.

Add a restriction to HTMLMediaElement which will pause autoplaying video when that video scrolls
out of the viewport, or is hidden with CSS.

Add a setting which controls whether that new restriction is set.

* dom/Element.h:
(WebCore::Element::isVisibleInViewportChanged): Add default empty virtual method.
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::HTMLMediaElement):
(WebCore::HTMLMediaElement::didMoveToNewDocument):
(WebCore::HTMLMediaElement::documentDidResumeFromPageCache):
(WebCore::HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture):
(WebCore::HTMLMediaElement::resumeAutoplaying):
(WebCore::mediaElementIsAllowedToAutoplay):
(WebCore::HTMLMediaElement::isVisibleInViewportChanged):
(WebCore::HTMLMediaElement::updateShouldAutoplay):
(WebCore::HTMLMediaElement::HTMLMediaElement): Set the new restriction based on the current Settings.
(WebCore::HTMLMediaElement::resumeAutoplaying): Continue autoplay, or begin playback.
(WebCore::HTMLMediaElement::didMoveToNewDocument): Update our autoplay state.
(WebCore::HTMLMediaElement::documentDidResumeFromPageCache): Ditto.
(WebCore::HTMLMediaElement::removedFrom): Ditto.
(WebCore::HTMLMediaElement::didAttachRenderers): Ditto.
(WebCore::HTMLMediaElement::didDetachRenderers): Ditto.
(WebCore::HTMLMediaElement::visibilityDidChange): Ditto.
(WebCore::HTMLMediaElement::willDetachRenderers): Unregister for visibility callbacks.
(WebCore::HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture): Clear new restriction.
(WebCore::mediaElementIsAllowedToAutoplay): Check for autoplay requirements.
(WebCore::HTMLMediaElement::isVisibleInViewportChanged): Added, update our autoplay state.
(WebCore::HTMLMediaElement::updateShouldAutoplay): Set interruption if necessary, clear otherwise.
* html/HTMLMediaElement.h:
* html/MediaElementSession.cpp:
(WebCore::restrictionName): Added support for new restriction.
* html/MediaElementSession.h:
* page/FrameView.cpp:
(WebCore::FrameView::viewportContentsChanged): Update clients of viewport visibility.
* page/Settings.in:
* platform/audio/PlatformMediaSession.cpp:
(WebCore::stateName): Add new "Autoplay" state.
(WebCore::interruptionName): Added new interruption type.
(WebCore::PlatformMediaSession::beginInterruption): Set the m_interruptionType.
(WebCore::PlatformMediaSession::clientWillBeginAutoplaying): Set the m_state to Autoplaying.
* platform/audio/PlatformMediaSession.h:
(WebCore::PlatformMediaSession::interruptionType): Added getter.
(WebCore::PlatformMediaSessionClient::resumeAutoplaying): Added default.
* platform/audio/PlatformMediaSessionManager.cpp:
(WebCore::PlatformMediaSessionManager::sessionWillBeginPlayback): Only pause session if its state is playing.
* rendering/RenderElement.cpp:
(WebCore::RenderElement::RenderElement): Set new ivars.
(WebCore::RenderElement::~RenderElement): Unregister for callbacks if necessary.
(WebCore::RenderElement::registerForVisibleInViewportCallback): Register for callbacks from RenderView.
(WebCore::RenderElement::unregisterForVisibleInViewportCallback): Unregister from same.
(WebCore::RenderElement::visibleInViewportStateChanged): Notify Element if value has changed.
* rendering/RenderElement.h:
* rendering/RenderView.cpp:
(WebCore::RenderView::registerForVisibleInViewportCallback): Add renderer to list of callbacks.
(WebCore::RenderView::unregisterForVisibleInViewportCallback): Remove renderer from same.
(WebCore::RenderView::updateVisibleViewportRect): Walk renderers setting their visiblility based on the viewport visible rect.
* rendering/RenderView.h:
* testing/Internals.cpp:
(WebCore::Internals::setMediaElementRestrictions): Support new restriction.

LayoutTests:

* media/video-restricted-invisible-autoplay-not-allowed-expected.txt: Added.
* media/video-restricted-invisible-autoplay-not-allowed.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@192966 268f45cc-cd09-0410-ab3c-d52691b4dbfc
24 files changed:
LayoutTests/ChangeLog
LayoutTests/media/video-restricted-invisible-autoplay-not-allowed-expected.txt [new file with mode: 0644]
LayoutTests/media/video-restricted-invisible-autoplay-not-allowed.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/dom/Element.h
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/html/MediaElementSession.cpp
Source/WebCore/html/MediaElementSession.h
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/Settings.in
Source/WebCore/platform/audio/PlatformMediaSession.cpp
Source/WebCore/platform/audio/PlatformMediaSession.h
Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp
Source/WebCore/rendering/RenderElement.cpp
Source/WebCore/rendering/RenderElement.h
Source/WebCore/rendering/RenderImage.h
Source/WebCore/rendering/RenderMedia.cpp
Source/WebCore/rendering/RenderMedia.h
Source/WebCore/rendering/RenderObject.cpp
Source/WebCore/rendering/RenderObject.h
Source/WebCore/rendering/RenderView.cpp
Source/WebCore/rendering/RenderView.h
Source/WebCore/testing/Internals.cpp