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

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

Issue 1576283003: Have HTMLMediaElement::play() return a Promise. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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 reserved. 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 11 matching lines...) Expand all
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "core/html/HTMLMediaElement.h" 26 #include "core/html/HTMLMediaElement.h"
27 27
28 #include "bindings/core/v8/ExceptionState.h" 28 #include "bindings/core/v8/ExceptionState.h"
29 #include "bindings/core/v8/ExceptionStatePlaceholder.h" 29 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
30 #include "bindings/core/v8/ScriptController.h" 30 #include "bindings/core/v8/ScriptController.h"
31 #include "bindings/core/v8/ScriptEventListener.h" 31 #include "bindings/core/v8/ScriptEventListener.h"
32 #include "bindings/core/v8/ScriptPromiseResolver.h"
32 #include "core/HTMLNames.h" 33 #include "core/HTMLNames.h"
33 #include "core/css/MediaList.h" 34 #include "core/css/MediaList.h"
34 #include "core/dom/Attribute.h" 35 #include "core/dom/Attribute.h"
35 #include "core/dom/ElementTraversal.h" 36 #include "core/dom/ElementTraversal.h"
36 #include "core/dom/ExceptionCode.h"
37 #include "core/dom/Fullscreen.h" 37 #include "core/dom/Fullscreen.h"
38 #include "core/dom/shadow/ShadowRoot.h" 38 #include "core/dom/shadow/ShadowRoot.h"
39 #include "core/events/Event.h" 39 #include "core/events/Event.h"
40 #include "core/frame/LocalFrame.h" 40 #include "core/frame/LocalFrame.h"
41 #include "core/frame/Settings.h" 41 #include "core/frame/Settings.h"
42 #include "core/frame/UseCounter.h" 42 #include "core/frame/UseCounter.h"
43 #include "core/frame/csp/ContentSecurityPolicy.h" 43 #include "core/frame/csp/ContentSecurityPolicy.h"
44 #include "core/html/HTMLMediaSource.h" 44 #include "core/html/HTMLMediaSource.h"
45 #include "core/html/HTMLSourceElement.h" 45 #include "core/html/HTMLSourceElement.h"
46 #include "core/html/HTMLTrackElement.h" 46 #include "core/html/HTMLTrackElement.h"
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 , m_processingPreferenceChange(false) 340 , m_processingPreferenceChange(false)
341 , m_remoteRoutesAvailable(false) 341 , m_remoteRoutesAvailable(false)
342 , m_playingRemotely(false) 342 , m_playingRemotely(false)
343 , m_isFinalizing(false) 343 , m_isFinalizing(false)
344 , m_initialPlayWithoutUserGesture(false) 344 , m_initialPlayWithoutUserGesture(false)
345 , m_autoplayMediaCounted(false) 345 , m_autoplayMediaCounted(false)
346 , m_inOverlayFullscreenVideo(false) 346 , m_inOverlayFullscreenVideo(false)
347 , m_audioTracks(AudioTrackList::create(*this)) 347 , m_audioTracks(AudioTrackList::create(*this))
348 , m_videoTracks(VideoTrackList::create(*this)) 348 , m_videoTracks(VideoTrackList::create(*this))
349 , m_textTracks(nullptr) 349 , m_textTracks(nullptr)
350 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl ement::resolvePlayPromises))
351 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle ment::rejectPlayPromises))
350 , m_audioSourceNode(nullptr) 352 , m_audioSourceNode(nullptr)
351 , m_autoplayHelper(*this) 353 , m_autoplayHelper(*this)
352 { 354 {
353 #if ENABLE(OILPAN) 355 #if ENABLE(OILPAN)
354 ThreadState::current()->registerPreFinalizer(this); 356 ThreadState::current()->registerPreFinalizer(this);
355 #endif 357 #endif
356 ASSERT(RuntimeEnabledFeatures::mediaEnabled()); 358 ASSERT(RuntimeEnabledFeatures::mediaEnabled());
357 359
358 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); 360 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this);
359 361
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 m_displayMode = Unknown; 736 m_displayMode = Unknown;
735 737
736 // 1 - Abort any already-running instance of the resource selection algorith m for this element. 738 // 1 - Abort any already-running instance of the resource selection algorith m for this element.
737 m_loadState = WaitingForSource; 739 m_loadState = WaitingForSource;
738 m_currentSourceNode = nullptr; 740 m_currentSourceNode = nullptr;
739 741
740 // 2 - If there are any tasks from the media element's media element event t ask source in 742 // 2 - If there are any tasks from the media element's media element event t ask source in
741 // one of the task queues, then remove those tasks. 743 // one of the task queues, then remove those tasks.
742 cancelPendingEventsAndCallbacks(); 744 cancelPendingEventsAndCallbacks();
743 745
746 rejectPlayPromises(AbortError, "The play() request was interrupted by a new load request.");
747
744 // 3 - If the media element's networkState is set to NETWORK_LOADING or NETW ORK_IDLE, queue 748 // 3 - If the media element's networkState is set to NETWORK_LOADING or NETW ORK_IDLE, queue
745 // a task to fire a simple event named abort at the media element. 749 // a task to fire a simple event named abort at the media element.
746 if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) 750 if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE)
747 scheduleEvent(EventTypeNames::abort); 751 scheduleEvent(EventTypeNames::abort);
748 752
749 resetMediaPlayerAndMediaSource(); 753 resetMediaPlayerAndMediaSource();
750 754
751 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps 755 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps
752 if (m_networkState != NETWORK_EMPTY) { 756 if (m_networkState != NETWORK_EMPTY) {
753 // 4.1 - Queue a task to fire a simple event named emptied at the media element. 757 // 4.1 - Queue a task to fire a simple event named emptied at the media element.
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
1246 } 1250 }
1247 1251
1248 void HTMLMediaElement::noneSupported() 1252 void HTMLMediaElement::noneSupported()
1249 { 1253 {
1250 WTF_LOG(Media, "HTMLMediaElement::noneSupported(%p)", this); 1254 WTF_LOG(Media, "HTMLMediaElement::noneSupported(%p)", this);
1251 1255
1252 stopPeriodicTimers(); 1256 stopPeriodicTimers();
1253 m_loadState = WaitingForSource; 1257 m_loadState = WaitingForSource;
1254 m_currentSourceNode = nullptr; 1258 m_currentSourceNode = nullptr;
1255 1259
1256 // 4.8.10.5 1260 // 4.8.13.5
1257 // 6 - Reaching this step indicates that the media resource failed to load o r that the given 1261 // The dedicated media source failure steps are the following steps:
1258 // URL could not be resolved. In one atomic operation, run the following ste ps:
1259 1262
1260 // 6.1 - Set the error attribute to a new MediaError object whose code attri bute is set to 1263 // 1 - Set the error attribute to a new MediaError object whose code attribu te is set to
1261 // MEDIA_ERR_SRC_NOT_SUPPORTED. 1264 // MEDIA_ERR_SRC_NOT_SUPPORTED.
1262 m_error = MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED); 1265 m_error = MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
1263 1266
1264 // 6.2 - Forget the media element's media-resource-specific text tracks. 1267 // 2 - Forget the media element's media-resource-specific text tracks.
1265 forgetResourceSpecificTracks(); 1268 forgetResourceSpecificTracks();
1266 1269
1267 // 6.3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE v alue. 1270 // 3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE val ue.
1268 setNetworkState(NETWORK_NO_SOURCE); 1271 setNetworkState(NETWORK_NO_SOURCE);
1269 1272
1270 // 7 - Queue a task to fire a simple event named error at the media element. 1273 // 4 - Set the element's show poster flag to true.
1274 updateDisplayState();
1275
1276 // 5 - Fire a simple event named error at the media element.
1271 scheduleEvent(EventTypeNames::error); 1277 scheduleEvent(EventTypeNames::error);
1272 1278
1279 // 6 - Reject pending play promises with NotSupportedError.
1280 scheduleRejectPlayPromises(NotSupportedError);
1281
1273 closeMediaSource(); 1282 closeMediaSource();
1274 1283
1275 // 8 - Set the element's delaying-the-load-event flag to false. This stops d elaying the load event. 1284 // 7 - Set the element's delaying-the-load-event flag to false. This stops d elaying the load event.
1276 setShouldDelayLoadEvent(false); 1285 setShouldDelayLoadEvent(false);
1277 1286
1278 // 9 - Abort these steps. Until the load() method is invoked or the src attr ibute is changed,
1279 // the element won't attempt to load another resource.
1280
1281 updateDisplayState();
1282
1283 if (layoutObject()) 1287 if (layoutObject())
1284 layoutObject()->updateFromElement(); 1288 layoutObject()->updateFromElement();
1285 } 1289 }
1286 1290
1287 void HTMLMediaElement::mediaEngineError(MediaError* err) 1291 void HTMLMediaElement::mediaEngineError(MediaError* err)
1288 { 1292 {
1289 ASSERT(m_readyState >= HAVE_METADATA); 1293 ASSERT(m_readyState >= HAVE_METADATA);
1290 WTF_LOG(Media, "HTMLMediaElement::mediaEngineError(%p, %d)", this, static_ca st<int>(err->code())); 1294 WTF_LOG(Media, "HTMLMediaElement::mediaEngineError(%p, %d)", this, static_ca st<int>(err->code()));
1291 1295
1292 // 1 - The user agent should cancel the fetching process. 1296 // 1 - The user agent should cancel the fetching process.
(...skipping 17 matching lines...) Expand all
1310 m_currentSourceNode = nullptr; 1314 m_currentSourceNode = nullptr;
1311 } 1315 }
1312 1316
1313 void HTMLMediaElement::cancelPendingEventsAndCallbacks() 1317 void HTMLMediaElement::cancelPendingEventsAndCallbacks()
1314 { 1318 {
1315 WTF_LOG(Media, "HTMLMediaElement::cancelPendingEventsAndCallbacks(%p)", this ); 1319 WTF_LOG(Media, "HTMLMediaElement::cancelPendingEventsAndCallbacks(%p)", this );
1316 m_asyncEventQueue->cancelAllEvents(); 1320 m_asyncEventQueue->cancelAllEvents();
1317 1321
1318 for (HTMLSourceElement* source = Traversal<HTMLSourceElement>::firstChild(*t his); source; source = Traversal<HTMLSourceElement>::nextSibling(*source)) 1322 for (HTMLSourceElement* source = Traversal<HTMLSourceElement>::firstChild(*t his); source; source = Traversal<HTMLSourceElement>::nextSibling(*source))
1319 source->cancelPendingErrorEvent(); 1323 source->cancelPendingErrorEvent();
1324
1325 m_playPromiseResolveTask->cancel();
1326 m_playPromiseRejectTask->cancel();
1320 } 1327 }
1321 1328
1322 void HTMLMediaElement::networkStateChanged() 1329 void HTMLMediaElement::networkStateChanged()
1323 { 1330 {
1324 setNetworkState(webMediaPlayer()->networkState()); 1331 setNetworkState(webMediaPlayer()->networkState());
1325 } 1332 }
1326 1333
1327 void HTMLMediaElement::mediaLoadingFailed(WebMediaPlayer::NetworkState error) 1334 void HTMLMediaElement::mediaLoadingFailed(WebMediaPlayer::NetworkState error)
1328 { 1335 {
1329 stopPeriodicTimers(); 1336 stopPeriodicTimers();
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1521 m_haveFiredLoadedData = true; 1528 m_haveFiredLoadedData = true;
1522 shouldUpdateDisplayState = true; 1529 shouldUpdateDisplayState = true;
1523 scheduleEvent(EventTypeNames::loadeddata); 1530 scheduleEvent(EventTypeNames::loadeddata);
1524 setShouldDelayLoadEvent(false); 1531 setShouldDelayLoadEvent(false);
1525 } 1532 }
1526 1533
1527 bool isPotentiallyPlaying = potentiallyPlaying(); 1534 bool isPotentiallyPlaying = potentiallyPlaying();
1528 if (m_readyState == HAVE_FUTURE_DATA && oldState <= HAVE_CURRENT_DATA && tra cksAreReady) { 1535 if (m_readyState == HAVE_FUTURE_DATA && oldState <= HAVE_CURRENT_DATA && tra cksAreReady) {
1529 scheduleEvent(EventTypeNames::canplay); 1536 scheduleEvent(EventTypeNames::canplay);
1530 if (isPotentiallyPlaying) 1537 if (isPotentiallyPlaying)
1531 scheduleEvent(EventTypeNames::playing); 1538 scheduleNotifyPlaying();
1532 shouldUpdateDisplayState = true; 1539 shouldUpdateDisplayState = true;
1533 } 1540 }
1534 1541
1535 if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && track sAreReady) { 1542 if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && track sAreReady) {
1536 if (oldState <= HAVE_CURRENT_DATA) { 1543 if (oldState <= HAVE_CURRENT_DATA) {
1537 scheduleEvent(EventTypeNames::canplay); 1544 scheduleEvent(EventTypeNames::canplay);
1538 if (isPotentiallyPlaying) 1545 if (isPotentiallyPlaying)
1539 scheduleEvent(EventTypeNames::playing); 1546 scheduleNotifyPlaying();
1540 } 1547 }
1541 1548
1542 // Check for autoplay, and record metrics about it if needed. 1549 // Check for autoplay, and record metrics about it if needed.
1543 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { 1550 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) {
1544 // If the autoplay experiment says that it's okay to play now, 1551 // If the autoplay experiment says that it's okay to play now,
1545 // then don't require a user gesture. 1552 // then don't require a user gesture.
1546 m_autoplayHelper.becameReadyToPlay(); 1553 m_autoplayHelper.becameReadyToPlay();
1547 1554
1548 if (!m_userGestureRequiredForPlay) { 1555 if (!m_userGestureRequiredForPlay) {
1549 m_paused = false; 1556 m_paused = false;
1550 invalidateCachedTime(); 1557 invalidateCachedTime();
1551 scheduleEvent(EventTypeNames::play); 1558 scheduleEvent(EventTypeNames::play);
1552 scheduleEvent(EventTypeNames::playing); 1559 scheduleNotifyPlaying();
1553 m_autoplaying = false; 1560 m_autoplaying = false;
1554 } 1561 }
1555 } 1562 }
1556 1563
1557 scheduleEvent(EventTypeNames::canplaythrough); 1564 scheduleEvent(EventTypeNames::canplaythrough);
1558 1565
1559 shouldUpdateDisplayState = true; 1566 shouldUpdateDisplayState = true;
1560 } 1567 }
1561 1568
1562 if (shouldUpdateDisplayState) { 1569 if (shouldUpdateDisplayState) {
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
1934 // https://crbug.com/310450 1941 // https://crbug.com/310450
1935 UseCounter::count(document(), UseCounter::HTMLMediaElementPreloadDefault); 1942 UseCounter::count(document(), UseCounter::HTMLMediaElementPreloadDefault);
1936 return WebMediaPlayer::PreloadAuto; 1943 return WebMediaPlayer::PreloadAuto;
1937 } 1944 }
1938 1945
1939 WebMediaPlayer::Preload HTMLMediaElement::effectivePreloadType() const 1946 WebMediaPlayer::Preload HTMLMediaElement::effectivePreloadType() const
1940 { 1947 {
1941 return autoplay() ? WebMediaPlayer::PreloadAuto : preloadType(); 1948 return autoplay() ? WebMediaPlayer::PreloadAuto : preloadType();
1942 } 1949 }
1943 1950
1944 void HTMLMediaElement::play() 1951 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* scriptState)
1952 {
1953 Nullable<ExceptionCode> code = play();
1954 if (!code.isNull()) {
1955 String message;
1956 switch (code.get()) {
1957 case NotAllowedError:
1958 message = "play() can only be initiated by a user gesture.";
1959 break;
1960 case NotSupportedError:
1961 message = "The element has no supported sources.";
1962 break;
1963 default:
1964 ASSERT_NOT_REACHED();
1965 }
1966 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(code.get(), message));
1967 }
1968
1969 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
1970 ScriptPromise promise = resolver->promise();
1971
1972 m_playResolvers.append(resolver);
1973 return promise;
1974 }
1975
1976 Nullable<ExceptionCode> HTMLMediaElement::play()
1945 { 1977 {
1946 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); 1978 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this);
1947 1979
1948 m_autoplayHelper.playMethodCalled(); 1980 m_autoplayHelper.playMethodCalled();
1949 1981
1950 if (!UserGestureIndicator::processingUserGesture()) { 1982 if (!UserGestureIndicator::processingUserGesture()) {
1951 autoplayMediaEncountered(); 1983 autoplayMediaEncountered();
1952 1984
1953 if (m_userGestureRequiredForPlay) { 1985 if (m_userGestureRequiredForPlay) {
1954 recordAutoplayMetric(PlayMethodFailed); 1986 recordAutoplayMetric(PlayMethodFailed);
1955 String message = ExceptionMessages::failedToExecute("play", "HTMLMed iaElement", "API can only be initiated by a user gesture."); 1987 String message = ExceptionMessages::failedToExecute("play", "HTMLMed iaElement", "API can only be initiated by a user gesture.");
1956 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); 1988 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message));
1957 return; 1989 return NotAllowedError;
1958 } 1990 }
1959 } else if (m_userGestureRequiredForPlay) { 1991 } else if (m_userGestureRequiredForPlay) {
1960 if (m_autoplayMediaCounted) 1992 if (m_autoplayMediaCounted)
1961 recordAutoplayMetric(AutoplayManualStart); 1993 recordAutoplayMetric(AutoplayManualStart);
1962 m_userGestureRequiredForPlay = false; 1994 m_userGestureRequiredForPlay = false;
1963 } 1995 }
1964 1996
1997 if (m_error && m_error->code() == MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED)
1998 return NotSupportedError;
1999
1965 playInternal(); 2000 playInternal();
2001
2002 return nullptr;
1966 } 2003 }
1967 2004
1968 void HTMLMediaElement::playInternal() 2005 void HTMLMediaElement::playInternal()
1969 { 2006 {
1970 WTF_LOG(Media, "HTMLMediaElement::playInternal(%p)", this); 2007 WTF_LOG(Media, "HTMLMediaElement::playInternal(%p)", this);
1971 2008
1972 // Always return the buffering strategy to normal when not paused, 2009 // Always return the buffering strategy to normal when not paused,
1973 // regardless of the cause. (In contrast with aggressive buffering which is 2010 // regardless of the cause. (In contrast with aggressive buffering which is
1974 // only enabled by pause(), not pauseInternal().) 2011 // only enabled by pause(), not pauseInternal().)
1975 if (webMediaPlayer()) 2012 if (webMediaPlayer())
(...skipping 10 matching lines...) Expand all
1986 seek(0); 2023 seek(0);
1987 2024
1988 if (m_paused) { 2025 if (m_paused) {
1989 m_paused = false; 2026 m_paused = false;
1990 invalidateCachedTime(); 2027 invalidateCachedTime();
1991 scheduleEvent(EventTypeNames::play); 2028 scheduleEvent(EventTypeNames::play);
1992 2029
1993 if (m_readyState <= HAVE_CURRENT_DATA) 2030 if (m_readyState <= HAVE_CURRENT_DATA)
1994 scheduleEvent(EventTypeNames::waiting); 2031 scheduleEvent(EventTypeNames::waiting);
1995 else if (m_readyState >= HAVE_FUTURE_DATA) 2032 else if (m_readyState >= HAVE_FUTURE_DATA)
1996 scheduleEvent(EventTypeNames::playing); 2033 scheduleNotifyPlaying();
2034 } else if (m_readyState >= HAVE_FUTURE_DATA) {
2035 scheduleResolvePlayPromises();
1997 } 2036 }
2037
1998 m_autoplaying = false; 2038 m_autoplaying = false;
1999 2039
2000 updatePlayState(); 2040 updatePlayState();
2001 } 2041 }
2002 2042
2003 void HTMLMediaElement::autoplayMediaEncountered() 2043 void HTMLMediaElement::autoplayMediaEncountered()
2004 { 2044 {
2005 if (!m_autoplayMediaCounted) { 2045 if (!m_autoplayMediaCounted) {
2006 m_autoplayMediaCounted = true; 2046 m_autoplayMediaCounted = true;
2007 recordAutoplayMetric(AutoplayMediaFound); 2047 recordAutoplayMetric(AutoplayMediaFound);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2042 m_autoplayHelper.pauseMethodCalled(); 2082 m_autoplayHelper.pauseMethodCalled();
2043 2083
2044 m_autoplaying = false; 2084 m_autoplaying = false;
2045 2085
2046 if (!m_paused) { 2086 if (!m_paused) {
2047 recordMetricsIfPausing(); 2087 recordMetricsIfPausing();
2048 2088
2049 m_paused = true; 2089 m_paused = true;
2050 scheduleTimeupdateEvent(false); 2090 scheduleTimeupdateEvent(false);
2051 scheduleEvent(EventTypeNames::pause); 2091 scheduleEvent(EventTypeNames::pause);
2092 scheduleRejectPlayPromises(AbortError);
2052 } 2093 }
2053 2094
2054 updatePlayState(); 2095 updatePlayState();
2055 } 2096 }
2056 2097
2057 void HTMLMediaElement::requestRemotePlayback() 2098 void HTMLMediaElement::requestRemotePlayback()
2058 { 2099 {
2059 ASSERT(m_remoteRoutesAvailable); 2100 ASSERT(m_remoteRoutesAvailable);
2060 webMediaPlayer()->requestRemotePlayback(); 2101 webMediaPlayer()->requestRemotePlayback();
2061 } 2102 }
(...skipping 1444 matching lines...) Expand 10 before | Expand all | Expand 10 after
3506 visitor->trace(m_asyncEventQueue); 3547 visitor->trace(m_asyncEventQueue);
3507 visitor->trace(m_error); 3548 visitor->trace(m_error);
3508 visitor->trace(m_currentSourceNode); 3549 visitor->trace(m_currentSourceNode);
3509 visitor->trace(m_nextChildNodeToConsider); 3550 visitor->trace(m_nextChildNodeToConsider);
3510 visitor->trace(m_mediaSource); 3551 visitor->trace(m_mediaSource);
3511 visitor->trace(m_audioTracks); 3552 visitor->trace(m_audioTracks);
3512 visitor->trace(m_videoTracks); 3553 visitor->trace(m_videoTracks);
3513 visitor->trace(m_cueTimeline); 3554 visitor->trace(m_cueTimeline);
3514 visitor->trace(m_textTracks); 3555 visitor->trace(m_textTracks);
3515 visitor->trace(m_textTracksWhenResourceSelectionBegan); 3556 visitor->trace(m_textTracksWhenResourceSelectionBegan);
3557 visitor->trace(m_playResolvers);
3516 visitor->trace(m_audioSourceProvider); 3558 visitor->trace(m_audioSourceProvider);
3517 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this); 3559 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this);
3518 visitor->trace(m_autoplayHelper); 3560 visitor->trace(m_autoplayHelper);
3519 HeapSupplementable<HTMLMediaElement>::trace(visitor); 3561 HeapSupplementable<HTMLMediaElement>::trace(visitor);
3520 #endif 3562 #endif
3521 HTMLElement::trace(visitor); 3563 HTMLElement::trace(visitor);
3522 ActiveDOMObject::trace(visitor); 3564 ActiveDOMObject::trace(visitor);
3523 } 3565 }
3524 3566
3525 void HTMLMediaElement::createPlaceholderTracksIfNecessary() 3567 void HTMLMediaElement::createPlaceholderTracksIfNecessary()
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3583 { 3625 {
3584 m_autoplayHelper.updatePositionNotificationRegistration(); 3626 m_autoplayHelper.updatePositionNotificationRegistration();
3585 } 3627 }
3586 3628
3587 // TODO(liberato): remove once autoplay gesture override experiment concludes. 3629 // TODO(liberato): remove once autoplay gesture override experiment concludes.
3588 void HTMLMediaElement::triggerAutoplayViewportCheckForTesting() 3630 void HTMLMediaElement::triggerAutoplayViewportCheckForTesting()
3589 { 3631 {
3590 m_autoplayHelper.triggerAutoplayViewportCheckForTesting(); 3632 m_autoplayHelper.triggerAutoplayViewportCheckForTesting();
3591 } 3633 }
3592 3634
3635 void HTMLMediaElement::scheduleResolvePlayPromises()
3636 {
3637 // Per spec, if there are two tasks in the queue, the first task will remove
3638 // all the pending promises making the second task useless unless a promise
3639 // can be added between the first and second task being run which is not
3640 // possible at the moment.
3641 if (m_playPromiseResolveTask->isPending())
3642 return;
3643
3644 Platform::current()->currentThread()->taskRunner()->postTask(BLINK_FROM_HERE , m_playPromiseResolveTask->cancelAndCreate());
3645 }
3646
3647 void HTMLMediaElement::scheduleRejectPlayPromises(ExceptionCode code)
3648 {
3649 // Per spec, if there are two tasks in the queue, the first task will remove
3650 // all the pending promises making the second task useless unless a promise
3651 // can be added between the first and second task being run which is not
3652 // possible at the moment.
3653 if (m_playPromiseRejectTask->isPending())
3654 return;
3655
3656 // TODO(mlamouri): because cancellable tasks can't take parameters, the
3657 // error code needs to be saved.
3658 m_playPromiseErrorCode = code;
3659 Platform::current()->currentThread()->taskRunner()->postTask(BLINK_FROM_HERE , m_playPromiseRejectTask->cancelAndCreate());
3660 }
3661
3662 void HTMLMediaElement::scheduleNotifyPlaying()
3663 {
3664 scheduleEvent(EventTypeNames::playing);
3665 scheduleResolvePlayPromises();
3666 }
3667
3668 void HTMLMediaElement::resolvePlayPromises()
3669 {
3670 for (auto& resolver: m_playResolvers)
3671 resolver->resolve();
3672
3673 m_playResolvers.clear();
3674 }
3675
3676 void HTMLMediaElement::rejectPlayPromises()
3677 {
3678 // TODO(mlamouri): the message is generated based on the code because
3679 // arguments can't be passed to a cancellable task. In order to save space
3680 // used by the object, the string isn't saved.
3681 ASSERT(m_playPromiseErrorCode == AbortError || m_playPromiseErrorCode == Not SupportedError);
3682 if (m_playPromiseErrorCode == AbortError)
3683 rejectPlayPromises(AbortError, "The play() request was interrupted by a call to pause().");
3684 else
3685 rejectPlayPromises(NotSupportedError, "Failed to load because no support ed source was found.");
3686 }
3687
3688 void HTMLMediaElement::rejectPlayPromises(ExceptionCode code, const String& mess age)
3689 {
3690 ASSERT(code == AbortError || code == NotSupportedError);
3691
3692 for (auto& resolver: m_playResolvers)
3693 resolver->reject(DOMException::create(code, message));
3694
3695 m_playResolvers.clear();
3696 }
3697
3593 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) 3698 void HTMLMediaElement::clearWeakMembers(Visitor* visitor)
3594 { 3699 {
3595 if (!Heap::isHeapObjectAlive(m_audioSourceNode)) 3700 if (!Heap::isHeapObjectAlive(m_audioSourceNode))
3596 audioSourceProvider().setClient(nullptr); 3701 audioSourceProvider().setClient(nullptr);
3597 } 3702 }
3598 3703
3599 void HTMLMediaElement::AudioSourceProviderImpl::wrap(WebAudioSourceProvider* pro vider) 3704 void HTMLMediaElement::AudioSourceProviderImpl::wrap(WebAudioSourceProvider* pro vider)
3600 { 3705 {
3601 MutexLocker locker(provideInputLock); 3706 MutexLocker locker(provideInputLock);
3602 3707
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3650 { 3755 {
3651 visitor->trace(m_client); 3756 visitor->trace(m_client);
3652 } 3757 }
3653 3758
3654 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) 3759 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl)
3655 { 3760 {
3656 visitor->trace(m_client); 3761 visitor->trace(m_client);
3657 } 3762 }
3658 3763
3659 } // namespace blink 3764 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLMediaElement.h ('k') | third_party/WebKit/Source/core/html/HTMLMediaElement.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698