Bug 1244768 part 9 - distinguish the "element is not allowd to play" and "element is blocked" cases; r?jwwang, alwu
Element is not allowd to play means that we cancel play operation and won't resume it.
Element is blocked means that we suspend the play operation and will resume it later.
MozReview-Commit-ID: BMAFGMcOpqu
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -3116,17 +3116,17 @@ HTMLMediaElement::Play(ErrorResult& aRv)
return PlayInternal(aRv);
}
void
HTMLMediaElement::PlayInternal(ErrorResult& aRv)
{
MOZ_ASSERT(!aRv.Failed());
- if (!IsAllowedToPlay()) {
+ if (!IsPlayOperationAllowed()) {
return;
}
// Play was not blocked so assume user interacted with the element.
mHasUserInteraction = true;
StopSuspendingAfterFirstFrame();
SetPlayedOrSeeked(true);
@@ -3152,16 +3152,21 @@ HTMLMediaElement::PlayInternal(ErrorResu
}
}
}
if (mCurrentPlayRangeStart == -1.0) {
mCurrentPlayRangeStart = CurrentTime();
}
+ // Check if the element is now blocked.
+ if (IsPlayOperationBlocked()) {
+ return;
+ }
+
bool oldPaused = mPaused;
mPaused = false;
mAutoplaying = false;
SetAudioChannelSuspended(nsISuspendedTypes::NONE_SUSPENDED);
// We changed mPaused and mAutoplaying which can affect AddRemoveSelfReference
// and our preload status.
AddRemoveSelfReference();
@@ -6085,18 +6090,20 @@ HTMLMediaElement::SetAudioChannelSuspend
bool
HTMLMediaElement::IsSuspendedByAudioChannel() const
{
return (mAudioChannelSuspended == nsISuspendedTypes::SUSPENDED_PAUSE ||
mAudioChannelSuspended == nsISuspendedTypes::SUSPENDED_PAUSE_DISPOSABLE ||
mAudioChannelSuspended == nsISuspendedTypes::SUSPENDED_BLOCK);
}
+// This method enumerates situations that play operation should be canceled
+// directly and won't be resumed later.
bool
-HTMLMediaElement::IsAllowedToPlay()
+HTMLMediaElement::IsPlayOperationAllowed() const
{
// Prevent media element from being auto-started by a script when
// media.autoplay.enabled=false
if (!mHasUserInteraction &&
!IsAutoplayEnabled() &&
!EventStateManager::IsHandlingUserInput() &&
!nsContentUtils::IsCallerChrome()) {
#if defined(MOZ_WIDGET_ANDROID)
@@ -6105,24 +6112,31 @@ HTMLMediaElement::IsAllowedToPlay()
NS_LITERAL_STRING("MozAutoplayMediaBlocked"),
false,
false);
#endif
return false;
}
// The MediaElement can't start playback until it's resumed by audio channel.
- if (mAudioChannelSuspended == nsISuspendedTypes::SUSPENDED_PAUSE ||
- mAudioChannelSuspended == nsISuspendedTypes::SUSPENDED_BLOCK) {
+ if (mAudioChannelSuspended == nsISuspendedTypes::SUSPENDED_PAUSE) {
return false;
}
return true;
}
+// This method enumerates situations that play operation is suspended and will
+// be resumed automatically later.
+bool
+HTMLMediaElement::IsPlayOperationBlocked() const
+{
+ return mAudioChannelSuspended == nsISuspendedTypes::SUSPENDED_BLOCK;
+}
+
#ifdef MOZ_EME
MediaKeys*
HTMLMediaElement::GetMediaKeys() const
{
return mMediaKeys;
}
bool
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -1251,17 +1251,25 @@ protected:
void ResumeFromAudioChannel();
void ResumeFromAudioChannelPaused(SuspendTypes aSuspend);
void ResumeFromAudioChannelBlocked();
bool IsSuspendedByAudioChannel() const;
void SetAudioChannelSuspended(SuspendTypes aSuspend);
- bool IsAllowedToPlay();
+ /*
+ * If IsPlayOperationAllowed() returns false, we cancel the play operation and
+ * won't resume it later.
+ *
+ * If IsPlayOperationBlocked() returns true, we make the play operation
+ * pending for now and will resume it later.
+ */
+ bool IsPlayOperationAllowed() const;
+ bool IsPlayOperationBlocked() const;
bool IsAudible() const;
bool HaveFailedWithSourceNotSupportedError() const;
void OpenUnsupportedMediaWithExtenalAppIfNeeded();
class nsAsyncEventRunner;
class nsNotifyAboutPlayingRunner;