Bug 1420488 - part1 : bless media if media has started playing before.
If the media has started playing before, bless it and it would always be allowed
to autoplay.
MozReview-Commit-ID: 4GqMARLXULU
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -1974,22 +1974,22 @@ void HTMLMediaElement::DoLoad()
LOG(LogLevel::Debug, ("%p Media not allowed", this));
return;
}
if (mIsRunningLoadMethod) {
return;
}
- // Detect if user has interacted with element so that play will not be
- // blocked when initiated by a script. This enables sites to capture user
- // intent to play by calling load() in the click handler of a "catalog
- // view" of a gallery of videos.
if (EventStateManager::IsHandlingUserInput()) {
- mHasUserInteractedLoadOrSeek = true;
+ // Detect if user has interacted with element so that play will not be
+ // blocked when initiated by a script. This enables sites to capture user
+ // intent to play by calling load() in the click handler of a "catalog
+ // view" of a gallery of videos.
+ mIsBlessed = true;
// Mark the channel as urgent-start when autopaly so that it will play the
// media from src after loading enough resource.
if (HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay)) {
mUseUrgentStartForChannel = true;
}
}
SetPlayedOrSeeked(false);
@@ -2752,17 +2752,17 @@ HTMLMediaElement::Seek(double aTime,
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
// Detect if user has interacted with element by seeking so that
// play will not be blocked when initiated by a script.
if (EventStateManager::IsHandlingUserInput()) {
- mHasUserInteractedLoadOrSeek = true;
+ mIsBlessed = true;
}
StopSuspendingAfterFirstFrame();
if (mSrcStream) {
// do nothing since media streams have an empty Seekable range.
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return promise.forget();
@@ -4038,17 +4038,16 @@ HTMLMediaElement::HTMLMediaElement(alrea
mShuttingDown(false),
mSuspendedForPreloadNone(false),
mSrcStreamIsPlaying(false),
mMediaSecurityVerified(false),
mCORSMode(CORS_NONE),
mIsEncrypted(false),
mWaitingForKey(NOT_WAITING_FOR_KEY),
mDisableVideo(false),
- mHasUserInteractedLoadOrSeek(false),
mFirstFrameLoaded(false),
mDefaultPlaybackStartPosition(0.0),
mHasSuspendTaint(false),
mMediaTracksConstructed(false),
mVisibilityState(Visibility::UNTRACKED),
mErrorSink(new ErrorSink(this)),
mAudioChannelWrapper(new AudioChannelAgentCallback(this))
{
@@ -4281,16 +4280,19 @@ HTMLMediaElement::PlayInternal(ErrorResu
mAutoplaying = false;
// We changed mPaused and mAutoplaying which can affect AddRemoveSelfReference
// and our preload status.
AddRemoveSelfReference();
UpdatePreloadAction();
UpdateSrcMediaStreamPlaying();
+ // once media start playing, we would always allow it to autoplay
+ mIsBlessed = true;
+
// TODO: If the playback has ended, then the user agent must set
// seek to the effective start.
// 4.8.12.8 - Step 6:
// If the media element's paused attribute is true, run the following steps:
if (oldPaused) {
// 6.1. Change the value of paused to false. (Already done.)
// This step is uplifted because the "block-media-playback" feature needs
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -736,21 +736,19 @@ public:
void NotifyCueUpdated(TextTrackCue *aCue) {
if (mTextTrackManager) {
mTextTrackManager->NotifyCueUpdated(aCue);
}
}
void NotifyCueDisplayStatesChanged();
- bool GetAndClearHasUserInteractedLoadOrSeek()
+ bool IsBlessed() const
{
- bool result = mHasUserInteractedLoadOrSeek;
- mHasUserInteractedLoadOrSeek = false;
- return result;
+ return mIsBlessed;
}
// A method to check whether we are currently playing.
bool IsCurrentlyPlaying() const;
// Returns true if the media element is being destroyed. Used in
// dormancy checks to prevent dormant processing for an element
// that will soon be gone.
@@ -1780,19 +1778,19 @@ private:
TimeDurationAccumulator mPlayTime;
// Total time a video has spent playing while hidden.
TimeDurationAccumulator mHiddenPlayTime;
// Total time a video has (or would have) spent in video-decode-suspend mode.
TimeDurationAccumulator mVideoDecodeSuspendTime;
- // True if user has called load() or seek() via user input.
+ // True if user has called load(), seek() or element has started playing before.
// It's *only* use for checking autoplay policy
- bool mHasUserInteractedLoadOrSeek;
+ bool mIsBlessed = false;
// True if the first frame has been successfully loaded.
bool mFirstFrameLoaded;
// Media elements also have a default playback start position, which must
// initially be set to zero seconds. This time is used to allow the element to
// be seeked even before the media is loaded.
double mDefaultPlaybackStartPosition;
--- a/dom/media/AutoplayPolicy.cpp
+++ b/dom/media/AutoplayPolicy.cpp
@@ -33,16 +33,15 @@ AutoplayPolicy::IsMediaElementAllowedToP
}
if (Preferences::GetBool("media.autoplay.enabled.user-gestures-needed")) {
return AutoplayPolicy::IsDocumentAllowedToPlay(aElement->OwnerDoc());
}
// TODO : this old way would be removed when user-gestures-needed becomes
// as a default option to block autoplay.
- // If user triggers load() or seek() before play(), we would also allow the
- // following play().
- return aElement->GetAndClearHasUserInteractedLoadOrSeek() ||
+ // If elelement is blessed, it would always be allowed to play().
+ return aElement->IsBlessed() ||
EventStateManager::IsHandlingUserInput();
}
} // namespace dom
} // namespace mozilla
\ No newline at end of file