Modified: trunk/Source/WebCore/ChangeLog (202748 => 202749)
--- trunk/Source/WebCore/ChangeLog 2016-07-01 19:41:30 UTC (rev 202748)
+++ trunk/Source/WebCore/ChangeLog 2016-07-01 20:31:18 UTC (rev 202749)
@@ -1,3 +1,38 @@
+2016-07-01 Eric Carlson <[email protected]>
+
+ HTMLMediaElement::resume() may cause _javascript_ execution
+ https://bugs.webkit.org/show_bug.cgi?id=159327
+ <rdar://problem/27131641>
+
+ Reviewed by Jer Noble.
+
+ HTMLMediaElement::updatePlayState can cause an element to begin playing and enter fullscreen,
+ which can result in a call to the media controls and _javascript_ execution. _javascript_ is not
+ allowed allowed to run when a page resumes, so make the call to updatePlayState asynchronous.
+
+ No new tests, I wasn't able to create a test that triggers the crash.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::scheduleDelayedAction): Support UpdatePlayState.
+ (WebCore::HTMLMediaElement::pendingActionTimerFired): Ditto.
+ (WebCore::HTMLMediaElement::setReadyState): UpdateMediaState -> UpdateState.
+ (WebCore::HTMLMediaElement::playInternal): Don't call updateMediaController, it is called
+ by updatePlayState.
+ (WebCore::HTMLMediaElement::setMuted): UpdateMediaState -> UpdateState.
+ (WebCore::HTMLMediaElement::mediaPlayerTimeChanged): Ditto.
+ (WebCore::HTMLMediaElement::mediaEngineWasUpdated): Update media state asynchronously.
+ (WebCore::HTMLMediaElement::updatePlayState): Add parameter to allow update to happen
+ asynchronously.
+ (WebCore::HTMLMediaElement::setPlaying): UpdateMediaState -> UpdateState.
+ (WebCore::HTMLMediaElement::setPausedInternal): Update media state asynchronously.
+ (WebCore::HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged):
+ UpdateMediaState -> UpdateState.
+ (WebCore::HTMLMediaElement::removeEventListener): Ditto.
+ (WebCore::HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent): Ditto.
+ (WebCore::HTMLMediaElement::updateMediaState): UpdateMediaState -> UpdateState
+ * html/HTMLMediaElement.h:
+ * html/HTMLMediaElementEnums.h: Add UpdatePlayState.
+
2016-07-01 Brady Eidson <[email protected]>
Blob content type not preserved when retrieving blobs from IndexedDB.
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (202748 => 202749)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2016-07-01 19:41:30 UTC (rev 202748)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2016-07-01 20:31:18 UTC (rev 202749)
@@ -892,6 +892,9 @@
if (actionType & MediaEngineUpdated)
setFlags(m_pendingActionFlags, MediaEngineUpdated);
+ if (actionType & UpdatePlayState)
+ setFlags(m_pendingActionFlags, UpdatePlayState);
+
m_pendingActionTimer.startOneShot(0);
}
@@ -979,6 +982,9 @@
if (pendingActions & MediaEngineUpdated)
mediaEngineWasUpdated();
+
+ if (pendingActions & UpdatePlayState)
+ updatePlayState();
}
MediaError* HTMLMediaElement::error() const
@@ -2269,7 +2275,7 @@
logMediaLoadRequest(document().page(), m_player->engineDescription(), String(), true);
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- updateMediaState(UpdateMediaState::Asynchronously);
+ updateMediaState(UpdateState::Asynchronously);
#endif
m_mediaSession->clientCharacteristicsChanged();
@@ -3126,7 +3132,7 @@
m_autoplaying = false;
updatePlayState();
- updateMediaController();
+
return true;
}
@@ -3358,7 +3364,7 @@
#endif
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- updateMediaState(UpdateMediaState::Asynchronously);
+ updateMediaState(UpdateState::Asynchronously);
#endif
}
@@ -4418,7 +4424,7 @@
m_sentEndEvent = false;
}
- updatePlayState();
+ updatePlayState(UpdateState::Asynchronously);
endProcessingMediaPlayerCallback();
}
@@ -4594,7 +4600,7 @@
#endif
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- updateMediaState(UpdateMediaState::Asynchronously);
+ updateMediaState(UpdateState::Asynchronously);
#endif
}
@@ -4828,8 +4834,13 @@
#endif
}
-void HTMLMediaElement::updatePlayState()
+void HTMLMediaElement::updatePlayState(UpdateState updateState)
{
+ if (updateState == UpdateState::Asynchronously) {
+ scheduleDelayedAction(UpdatePlayState);
+ return;
+ }
+
if (!m_player)
return;
@@ -4922,7 +4933,7 @@
#endif
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- updateMediaState(UpdateMediaState::Asynchronously);
+ updateMediaState(UpdateState::Asynchronously);
#endif
}
@@ -4929,7 +4940,7 @@
void HTMLMediaElement::setPausedInternal(bool b)
{
m_pausedInternal = b;
- updatePlayState();
+ updatePlayState(UpdateState::Asynchronously);
}
void HTMLMediaElement::stopPeriodicTimers()
@@ -5221,7 +5232,7 @@
m_mediaSession->isPlayingToWirelessPlaybackTargetChanged(m_isPlayingToWirelessTarget);
if (m_isPlayingToWirelessTarget)
m_mediaSession->setCanProduceAudio(true);
- updateMediaState(UpdateMediaState::Asynchronously);
+ updateMediaState(UpdateState::Asynchronously);
}
bool HTMLMediaElement::dispatchEvent(Event& event)
@@ -5266,7 +5277,7 @@
if (didRemoveLastAvailabilityChangedListener) {
m_hasPlaybackTargetAvailabilityListeners = false;
m_mediaSession->setHasPlaybackTargetAvailabilityListeners(*this, false);
- updateMediaState(UpdateMediaState::Asynchronously);
+ updateMediaState(UpdateState::Asynchronously);
}
return true;
@@ -5279,7 +5290,7 @@
auto event = WebKitPlaybackTargetAvailabilityEvent::create(eventNames().webkitplaybacktargetavailabilitychangedEvent, hasTargets);
event->setTarget(this);
m_asyncEventQueue.enqueueEvent(WTFMove(event));
- updateMediaState(UpdateMediaState::Asynchronously);
+ updateMediaState(UpdateState::Asynchronously);
}
void HTMLMediaElement::setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&& device)
@@ -6844,9 +6855,9 @@
}
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-void HTMLMediaElement::updateMediaState(UpdateMediaState updateState)
+void HTMLMediaElement::updateMediaState(UpdateState updateState)
{
- if (updateState == UpdateMediaState::Asynchronously) {
+ if (updateState == UpdateState::Asynchronously) {
scheduleDelayedAction(CheckMediaState);
return;
}
Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (202748 => 202749)
--- trunk/Source/WebCore/html/HTMLMediaElement.h 2016-07-01 19:41:30 UTC (rev 202748)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h 2016-07-01 20:31:18 UTC (rev 202749)
@@ -690,8 +690,10 @@
void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; }
void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
+ enum class UpdateState { Asynchronously, Synchronously };
+
+ void updatePlayState(UpdateState updateState = UpdateState::Synchronously);
void updateVolume();
- void updatePlayState();
void setPlaying(bool);
bool potentiallyPlaying() const;
bool endedPlayback() const;
@@ -770,8 +772,7 @@
void prepareForDocumentSuspension() final;
void resumeFromDocumentSuspension() final;
- enum class UpdateMediaState { Asynchronously, Synchronously };
- void updateMediaState(UpdateMediaState updateState = UpdateMediaState::Synchronously);
+ void updateMediaState(UpdateState updateState = UpdateState::Synchronously);
bool hasPlaybackTargetAvailabilityListeners() const { return m_hasPlaybackTargetAvailabilityListeners; }
#endif
Modified: trunk/Source/WebCore/html/HTMLMediaElementEnums.h (202748 => 202749)
--- trunk/Source/WebCore/html/HTMLMediaElementEnums.h 2016-07-01 19:41:30 UTC (rev 202748)
+++ trunk/Source/WebCore/html/HTMLMediaElementEnums.h 2016-07-01 20:31:18 UTC (rev 202749)
@@ -42,8 +42,9 @@
CheckPlaybackTargetCompatablity = 1 << 4,
CheckMediaState = 1 << 5,
MediaEngineUpdated = 1 << 6,
+ UpdatePlayState = 1 << 7,
- EveryDelayedAction = LoadMediaResource | ConfigureTextTracks | TextTrackChangesNotification | ConfigureTextTrackDisplay | CheckPlaybackTargetCompatablity | CheckMediaState,
+ EveryDelayedAction = LoadMediaResource | ConfigureTextTracks | TextTrackChangesNotification | ConfigureTextTrackDisplay | CheckPlaybackTargetCompatablity | CheckMediaState | UpdatePlayState,
};
enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTURE_DATA, HAVE_ENOUGH_DATA };