Changeset 211008 in webkit


Ignore:
Timestamp:
Jan 20, 2017 6:31:33 PM (7 years ago)
Author:
commit-queue@webkit.org
Message:

Record whether a media element was prevented from playing without user interaction
https://bugs.webkit.org/show_bug.cgi?id=167214

Patch by Matt Rajca <mrajca@apple.com> on 2017-01-20
Reviewed by Eric Carlson.

This state will be used to notify clients when a user explicitly starts playback
of a media element that was prevented from autoplaying.

Tests will be added after a WebKit callback API is added.

  • WebCore.xcodeproj/project.pbxproj:
  • dom/SuccessOr.h: Added.

(WebCore::SuccessOr::SuccessOr):
(WebCore::SuccessOr::operator bool):

  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::canTransitionFromAutoplayToPlay):
(WebCore::HTMLMediaElement::setReadyState):
(WebCore::HTMLMediaElement::play):
(WebCore::HTMLMediaElement::playInternal):

  • html/HTMLMediaElement.h:
  • html/MediaElementSession.cpp:

(WebCore::MediaElementSession::playbackPermitted):

  • html/MediaElementSession.h:
Location:
trunk/Source/WebCore
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r211007 r211008  
     12017-01-20  Matt Rajca  <mrajca@apple.com>
     2
     3        Record whether a media element was prevented from playing without user interaction
     4        https://bugs.webkit.org/show_bug.cgi?id=167214
     5
     6        Reviewed by Eric Carlson.
     7
     8        This state will be used to notify clients when a user explicitly starts playback
     9        of a media element that was prevented from autoplaying.
     10
     11        Tests will be added after a WebKit callback API is added.
     12
     13        * WebCore.xcodeproj/project.pbxproj:
     14        * dom/SuccessOr.h: Added.
     15        (WebCore::SuccessOr::SuccessOr):
     16        (WebCore::SuccessOr::operator bool):
     17        * html/HTMLMediaElement.cpp:
     18        (WebCore::HTMLMediaElement::canTransitionFromAutoplayToPlay):
     19        (WebCore::HTMLMediaElement::setReadyState):
     20        (WebCore::HTMLMediaElement::play):
     21        (WebCore::HTMLMediaElement::playInternal):
     22        * html/HTMLMediaElement.h:
     23        * html/MediaElementSession.cpp:
     24        (WebCore::MediaElementSession::playbackPermitted):
     25        * html/MediaElementSession.h:
     26
    1272017-01-20  Brady Eidson  <beidson@apple.com>
    228
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r210936 r211008  
    56965696                C96F5EC71B5872260091EA9D /* MediaSessionInterruptionProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C96F5EC31B5872260091EA9D /* MediaSessionInterruptionProvider.cpp */; };
    56975697                C96F5EC81B5872260091EA9D /* MediaSessionInterruptionProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = C96F5EC41B5872260091EA9D /* MediaSessionInterruptionProvider.h */; };
     5698                C99058131E32C75F0073BDDA /* SuccessOr.h in Headers */ = {isa = PBXBuildFile; fileRef = C99058121E32B7340073BDDA /* SuccessOr.h */; settings = {ATTRIBUTES = (Private, ); }; };
    56985699                C9D851F01B39DC780085062E /* MediaSessionMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = C9D851EE1B39DC780085062E /* MediaSessionMetadata.h */; settings = {ATTRIBUTES = (Private, ); }; };
    56995700                C9DADBCB1B1D3B97001F17D8 /* JSMediaSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C9DADBC91B1D3B25001F17D8 /* JSMediaSession.cpp */; };
     
    1362913630                C96F5EC31B5872260091EA9D /* MediaSessionInterruptionProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaSessionInterruptionProvider.cpp; sourceTree = "<group>"; };
    1363013631                C96F5EC41B5872260091EA9D /* MediaSessionInterruptionProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaSessionInterruptionProvider.h; sourceTree = "<group>"; };
     13632                C99058121E32B7340073BDDA /* SuccessOr.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SuccessOr.h; sourceTree = "<group>"; };
    1363113633                C9D851EE1B39DC780085062E /* MediaSessionMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaSessionMetadata.h; sourceTree = "<group>"; };
    1363213634                C9DADBC91B1D3B25001F17D8 /* JSMediaSession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaSession.cpp; sourceTree = "<group>"; };
     
    2435624358                                A8C4A7EC09D563270003AC8D /* StyledElement.cpp */,
    2435724359                                A8C4A7EB09D563270003AC8D /* StyledElement.h */,
     24360                                C99058121E32B7340073BDDA /* SuccessOr.h */,
    2435824361                                463EB6201B8789CB0096ED51 /* TagCollection.cpp */,
    2435924362                                463EB6211B8789CB0096ED51 /* TagCollection.h */,
     
    2764427647                                D01A27AE10C9BFD800026A42 /* SpaceSplitString.h in Headers */,
    2764527648                                626CDE0F1140424C001E5A68 /* SpatialNavigation.h in Headers */,
     27649                                C99058131E32C75F0073BDDA /* SuccessOr.h in Headers */,
    2764627650                                AA2A5AD416A4861100975A25 /* SpeechSynthesis.h in Headers */,
    2764727651                                AA2A5AD216A4860A00975A25 /* SpeechSynthesisEvent.h in Headers */,
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r210859 r211008  
    22542254}
    22552255
    2256 bool HTMLMediaElement::canTransitionFromAutoplayToPlay() const
    2257 {
    2258     return isAutoplaying()
    2259         && mediaSession().autoplayPermitted()
    2260         && paused()
    2261         && autoplay()
    2262         && !pausedForUserInteraction()
    2263         && !document().isSandboxed(SandboxAutomaticFeatures)
    2264         && mediaSession().playbackPermitted(*this);
     2256SuccessOr<MediaPlaybackDenialReason> HTMLMediaElement::canTransitionFromAutoplayToPlay() const
     2257{
     2258    if (isAutoplaying()
     2259     && mediaSession().autoplayPermitted()
     2260     && paused()
     2261     && autoplay()
     2262     && !pausedForUserInteraction()
     2263     && !document().isSandboxed(SandboxAutomaticFeatures))
     2264        return mediaSession().playbackPermitted(*this);
     2265
     2266    return MediaPlaybackDenialReason::PageConsentRequired;
    22652267}
    22662268
     
    23762378            scheduleNotifyAboutPlaying();
    23772379
    2378         if (canTransitionFromAutoplayToPlay()) {
     2380        auto success = canTransitionFromAutoplayToPlay();
     2381        if (success) {
    23792382            m_paused = false;
    23802383            invalidateCachedTime();
     
    23822385            scheduleEvent(eventNames().playEvent);
    23832386            scheduleNotifyAboutPlaying();
    2384         }
     2387        } else if (success.value() == MediaPlaybackDenialReason::UserGestureRequired)
     2388            m_preventedFromPlayingWithoutUserGesture = true;
    23852389
    23862390        shouldUpdateDisplayState = true;
     
    30623066    LOG(Media, "HTMLMediaElement::play(%p)", this);
    30633067
    3064     if (!m_mediaSession->playbackPermitted(*this)) {
     3068    auto success = m_mediaSession->playbackPermitted(*this);
     3069    if (!success) {
     3070        if (success.value() == MediaPlaybackDenialReason::UserGestureRequired)
     3071            m_preventedFromPlayingWithoutUserGesture = true;
    30653072        promise.reject(NotAllowedError);
    30663073        return;
     
    30873094    LOG(Media, "HTMLMediaElement::play(%p)", this);
    30883095
    3089     if (!m_mediaSession->playbackPermitted(*this))
    3090         return;
     3096    auto success = m_mediaSession->playbackPermitted(*this);
     3097    if (!success) {
     3098        if (success.value() == MediaPlaybackDenialReason::UserGestureRequired)
     3099            m_preventedFromPlayingWithoutUserGesture = true;
     3100        return;
     3101    }
    30913102    if (ScriptController::processingUserGestureForMedia())
    30923103        removeBehaviorsRestrictionsAfterFirstUserGesture();
     
    31523163    } else if (m_readyState >= HAVE_FUTURE_DATA)
    31533164        scheduleResolvePendingPlayPromises();
     3165
     3166    if (ScriptController::processingUserGestureForMedia() && m_preventedFromPlayingWithoutUserGesture) {
     3167        // FIXME: notify clients a user gesture was made and started playback of an element that was otherwise prevented from playing.
     3168        m_preventedFromPlayingWithoutUserGesture = false;
     3169    }
    31543170
    31553171    m_autoplaying = false;
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r210780 r211008  
    720720    bool pausedForUserInteraction() const;
    721721    bool couldPlayIfEnoughData() const;
    722     bool canTransitionFromAutoplayToPlay() const;
     722    SuccessOr<MediaPlaybackDenialReason> canTransitionFromAutoplayToPlay() const;
    723723
    724724    MediaTime minTimeSeekable() const;
     
    962962    bool m_receivedLayoutSizeChanged : 1;
    963963    bool m_hasEverNotifiedAboutPlaying : 1;
     964    bool m_preventedFromPlayingWithoutUserGesture : 1;
    964965
    965966    bool m_hasEverHadAudio : 1;
  • trunk/Source/WebCore/html/MediaElementSession.cpp

    r210828 r211008  
    149149}
    150150
    151 bool MediaElementSession::playbackPermitted(const HTMLMediaElement& element) const
     151SuccessOr<MediaPlaybackDenialReason> MediaElementSession::playbackPermitted(const HTMLMediaElement& element) const
    152152{
    153153    if (element.document().isMediaDocument() && !element.document().ownerElement())
    154         return true;
     154        return SuccessOr<MediaPlaybackDenialReason>();
    155155
    156156    if (pageExplicitlyAllowsElementToAutoplayInline(element))
    157         return true;
     157        return SuccessOr<MediaPlaybackDenialReason>();
    158158
    159159    if (requiresFullscreenForVideoPlayback(element) && !fullscreenPermitted(element)) {
    160160        LOG(Media, "MediaElementSession::playbackPermitted - returning FALSE because of fullscreen restriction");
    161         return false;
     161        return MediaPlaybackDenialReason::FullscreenRequired;
    162162    }
    163163
    164164    if (m_restrictions & OverrideUserGestureRequirementForMainContent && updateIsMainContent())
    165         return true;
     165        return SuccessOr<MediaPlaybackDenialReason>();
    166166
    167167    if (m_restrictions & RequireUserGestureForVideoRateChange && element.isVideo() && !ScriptController::processingUserGestureForMedia()) {
    168168        LOG(Media, "MediaElementSession::playbackPermitted - returning FALSE because of video rate change restriction");
    169         return false;
     169        return MediaPlaybackDenialReason::UserGestureRequired;
    170170    }
    171171
    172172    if (m_restrictions & RequireUserGestureForAudioRateChange && (!element.isVideo() || element.hasAudio()) && !element.muted() && !ScriptController::processingUserGestureForMedia()) {
    173173        LOG(Media, "MediaElementSession::playbackPermitted - returning FALSE because of audio rate change restriction");
    174         return false;
    175     }
    176 
    177     return true;
     174        return MediaPlaybackDenialReason::UserGestureRequired;
     175    }
     176
     177    return SuccessOr<MediaPlaybackDenialReason>();
    178178}
    179179
  • trunk/Source/WebCore/html/MediaElementSession.h

    r208464 r211008  
    3030#include "MediaPlayer.h"
    3131#include "PlatformMediaSession.h"
     32#include "SuccessOr.h"
    3233#include "Timer.h"
    3334#include <wtf/TypeCasts.h>
     
    3839    MediaControls,
    3940    Autoplay
     41};
     42
     43enum class MediaPlaybackDenialReason {
     44    UserGestureRequired,
     45    FullscreenRequired,
     46    PageConsentRequired,
    4047};
    4148
     
    5360    void unregisterWithDocument(Document&);
    5461
    55     bool playbackPermitted(const HTMLMediaElement&) const;
     62    SuccessOr<MediaPlaybackDenialReason> playbackPermitted(const HTMLMediaElement&) const;
    5663    bool autoplayPermitted() const;
    5764    bool dataLoadingPermitted(const HTMLMediaElement&) const;
Note: See TracChangeset for help on using the changeset viewer.