Bug 1321196 part 2 - rework the IsAllowedToPlay policy; r=alwu,jwwang
authorKaku Kuo <kaku@mozilla.com>
Wed, 30 Nov 2016 16:01:36 +0800
changeset 324901 fcabe39c665ff1e8e5a83563748449ca1acc214f
parent 324900 e972bb041a4e91742496a48672cf63721d3700ee
child 324902 0fc28aab9031aa803f8adbe69c059063195cd6c3
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersalwu, jwwang
bugs1321196
milestone53.0a1
Bug 1321196 part 2 - rework the IsAllowedToPlay policy; r=alwu,jwwang MozReview-Commit-ID: 8mrXoLRK42y
dom/html/HTMLMediaElement.cpp
--- 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) {