OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights | 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights |
3 * reserved. | 3 * reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
11 * notice, this list of conditions and the following disclaimer in the | 11 * notice, this list of conditions and the following disclaimer in the |
12 * documentation and/or other materials provided with the distribution. | 12 * documentation and/or other materials provided with the distribution. |
13 * | 13 * |
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 */ | 25 */ |
26 | 26 |
27 #include "core/html/HTMLMediaElement.h" | 27 #include "core/html/HTMLMediaElement.h" |
28 | 28 |
29 #include <limits> | |
29 #include "bindings/core/v8/ExceptionState.h" | 30 #include "bindings/core/v8/ExceptionState.h" |
30 #include "bindings/core/v8/Microtask.h" | 31 #include "bindings/core/v8/Microtask.h" |
31 #include "bindings/core/v8/ScriptController.h" | 32 #include "bindings/core/v8/ScriptController.h" |
32 #include "bindings/core/v8/ScriptEventListener.h" | 33 #include "bindings/core/v8/ScriptEventListener.h" |
33 #include "bindings/core/v8/ScriptPromiseResolver.h" | 34 #include "bindings/core/v8/ScriptPromiseResolver.h" |
34 #include "core/HTMLNames.h" | 35 #include "core/HTMLNames.h" |
35 #include "core/css/MediaList.h" | 36 #include "core/css/MediaList.h" |
36 #include "core/dom/Attribute.h" | 37 #include "core/dom/Attribute.h" |
37 #include "core/dom/DOMException.h" | 38 #include "core/dom/DOMException.h" |
39 #include "core/dom/DocumentUserGestureToken.h" | |
38 #include "core/dom/ElementTraversal.h" | 40 #include "core/dom/ElementTraversal.h" |
39 #include "core/dom/ElementVisibilityObserver.h" | 41 #include "core/dom/ElementVisibilityObserver.h" |
40 #include "core/dom/Fullscreen.h" | 42 #include "core/dom/Fullscreen.h" |
41 #include "core/dom/TaskRunnerHelper.h" | 43 #include "core/dom/TaskRunnerHelper.h" |
42 #include "core/dom/shadow/ShadowRoot.h" | 44 #include "core/dom/shadow/ShadowRoot.h" |
43 #include "core/events/Event.h" | 45 #include "core/events/Event.h" |
44 #include "core/frame/FrameView.h" | 46 #include "core/frame/FrameView.h" |
45 #include "core/frame/LocalFrame.h" | 47 #include "core/frame/LocalFrame.h" |
46 #include "core/frame/Settings.h" | 48 #include "core/frame/Settings.h" |
47 #include "core/frame/UseCounter.h" | 49 #include "core/frame/UseCounter.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
90 #include "public/platform/WebMediaPlayerSource.h" | 92 #include "public/platform/WebMediaPlayerSource.h" |
91 #include "public/platform/WebMediaStream.h" | 93 #include "public/platform/WebMediaStream.h" |
92 #include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h " | 94 #include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h " |
93 #include "public/platform/modules/remoteplayback/WebRemotePlaybackClient.h" | 95 #include "public/platform/modules/remoteplayback/WebRemotePlaybackClient.h" |
94 #include "public/platform/modules/remoteplayback/WebRemotePlaybackState.h" | 96 #include "public/platform/modules/remoteplayback/WebRemotePlaybackState.h" |
95 #include "wtf/AutoReset.h" | 97 #include "wtf/AutoReset.h" |
96 #include "wtf/CurrentTime.h" | 98 #include "wtf/CurrentTime.h" |
97 #include "wtf/MathExtras.h" | 99 #include "wtf/MathExtras.h" |
98 #include "wtf/PtrUtil.h" | 100 #include "wtf/PtrUtil.h" |
99 #include "wtf/text/CString.h" | 101 #include "wtf/text/CString.h" |
100 #include <limits> | |
101 | 102 |
102 #ifndef BLINK_MEDIA_LOG | 103 #ifndef BLINK_MEDIA_LOG |
103 #define BLINK_MEDIA_LOG DVLOG(3) | 104 #define BLINK_MEDIA_LOG DVLOG(3) |
104 #endif | 105 #endif |
105 | 106 |
106 #ifndef LOG_MEDIA_EVENTS | 107 #ifndef LOG_MEDIA_EVENTS |
107 // Default to not logging events because so many are generated they can | 108 // Default to not logging events because so many are generated they can |
108 // overwhelm the rest of the logging. | 109 // overwhelm the rest of the logging. |
109 #define LOG_MEDIA_EVENTS 0 | 110 #define LOG_MEDIA_EVENTS 0 |
110 #endif | 111 #endif |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
417 m_deferredLoadState(NotDeferred), | 418 m_deferredLoadState(NotDeferred), |
418 m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired), | 419 m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired), |
419 m_webLayer(nullptr), | 420 m_webLayer(nullptr), |
420 m_displayMode(Unknown), | 421 m_displayMode(Unknown), |
421 m_officialPlaybackPosition(0), | 422 m_officialPlaybackPosition(0), |
422 m_officialPlaybackPositionNeedsUpdate(true), | 423 m_officialPlaybackPositionNeedsUpdate(true), |
423 m_fragmentEndTime(std::numeric_limits<double>::quiet_NaN()), | 424 m_fragmentEndTime(std::numeric_limits<double>::quiet_NaN()), |
424 m_pendingActionFlags(0), | 425 m_pendingActionFlags(0), |
425 m_lockedPendingUserGesture(false), | 426 m_lockedPendingUserGesture(false), |
426 m_lockedPendingUserGestureIfCrossOriginExperimentEnabled(true), | 427 m_lockedPendingUserGestureIfCrossOriginExperimentEnabled(true), |
428 m_wasLockedWhenBackgrounded(false), | |
427 m_playing(false), | 429 m_playing(false), |
428 m_shouldDelayLoadEvent(false), | 430 m_shouldDelayLoadEvent(false), |
429 m_haveFiredLoadedData(false), | 431 m_haveFiredLoadedData(false), |
430 m_canAutoplay(true), | 432 m_canAutoplay(true), |
431 m_muted(false), | 433 m_muted(false), |
432 m_paused(true), | 434 m_paused(true), |
433 m_seeking(false), | 435 m_seeking(false), |
434 m_sentStalledEvent(false), | 436 m_sentStalledEvent(false), |
435 m_ignorePreloadNone(false), | 437 m_ignorePreloadNone(false), |
436 m_textTracksVisible(false), | 438 m_textTracksVisible(false), |
(...skipping 1871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2308 | 2310 |
2309 setIgnorePreloadNone(); | 2311 setIgnorePreloadNone(); |
2310 updatePlayState(); | 2312 updatePlayState(); |
2311 } | 2313 } |
2312 | 2314 |
2313 void HTMLMediaElement::pause() { | 2315 void HTMLMediaElement::pause() { |
2314 BLINK_MEDIA_LOG << "pause(" << (void*)this << ")"; | 2316 BLINK_MEDIA_LOG << "pause(" << (void*)this << ")"; |
2315 | 2317 |
2316 // Only buffer aggressively on a user-initiated pause. Other types of pauses | 2318 // Only buffer aggressively on a user-initiated pause. Other types of pauses |
2317 // (which go directly to pauseInternal()) should not cause this behavior. | 2319 // (which go directly to pauseInternal()) should not cause this behavior. |
2318 if (webMediaPlayer() && UserGestureIndicator::utilizeUserGesture()) | 2320 if (webMediaPlayer() && UserGestureIndicator::utilizeUserGesture()) { |
2319 webMediaPlayer()->setBufferingStrategy( | 2321 webMediaPlayer()->setBufferingStrategy( |
2320 WebMediaPlayer::BufferingStrategy::Aggressive); | 2322 WebMediaPlayer::BufferingStrategy::Aggressive); |
2323 } | |
2321 | 2324 |
2322 if (m_autoplayVisibilityObserver) { | 2325 if (m_autoplayVisibilityObserver) { |
2323 m_autoplayVisibilityObserver->stop(); | 2326 m_autoplayVisibilityObserver->stop(); |
2324 m_autoplayVisibilityObserver = nullptr; | 2327 m_autoplayVisibilityObserver = nullptr; |
2325 } | 2328 } |
2326 | 2329 |
2327 pauseInternal(); | 2330 pauseInternal(); |
2328 } | 2331 } |
2329 | 2332 |
2330 void HTMLMediaElement::pauseInternal() { | 2333 void HTMLMediaElement::pauseInternal() { |
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3113 if (requestSeek) | 3116 if (requestSeek) |
3114 seek(duration); | 3117 seek(duration); |
3115 } | 3118 } |
3116 | 3119 |
3117 void HTMLMediaElement::playbackStateChanged() { | 3120 void HTMLMediaElement::playbackStateChanged() { |
3118 BLINK_MEDIA_LOG << "playbackStateChanged(" << (void*)this << ")"; | 3121 BLINK_MEDIA_LOG << "playbackStateChanged(" << (void*)this << ")"; |
3119 | 3122 |
3120 if (!webMediaPlayer()) | 3123 if (!webMediaPlayer()) |
3121 return; | 3124 return; |
3122 | 3125 |
3126 // playbackStateChanged() is always a result of a user gesture. | |
3127 UserGestureIndicator gestureIndicator( | |
3128 DocumentUserGestureToken::create(&document())); | |
3123 if (webMediaPlayer()->paused()) | 3129 if (webMediaPlayer()->paused()) |
3124 pauseInternal(); | 3130 pause(); |
3125 else | 3131 else |
3126 playInternal(); | 3132 play(); |
3127 } | 3133 } |
mlamouri (slow - plz ping)
2017/02/20 12:00:17
I know you already replied to this comment but thi
whywhat
2017/02/20 17:16:04
If I understood Dan correctly - in general, no :)
| |
3128 | 3134 |
3129 void HTMLMediaElement::requestSeek(double time) { | 3135 void HTMLMediaElement::requestSeek(double time) { |
3130 // The player is the source of this seek request. | 3136 // The player is the source of this seek request. |
3131 setCurrentTime(time); | 3137 setCurrentTime(time); |
3132 } | 3138 } |
3133 | 3139 |
3134 void HTMLMediaElement::remoteRouteAvailabilityChanged( | 3140 void HTMLMediaElement::remoteRouteAvailabilityChanged( |
3135 WebRemotePlaybackAvailability availability) { | 3141 WebRemotePlaybackAvailability availability) { |
3136 if (remotePlaybackClient()) | 3142 if (remotePlaybackClient()) |
3137 remotePlaybackClient()->availabilityChanged(availability); | 3143 remotePlaybackClient()->availabilityChanged(availability); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3178 void HTMLMediaElement::cancelledRemotePlaybackRequest() { | 3184 void HTMLMediaElement::cancelledRemotePlaybackRequest() { |
3179 if (remotePlaybackClient()) | 3185 if (remotePlaybackClient()) |
3180 remotePlaybackClient()->promptCancelled(); | 3186 remotePlaybackClient()->promptCancelled(); |
3181 } | 3187 } |
3182 | 3188 |
3183 void HTMLMediaElement::remotePlaybackStarted() { | 3189 void HTMLMediaElement::remotePlaybackStarted() { |
3184 if (remotePlaybackClient()) | 3190 if (remotePlaybackClient()) |
3185 remotePlaybackClient()->stateChanged(WebRemotePlaybackState::Connected); | 3191 remotePlaybackClient()->stateChanged(WebRemotePlaybackState::Connected); |
3186 } | 3192 } |
3187 | 3193 |
3194 void HTMLMediaElement::wasPausedWhenBackgrounded() { | |
3195 // Prevent websites from resuming elements paused when backgrounded if | |
3196 // user gesture is required for playback. | |
3197 m_wasLockedWhenBackgrounded = m_lockedPendingUserGesture; | |
3198 m_lockedPendingUserGesture = computeLockedPendingUserGesture(document()); | |
3199 } | |
3200 | |
3201 void HTMLMediaElement::wasResumedWhenForegrounded() { | |
3202 // If the element was resumed when foregrounded, restore its unlocked state. | |
3203 if (m_lockedPendingUserGesture && !m_wasLockedWhenBackgrounded) | |
3204 m_lockedPendingUserGesture = false; | |
3205 } | |
mlamouri (slow - plz ping)
2017/02/20 12:00:17
Instead of this logic, would it make sense if the
whywhat
2017/02/20 17:16:04
It should only require a user gesture until it's u
| |
3206 | |
3188 bool HTMLMediaElement::hasSelectedVideoTrack() { | 3207 bool HTMLMediaElement::hasSelectedVideoTrack() { |
3189 DCHECK(RuntimeEnabledFeatures::backgroundVideoTrackOptimizationEnabled()); | 3208 DCHECK(RuntimeEnabledFeatures::backgroundVideoTrackOptimizationEnabled()); |
3190 | 3209 |
3191 return m_videoTracks && m_videoTracks->selectedIndex() != -1; | 3210 return m_videoTracks && m_videoTracks->selectedIndex() != -1; |
3192 } | 3211 } |
3193 | 3212 |
3194 WebMediaPlayer::TrackId HTMLMediaElement::getSelectedVideoTrackId() { | 3213 WebMediaPlayer::TrackId HTMLMediaElement::getSelectedVideoTrackId() { |
3195 DCHECK(RuntimeEnabledFeatures::backgroundVideoTrackOptimizationEnabled()); | 3214 DCHECK(RuntimeEnabledFeatures::backgroundVideoTrackOptimizationEnabled()); |
3196 DCHECK(hasSelectedVideoTrack()); | 3215 DCHECK(hasSelectedVideoTrack()); |
3197 | 3216 |
3198 int selectedTrackIndex = m_videoTracks->selectedIndex(); | 3217 int selectedTrackIndex = m_videoTracks->selectedIndex(); |
3199 VideoTrack* track = m_videoTracks->anonymousIndexedGetter(selectedTrackIndex); | 3218 VideoTrack* track = m_videoTracks->anonymousIndexedGetter(selectedTrackIndex); |
3200 return track->id(); | 3219 return track->id(); |
3201 } | 3220 } |
3202 | 3221 |
3203 bool HTMLMediaElement::isAutoplayingMuted() { | 3222 bool HTMLMediaElement::isAutoplayingMuted() { |
3204 if (!isHTMLVideoElement() || | 3223 if (!isHTMLVideoElement() || |
3205 !RuntimeEnabledFeatures::autoplayMutedVideosEnabled()) { | 3224 !RuntimeEnabledFeatures::autoplayMutedVideosEnabled()) { |
3206 return false; | 3225 return false; |
3207 } | 3226 } |
3208 | 3227 |
3209 return !paused() && muted() && isLockedPendingUserGesture(); | 3228 return !paused() && muted() && isLockedPendingUserGesture(); |
3210 } | 3229 } |
3211 | 3230 |
3231 bool HTMLMediaElement::isBackgroundVideoPlaybackUnlocked() { | |
3232 return !isLockedPendingUserGesture(); | |
3233 } | |
3234 | |
3212 void HTMLMediaElement::requestReload(const WebURL& newUrl) { | 3235 void HTMLMediaElement::requestReload(const WebURL& newUrl) { |
3213 DCHECK(webMediaPlayer()); | 3236 DCHECK(webMediaPlayer()); |
3214 DCHECK(!m_srcObject); | 3237 DCHECK(!m_srcObject); |
3215 DCHECK(newUrl.isValid()); | 3238 DCHECK(newUrl.isValid()); |
3216 DCHECK(isSafeToLoadURL(newUrl, Complain)); | 3239 DCHECK(isSafeToLoadURL(newUrl, Complain)); |
3217 resetMediaPlayerAndMediaSource(); | 3240 resetMediaPlayerAndMediaSource(); |
3218 startPlayerLoad(newUrl); | 3241 startPlayerLoad(newUrl); |
3219 } | 3242 } |
3220 | 3243 |
3221 // MediaPlayerPresentation methods | 3244 // MediaPlayerPresentation methods |
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3846 bool HTMLMediaElement::isLockedPendingUserGesture() const { | 3869 bool HTMLMediaElement::isLockedPendingUserGesture() const { |
3847 return m_lockedPendingUserGesture; | 3870 return m_lockedPendingUserGesture; |
3848 } | 3871 } |
3849 | 3872 |
3850 void HTMLMediaElement::unlockUserGesture() { | 3873 void HTMLMediaElement::unlockUserGesture() { |
3851 m_lockedPendingUserGesture = false; | 3874 m_lockedPendingUserGesture = false; |
3852 m_lockedPendingUserGestureIfCrossOriginExperimentEnabled = false; | 3875 m_lockedPendingUserGestureIfCrossOriginExperimentEnabled = false; |
3853 } | 3876 } |
3854 | 3877 |
3855 bool HTMLMediaElement::isGestureNeededForPlayback() const { | 3878 bool HTMLMediaElement::isGestureNeededForPlayback() const { |
3856 if (!m_lockedPendingUserGesture) | 3879 if (!isLockedPendingUserGesture()) |
3857 return false; | 3880 return false; |
3858 | 3881 |
3859 return isGestureNeededForPlaybackIfPendingUserGestureIsLocked(); | 3882 return isGestureNeededForPlaybackIfPendingUserGestureIsLocked(); |
3860 } | 3883 } |
3861 | 3884 |
3862 bool HTMLMediaElement:: | 3885 bool HTMLMediaElement:: |
3863 isGestureNeededForPlaybackIfCrossOriginExperimentEnabled() const { | 3886 isGestureNeededForPlaybackIfCrossOriginExperimentEnabled() const { |
3864 if (!m_lockedPendingUserGestureIfCrossOriginExperimentEnabled) | 3887 if (!m_lockedPendingUserGestureIfCrossOriginExperimentEnabled) |
3865 return false; | 3888 return false; |
3866 | 3889 |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4148 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); | 4171 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); |
4149 } | 4172 } |
4150 | 4173 |
4151 void HTMLMediaElement::viewportFillDebouncerTimerFired(TimerBase*) { | 4174 void HTMLMediaElement::viewportFillDebouncerTimerFired(TimerBase*) { |
4152 m_mostlyFillingViewport = true; | 4175 m_mostlyFillingViewport = true; |
4153 if (m_webMediaPlayer) | 4176 if (m_webMediaPlayer) |
4154 m_webMediaPlayer->becameDominantVisibleContent(m_mostlyFillingViewport); | 4177 m_webMediaPlayer->becameDominantVisibleContent(m_mostlyFillingViewport); |
4155 } | 4178 } |
4156 | 4179 |
4157 } // namespace blink | 4180 } // namespace blink |
OLD | NEW |