Bug 1321196 part 2 - rework the IsAllowedToPlay policy; r?jwwang, alwu
MozReview-Commit-ID: 8mrXoLRK42y
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -668,36 +668,29 @@ public:
return;
}
mIsOwnerAudible = newAudibleState;
mAudioChannelAgent->NotifyStartedAudible(mIsOwnerAudible, aReason);
}
bool
- IsAllowedToPlay()
+ IsPlaybackBlocked()
{
- // The media element has already been paused or blocked, so it can't start
- // playback again by script or user's intend until resuming by audio channel.
- if (mSuspended == nsISuspendedTypes::SUSPENDED_PAUSE ||
- mSuspended == nsISuspendedTypes::SUSPENDED_BLOCK) {
- return false;
- }
-
// If the tab hasn't been activated yet, the media element in that tab can't
// be playback now until the tab goes to foreground first time or user clicks
// the unblocking tab icon.
if (!IsTabActivated()) {
// Even we haven't start playing yet, we still need to notify the audio
// channe system because we need to receive the resume notification later.
UpdateAudioChannelPlayingState(true /* force to start */);
- return false;
- }
-
- return true;
+ return true;
+ }
+
+ return false;
}
float
GetEffectiveVolume() const
{
return mOwner->Volume() * mAudioChannelVolume;
}
@@ -3563,32 +3556,38 @@ void
HTMLMediaElement::NotifyXPCOMShutdown()
{
ShutdownDecoder();
}
void
HTMLMediaElement::Play(ErrorResult& aRv)
{
- if (!IsAllowedToPlay()) {
+ if (mAudioChannelWrapper && mAudioChannelWrapper->IsPlaybackBlocked()) {
+ // NOTE: for promise-based-play, will return a pending promise here.
MaybeDoLoad();
return;
}
nsresult rv = PlayInternal();
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
UpdateCustomPolicyAfterPlayed();
}
nsresult
HTMLMediaElement::PlayInternal()
{
+ if (!IsAllowedToPlay()) {
+ // NOTE: for promise-based-play, will return a rejected promise here.
+ return NS_OK;
+ }
+
// Play was not blocked so assume user interacted with the element.
mHasUserInteraction = true;
StopSuspendingAfterFirstFrame();
SetPlayedOrSeeked(true);
MaybeDoLoad();
if (mSuspendedForPreloadNone) {
@@ -3652,17 +3651,18 @@ HTMLMediaElement::MaybeDoLoad()
{
if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
DoLoad();
}
}
NS_IMETHODIMP HTMLMediaElement::Play()
{
- if (!IsAllowedToPlay()) {
+ if (mAudioChannelWrapper && mAudioChannelWrapper->IsPlaybackBlocked()) {
+ // NOTE: for promise-based-play, will return a pending promise here.
MaybeDoLoad();
return NS_OK;
}
nsresult rv = PlayInternal();
if (NS_FAILED(rv)) {
return rv;
}
@@ -5484,18 +5484,23 @@ bool HTMLMediaElement::CanActivateAutopl
if (!mPaused) {
return false;
}
if (mPausedForInactiveDocumentOrChannel) {
return false;
}
- if (mAudioChannelWrapper && !mAudioChannelWrapper->IsAllowedToPlay()) {
- return false;
+ if (mAudioChannelWrapper) {
+ // Note: SUSPENDED_PAUSE and SUSPENDED_BLOCK will be merged into one single state.
+ if (mAudioChannelWrapper->GetSuspendType() == nsISuspendedTypes::SUSPENDED_PAUSE ||
+ mAudioChannelWrapper->GetSuspendType() == nsISuspendedTypes::SUSPENDED_BLOCK ||
+ mAudioChannelWrapper->IsPlaybackBlocked()) {
+ return false;
+ }
}
bool hasData =
(mDecoder && mReadyState >= nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA) ||
(mSrcStream && mSrcStream->Active()) ||
mMediaSource;
return hasData;
@@ -6310,17 +6315,23 @@ HTMLMediaElement::IsAllowedToPlay()
false,
false);
#endif
return false;
}
// Check our custom playback policy.
if (mAudioChannelWrapper) {
- return mAudioChannelWrapper->IsAllowedToPlay();
+ // Note: SUSPENDED_PAUSE and SUSPENDED_BLOCK will be merged into one single state.
+ if (mAudioChannelWrapper->GetSuspendType() == nsISuspendedTypes::SUSPENDED_PAUSE ||
+ mAudioChannelWrapper->GetSuspendType() == nsISuspendedTypes::SUSPENDED_BLOCK) {
+ return false;
+ }
+
+ return true;
}
// If the mAudioChannelWrapper doesn't exist that means the CC happened.
return false;
}
static const char* VisibilityString(Visibility aVisibility) {
switch(aVisibility) {