Changeset 211008 in webkit
- Timestamp:
- Jan 20, 2017 6:31:33 PM (7 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r211007 r211008 1 2017-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 1 27 2017-01-20 Brady Eidson <beidson@apple.com> 2 28 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r210936 r211008 5696 5696 C96F5EC71B5872260091EA9D /* MediaSessionInterruptionProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C96F5EC31B5872260091EA9D /* MediaSessionInterruptionProvider.cpp */; }; 5697 5697 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, ); }; }; 5698 5699 C9D851F01B39DC780085062E /* MediaSessionMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = C9D851EE1B39DC780085062E /* MediaSessionMetadata.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5699 5700 C9DADBCB1B1D3B97001F17D8 /* JSMediaSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C9DADBC91B1D3B25001F17D8 /* JSMediaSession.cpp */; }; … … 13629 13630 C96F5EC31B5872260091EA9D /* MediaSessionInterruptionProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaSessionInterruptionProvider.cpp; sourceTree = "<group>"; }; 13630 13631 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>"; }; 13631 13633 C9D851EE1B39DC780085062E /* MediaSessionMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaSessionMetadata.h; sourceTree = "<group>"; }; 13632 13634 C9DADBC91B1D3B25001F17D8 /* JSMediaSession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaSession.cpp; sourceTree = "<group>"; }; … … 24356 24358 A8C4A7EC09D563270003AC8D /* StyledElement.cpp */, 24357 24359 A8C4A7EB09D563270003AC8D /* StyledElement.h */, 24360 C99058121E32B7340073BDDA /* SuccessOr.h */, 24358 24361 463EB6201B8789CB0096ED51 /* TagCollection.cpp */, 24359 24362 463EB6211B8789CB0096ED51 /* TagCollection.h */, … … 27644 27647 D01A27AE10C9BFD800026A42 /* SpaceSplitString.h in Headers */, 27645 27648 626CDE0F1140424C001E5A68 /* SpatialNavigation.h in Headers */, 27649 C99058131E32C75F0073BDDA /* SuccessOr.h in Headers */, 27646 27650 AA2A5AD416A4861100975A25 /* SpeechSynthesis.h in Headers */, 27647 27651 AA2A5AD216A4860A00975A25 /* SpeechSynthesisEvent.h in Headers */, -
trunk/Source/WebCore/html/HTMLMediaElement.cpp
r210859 r211008 2254 2254 } 2255 2255 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); 2256 SuccessOr<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; 2265 2267 } 2266 2268 … … 2376 2378 scheduleNotifyAboutPlaying(); 2377 2379 2378 if (canTransitionFromAutoplayToPlay()) { 2380 auto success = canTransitionFromAutoplayToPlay(); 2381 if (success) { 2379 2382 m_paused = false; 2380 2383 invalidateCachedTime(); … … 2382 2385 scheduleEvent(eventNames().playEvent); 2383 2386 scheduleNotifyAboutPlaying(); 2384 } 2387 } else if (success.value() == MediaPlaybackDenialReason::UserGestureRequired) 2388 m_preventedFromPlayingWithoutUserGesture = true; 2385 2389 2386 2390 shouldUpdateDisplayState = true; … … 3062 3066 LOG(Media, "HTMLMediaElement::play(%p)", this); 3063 3067 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; 3065 3072 promise.reject(NotAllowedError); 3066 3073 return; … … 3087 3094 LOG(Media, "HTMLMediaElement::play(%p)", this); 3088 3095 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 } 3091 3102 if (ScriptController::processingUserGestureForMedia()) 3092 3103 removeBehaviorsRestrictionsAfterFirstUserGesture(); … … 3152 3163 } else if (m_readyState >= HAVE_FUTURE_DATA) 3153 3164 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 } 3154 3170 3155 3171 m_autoplaying = false; -
trunk/Source/WebCore/html/HTMLMediaElement.h
r210780 r211008 720 720 bool pausedForUserInteraction() const; 721 721 bool couldPlayIfEnoughData() const; 722 boolcanTransitionFromAutoplayToPlay() const;722 SuccessOr<MediaPlaybackDenialReason> canTransitionFromAutoplayToPlay() const; 723 723 724 724 MediaTime minTimeSeekable() const; … … 962 962 bool m_receivedLayoutSizeChanged : 1; 963 963 bool m_hasEverNotifiedAboutPlaying : 1; 964 bool m_preventedFromPlayingWithoutUserGesture : 1; 964 965 965 966 bool m_hasEverHadAudio : 1; -
trunk/Source/WebCore/html/MediaElementSession.cpp
r210828 r211008 149 149 } 150 150 151 boolMediaElementSession::playbackPermitted(const HTMLMediaElement& element) const151 SuccessOr<MediaPlaybackDenialReason> MediaElementSession::playbackPermitted(const HTMLMediaElement& element) const 152 152 { 153 153 if (element.document().isMediaDocument() && !element.document().ownerElement()) 154 return true;154 return SuccessOr<MediaPlaybackDenialReason>(); 155 155 156 156 if (pageExplicitlyAllowsElementToAutoplayInline(element)) 157 return true;157 return SuccessOr<MediaPlaybackDenialReason>(); 158 158 159 159 if (requiresFullscreenForVideoPlayback(element) && !fullscreenPermitted(element)) { 160 160 LOG(Media, "MediaElementSession::playbackPermitted - returning FALSE because of fullscreen restriction"); 161 return false;161 return MediaPlaybackDenialReason::FullscreenRequired; 162 162 } 163 163 164 164 if (m_restrictions & OverrideUserGestureRequirementForMainContent && updateIsMainContent()) 165 return true;165 return SuccessOr<MediaPlaybackDenialReason>(); 166 166 167 167 if (m_restrictions & RequireUserGestureForVideoRateChange && element.isVideo() && !ScriptController::processingUserGestureForMedia()) { 168 168 LOG(Media, "MediaElementSession::playbackPermitted - returning FALSE because of video rate change restriction"); 169 return false;169 return MediaPlaybackDenialReason::UserGestureRequired; 170 170 } 171 171 172 172 if (m_restrictions & RequireUserGestureForAudioRateChange && (!element.isVideo() || element.hasAudio()) && !element.muted() && !ScriptController::processingUserGestureForMedia()) { 173 173 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>(); 178 178 } 179 179 -
trunk/Source/WebCore/html/MediaElementSession.h
r208464 r211008 30 30 #include "MediaPlayer.h" 31 31 #include "PlatformMediaSession.h" 32 #include "SuccessOr.h" 32 33 #include "Timer.h" 33 34 #include <wtf/TypeCasts.h> … … 38 39 MediaControls, 39 40 Autoplay 41 }; 42 43 enum class MediaPlaybackDenialReason { 44 UserGestureRequired, 45 FullscreenRequired, 46 PageConsentRequired, 40 47 }; 41 48 … … 53 60 void unregisterWithDocument(Document&); 54 61 55 boolplaybackPermitted(const HTMLMediaElement&) const;62 SuccessOr<MediaPlaybackDenialReason> playbackPermitted(const HTMLMediaElement&) const; 56 63 bool autoplayPermitted() const; 57 64 bool dataLoadingPermitted(const HTMLMediaElement&) const;
Note: See TracChangeset
for help on using the changeset viewer.