Index: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp |
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp |
index 5889a8f795c07f25f1ac9d8627c0aa344c51fb03..312ceb00823994ecd82918149fc04cf0795e84cd 100644 |
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp |
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp |
@@ -27,6 +27,7 @@ |
#include "bindings/core/v8/ExceptionState.h" |
#include "bindings/core/v8/ExceptionStatePlaceholder.h" |
+#include "bindings/core/v8/Microtask.h" |
#include "bindings/core/v8/ScriptController.h" |
#include "bindings/core/v8/ScriptEventListener.h" |
#include "bindings/core/v8/ScriptPromiseResolver.h" |
@@ -388,7 +389,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum |
: HTMLElement(tagName, document) |
, ActiveScriptWrappable(this) |
, ActiveDOMObject(&document) |
- , m_loadTimer(this, &HTMLMediaElement::loadTimerFired) |
+ , m_textTrackLoadTimer(this, &HTMLMediaElement::textTrackLoadTimerFired) |
, m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired) |
, m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFired) |
, m_audioTracksTimer(this, &HTMLMediaElement::audioTracksTimerFired) |
@@ -413,7 +414,6 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum |
, m_displayMode(Unknown) |
, m_cachedTime(std::numeric_limits<double>::quiet_NaN()) |
, m_fragmentEndTime(std::numeric_limits<double>::quiet_NaN()) |
- , m_pendingActionFlags(0) |
, m_lockedPendingUserGesture(false) |
, m_playing(false) |
, m_shouldDelayLoadEvent(false) |
@@ -436,6 +436,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum |
, m_textTracks(nullptr) |
, m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaElement::resolveScheduledPlayPromises)) |
, m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaElement::rejectScheduledPlayPromises)) |
+ , m_weakTaskFactory(this) |
, m_audioSourceNode(nullptr) |
, m_autoplayHelperClient(AutoplayHelperClientImpl::create(this)) |
, m_autoplayHelper(AutoplayExperimentHelper::create(m_autoplayHelperClient.get())) |
@@ -635,17 +636,8 @@ void HTMLMediaElement::scheduleTextTrackResourceLoad() |
{ |
BLINK_MEDIA_LOG << "scheduleTextTrackResourceLoad(" << (void*)this << ")"; |
- m_pendingActionFlags |= LoadTextTrackResource; |
- |
- if (!m_loadTimer.isActive()) |
- m_loadTimer.startOneShot(0, BLINK_FROM_HERE); |
-} |
- |
-void HTMLMediaElement::scheduleNextSourceChild() |
-{ |
- // Schedule the timer to try the next <source> element WITHOUT resetting state ala invokeLoadAlgorithm. |
- m_pendingActionFlags |= LoadMediaResource; |
- m_loadTimer.startOneShot(0, BLINK_FROM_HERE); |
+ if (!m_textTrackLoadTimer.isActive()) |
+ m_textTrackLoadTimer.startOneShot(0, BLINK_FROM_HERE); |
} |
void HTMLMediaElement::scheduleEvent(const AtomicString& eventName) |
@@ -661,19 +653,10 @@ void HTMLMediaElement::scheduleEvent(Event* event) |
m_asyncEventQueue->enqueueEvent(event); |
} |
-void HTMLMediaElement::loadTimerFired(TimerBase*) |
+void HTMLMediaElement::textTrackLoadTimerFired(TimerBase*) |
{ |
- if (m_pendingActionFlags & LoadTextTrackResource) |
- honorUserPreferencesForAutomaticTextTrackSelection(); |
- |
- if (m_pendingActionFlags & LoadMediaResource) { |
- if (m_loadState == LoadingFromSourceElement) |
- loadNextSourceChild(); |
- else |
- loadInternal(); |
- } |
- |
- m_pendingActionFlags = 0; |
+ BLINK_MEDIA_LOG << "HTMLMediaElement::textTrackLoadTimerFired(" << (void*)this << ")"; |
+ honorUserPreferencesForAutomaticTextTrackSelection(); |
} |
MediaError* HTMLMediaElement::error() const |
@@ -741,15 +724,13 @@ void HTMLMediaElement::invokeLoadAlgorithm() |
// Perform the cleanup required for the resource load algorithm to run. |
stopPeriodicTimers(); |
- m_loadTimer.stop(); |
cancelDeferredLoad(); |
- // FIXME: Figure out appropriate place to reset LoadTextTrackResource if necessary and set m_pendingActionFlags to 0 here. |
- m_pendingActionFlags &= ~LoadMediaResource; |
m_sentStalledEvent = false; |
m_haveFiredLoadedData = false; |
m_displayMode = Unknown; |
// 1 - Abort any already-running instance of the resource selection algorithm for this element. |
+ m_weakTaskFactory.revokeAll(); |
m_loadState = WaitingForSource; |
m_currentSourceNode = nullptr; |
@@ -847,6 +828,12 @@ void HTMLMediaElement::invokeLoadAlgorithm() |
// 10 - Note: Playback of any previously playing media resource for this element stops. |
} |
+void HTMLMediaElement::continueResourceSelectionAlgorithm() |
+{ |
+ BLINK_MEDIA_LOG << "HTMLMediaElement::continueResourceSelectionAlgorithm(" << (void*)this << ")"; |
+ loadInternal(); |
+} |
+ |
void HTMLMediaElement::invokeResourceSelectionAlgorithm() |
{ |
BLINK_MEDIA_LOG << "invokeResourceSelectionAlgorithm(" << (void*)this << ")"; |
@@ -870,9 +857,7 @@ void HTMLMediaElement::invokeResourceSelectionAlgorithm() |
mediaControls()->reset(); |
// 4 - Await a stable state, allowing the task that invoked this algorithm to continue |
- // TODO(srirama.m): Remove scheduleNextSourceChild() and post a microtask instead. |
- // See http://crbug.com/593289 for more details. |
- scheduleNextSourceChild(); |
+ Microtask::enqueueMicrotask(WTF::bind(&HTMLMediaElement::continueResourceSelectionAlgorithm, m_weakTaskFactory.createWeakPtr())); |
} |
void HTMLMediaElement::loadInternal() |
@@ -1002,6 +987,13 @@ void HTMLMediaElement::loadNextSourceChild() |
loadResource(WebMediaPlayerSource(WebURL(mediaURL)), contentType); |
} |
+void HTMLMediaElement::loadNextSourceChildAfterError() |
+{ |
+ // 9.Otherwise.11 - Forget the media element's media-resource-specific tracks. |
+ forgetResourceSpecificTracks(); |
+ loadNextSourceChild(); |
+} |
+ |
void HTMLMediaElement::loadResource(const WebMediaPlayerSource& source, const ContentType& contentType) |
{ |
DCHECK(isMainThread()); |
@@ -1440,13 +1432,9 @@ void HTMLMediaElement::mediaLoadingFailed(WebMediaPlayer::NetworkState error) |
BLINK_MEDIA_LOG << "setNetworkState(" << (void*)this << ") - error event not sent, <source> was removed"; |
// 9.Otherwise.10 - Asynchronously await a stable state. The synchronous section consists of all the remaining steps of this algorithm until the algorithm says the synchronous section has ended. |
- |
- // 9.Otherwise.11 - Forget the media element's media-resource-specific tracks. |
- forgetResourceSpecificTracks(); |
- |
if (havePotentialSourceChild()) { |
BLINK_MEDIA_LOG << "setNetworkState(" << (void*)this << ") - scheduling next <source>"; |
- scheduleNextSourceChild(); |
+ Microtask::enqueueMicrotask(WTF::bind(&HTMLMediaElement::loadNextSourceChildAfterError, m_weakTaskFactory.createWeakPtr())); |
} else { |
BLINK_MEDIA_LOG << "setNetworkState(" << (void*)this << ") - no more <source> elements, waiting"; |
waitForSourceChange(); |
@@ -2860,7 +2848,7 @@ void HTMLMediaElement::sourceWasAdded(HTMLSourceElement* source) |
// 25. Jump back to the find next candidate step above. |
m_nextChildNodeToConsider = source; |
- scheduleNextSourceChild(); |
+ loadNextSourceChild(); |
} |
void HTMLMediaElement::sourceWasRemoved(HTMLSourceElement* source) |
@@ -3208,9 +3196,8 @@ void HTMLMediaElement::clearMediaPlayer() |
} |
stopPeriodicTimers(); |
- m_loadTimer.stop(); |
+ m_textTrackLoadTimer.stop(); |
- m_pendingActionFlags = 0; |
m_loadState = WaitingForSource; |
// We can't cast if we don't have a media player. |