Bug 1625615 - part2 : suspend or resume media element according to docShell's SuspendMediaWhenInactive r=bryce
If docShell's `SuspendMediaWhenInactive` is true, then we should suspend or resume the media element according to the docshell active state when the docshell changes it active state. Differential Revision: https://phabricator.services.mozilla.com/D69671
This commit is contained in:
@@ -4304,7 +4304,7 @@ void HTMLMediaElement::PlayInternal(bool aHandlingUserInput) {
|
|||||||
if (mDecoder->IsEnded()) {
|
if (mDecoder->IsEnded()) {
|
||||||
SetCurrentTime(0);
|
SetCurrentTime(0);
|
||||||
}
|
}
|
||||||
if (!mSuspendedForInactiveDocument) {
|
if (!mSuspendedByInactiveDocOrDocshell) {
|
||||||
mDecoder->Play();
|
mDecoder->Play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5048,13 +5048,13 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder) {
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSuspendedForInactiveDocument) {
|
if (mSuspendedByInactiveDocOrDocshell) {
|
||||||
mDecoder->Suspend();
|
mDecoder->Suspend();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mPaused) {
|
if (!mPaused) {
|
||||||
SetPlayedOrSeeked(true);
|
SetPlayedOrSeeked(true);
|
||||||
if (!mSuspendedForInactiveDocument) {
|
if (!mSuspendedByInactiveDocOrDocshell) {
|
||||||
mDecoder->Play();
|
mDecoder->Play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5070,7 +5070,7 @@ void HTMLMediaElement::UpdateSrcMediaStreamPlaying(uint32_t aFlags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool shouldPlay = !(aFlags & REMOVING_SRC_STREAM) && !mPaused &&
|
bool shouldPlay = !(aFlags & REMOVING_SRC_STREAM) && !mPaused &&
|
||||||
!mSuspendedForInactiveDocument;
|
!mSuspendedByInactiveDocOrDocshell;
|
||||||
if (shouldPlay == mSrcStreamIsPlaying) {
|
if (shouldPlay == mSrcStreamIsPlaying) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -5944,7 +5944,7 @@ void HTMLMediaElement::ChangeReadyState(nsMediaReadyState aState) {
|
|||||||
if (oldState < HAVE_FUTURE_DATA && mReadyState >= HAVE_FUTURE_DATA) {
|
if (oldState < HAVE_FUTURE_DATA && mReadyState >= HAVE_FUTURE_DATA) {
|
||||||
DispatchAsyncEvent(NS_LITERAL_STRING("canplay"));
|
DispatchAsyncEvent(NS_LITERAL_STRING("canplay"));
|
||||||
if (!mPaused) {
|
if (!mPaused) {
|
||||||
if (mDecoder && !mSuspendedForInactiveDocument) {
|
if (mDecoder && !mSuspendedByInactiveDocOrDocshell) {
|
||||||
MOZ_ASSERT(AutoplayPolicy::IsAllowedToPlay(*this));
|
MOZ_ASSERT(AutoplayPolicy::IsAllowedToPlay(*this));
|
||||||
mDecoder->Play();
|
mDecoder->Play();
|
||||||
}
|
}
|
||||||
@@ -6019,7 +6019,7 @@ bool HTMLMediaElement::CanActivateAutoplay() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSuspendedForInactiveDocument) {
|
if (mSuspendedByInactiveDocOrDocshell) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6063,7 +6063,7 @@ void HTMLMediaElement::CheckAutoplayDataReady() {
|
|||||||
if (mCurrentPlayRangeStart == -1.0) {
|
if (mCurrentPlayRangeStart == -1.0) {
|
||||||
mCurrentPlayRangeStart = CurrentTime();
|
mCurrentPlayRangeStart = CurrentTime();
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(!mSuspendedForInactiveDocument);
|
MOZ_ASSERT(!mSuspendedByInactiveDocOrDocshell);
|
||||||
mDecoder->Play();
|
mDecoder->Play();
|
||||||
} else if (mSrcStream) {
|
} else if (mSrcStream) {
|
||||||
SetPlayedOrSeeked(true);
|
SetPlayedOrSeeked(true);
|
||||||
@@ -6362,11 +6362,11 @@ void HTMLMediaElement::UpdateMediaSize(const nsIntSize& aSize) {
|
|||||||
void HTMLMediaElement::SuspendOrResumeElement(bool aSuspendElement) {
|
void HTMLMediaElement::SuspendOrResumeElement(bool aSuspendElement) {
|
||||||
LOG(LogLevel::Debug, ("%p SuspendOrResumeElement(suspend=%d) hidden=%d", this,
|
LOG(LogLevel::Debug, ("%p SuspendOrResumeElement(suspend=%d) hidden=%d", this,
|
||||||
aSuspendElement, OwnerDoc()->Hidden()));
|
aSuspendElement, OwnerDoc()->Hidden()));
|
||||||
if (aSuspendElement == mSuspendedForInactiveDocument) {
|
if (aSuspendElement == mSuspendedByInactiveDocOrDocshell) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mSuspendedForInactiveDocument = aSuspendElement;
|
mSuspendedByInactiveDocOrDocshell = aSuspendElement;
|
||||||
UpdateSrcMediaStreamPlaying();
|
UpdateSrcMediaStreamPlaying();
|
||||||
UpdateAudioChannelPlayingState();
|
UpdateAudioChannelPlayingState();
|
||||||
|
|
||||||
@@ -6432,6 +6432,16 @@ bool HTMLMediaElement::IsBeingDestroyed() {
|
|||||||
return isBeingDestroyed;
|
return isBeingDestroyed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HTMLMediaElement::ShouldBeSuspendedByInactiveDocShell() const {
|
||||||
|
nsIDocShell* docShell = OwnerDoc()->GetDocShell();
|
||||||
|
if (!docShell) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool isDocShellActive = false;
|
||||||
|
docShell->GetIsActive(&isDocShellActive);
|
||||||
|
return !isDocShellActive && docShell->GetSuspendMediaWhenInactive();
|
||||||
|
}
|
||||||
|
|
||||||
void HTMLMediaElement::NotifyOwnerDocumentActivityChanged() {
|
void HTMLMediaElement::NotifyOwnerDocumentActivityChanged() {
|
||||||
bool visible = !IsHidden();
|
bool visible = !IsHidden();
|
||||||
if (visible) {
|
if (visible) {
|
||||||
@@ -6446,7 +6456,11 @@ void HTMLMediaElement::NotifyOwnerDocumentActivityChanged() {
|
|||||||
NotifyDecoderActivityChanges();
|
NotifyDecoderActivityChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
SuspendOrResumeElement(!IsActive());
|
// We would suspend media when the document is inactive, or its docshell has
|
||||||
|
// been set to hidden and explicitly wants to suspend media. In those cases,
|
||||||
|
// the media would be not visible and we don't want them to continue playing.
|
||||||
|
bool shouldSuspend = !IsActive() || ShouldBeSuspendedByInactiveDocShell();
|
||||||
|
SuspendOrResumeElement(shouldSuspend);
|
||||||
|
|
||||||
// If the owning document has become inactive we should shutdown the CDM.
|
// If the owning document has become inactive we should shutdown the CDM.
|
||||||
if (!OwnerDoc()->IsCurrentActiveDocument() && mMediaKeys) {
|
if (!OwnerDoc()->IsCurrentActiveDocument() && mMediaKeys) {
|
||||||
|
|||||||
@@ -1625,10 +1625,11 @@ class HTMLMediaElement : public nsGenericHTMLElement,
|
|||||||
// to raise the 'waiting' event as per 4.7.1.8 in HTML 5 specification.
|
// to raise the 'waiting' event as per 4.7.1.8 in HTML 5 specification.
|
||||||
bool mPlayingBeforeSeek = false;
|
bool mPlayingBeforeSeek = false;
|
||||||
|
|
||||||
// True if this element is suspended because the document is inactive.
|
// True if this element is suspended because the document is inactive or the
|
||||||
bool mSuspendedForInactiveDocument = false;
|
// inactive docshell is not allowing media to play.
|
||||||
|
bool mSuspendedByInactiveDocOrDocshell = false;
|
||||||
|
|
||||||
// True if event delivery is suspended (mSuspendedForInactiveDocument
|
// True if event delivery is suspended (mSuspendedByInactiveDocOrDocshell
|
||||||
// must also be true).
|
// must also be true).
|
||||||
bool mEventDeliveryPaused = false;
|
bool mEventDeliveryPaused = false;
|
||||||
|
|
||||||
@@ -1898,6 +1899,10 @@ class HTMLMediaElement : public nsGenericHTMLElement,
|
|||||||
// AsyncRejectSeekDOMPromiseIfExists() methods.
|
// AsyncRejectSeekDOMPromiseIfExists() methods.
|
||||||
RefPtr<dom::Promise> mSeekDOMPromise;
|
RefPtr<dom::Promise> mSeekDOMPromise;
|
||||||
|
|
||||||
|
// Return true if the docshell is inactive and explicitly wants to stop media
|
||||||
|
// playing in that shell.
|
||||||
|
bool ShouldBeSuspendedByInactiveDocShell() const;
|
||||||
|
|
||||||
// For debugging bug 1407148.
|
// For debugging bug 1407148.
|
||||||
void AssertReadyStateIsNothing();
|
void AssertReadyStateIsNothing();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user