Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1114)

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp

Issue 2681863005: [Video] MediaSession API event handlers can resume background video. (Closed)
Patch Set: Tweaked the logic in HTMLME a bit Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLMediaElement.h ('k') | third_party/WebKit/public/platform/WebMediaPlayerClient.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698