Bug 1322505 - part2 : reset suspend type for blocked media after calling media.pause(). draft
authorAlastor Wu <alwu@mozilla.com>
Mon, 23 Jan 2017 10:52:06 +0800
changeset 464872 384e5db1186c5f2ad5a9abeb13d68efc06e35e93
parent 464871 5a65bee282f16edd5834a9f1d218589da3d41eab
child 464873 dd49da50cb91a47bde92ff3fca320760dedc1ede
push id42464
push useralwu@mozilla.com
push dateMon, 23 Jan 2017 06:45:24 +0000
bugs1322505
milestone53.0a1
Bug 1322505 - part2 : reset suspend type for blocked media after calling media.pause(). If the blocked media is paused before resuming it, we should not resume it again after the tab is visible. The way to achieve that is to unregister the agent so AudioChannelService can't resume that media because we have disconnected their relationship. MozReview-Commit-ID: 6Dq4K9hVsU0
dom/html/HTMLMediaElement.cpp
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -649,25 +649,42 @@ public:
         return;
       }
 
       mPlayingThroughTheAudioChannel = playingThroughTheAudioChannel;
       NotifyAudioChannelAgent(mPlayingThroughTheAudioChannel);
     }
   }
 
+  bool
+  ShouldResetSuspend() const
+  {
+    // The disposable-pause should be clear after media starts playing.
+    if (!mOwner->Paused() &&
+        mSuspended == nsISuspendedTypes::SUSPENDED_PAUSE_DISPOSABLE) {
+      return true;
+    }
+
+    // If the blocked media is paused, we don't need to resume it. We reset the
+    // mSuspended in order to unregister the agent.
+    if (mOwner->Paused() &&
+        mSuspended == nsISuspendedTypes::SUSPENDED_BLOCK) {
+      return true;
+    }
+
+    return false;
+  }
+
   void
   NotifyPlayStateChanged()
   {
     MOZ_ASSERT(!mIsShutDown);
-    // When owner's play state changed, we should reset the suspend type. If
-    // owner is playing, the suspend type should be 'NONE_SUSPENDED', and if
-    // owner paused, the suspend type also needs to be reset because the agent
-    // maybe need to be unregistered.
-    SetSuspended(nsISuspendedTypes::NONE_SUSPENDED);
+    if (ShouldResetSuspend()) {
+      SetSuspended(nsISuspendedTypes::NONE_SUSPENDED);
+    }
     UpdateAudioChannelPlayingState();
   }
 
   NS_IMETHODIMP
   WindowVolumeChanged(float aVolume, bool aMuted) override
   {
     MOZ_ASSERT(mAudioChannelAgent);
 
@@ -876,17 +893,17 @@ private:
   }
 
   void
   Resume()
   {
     if (!IsSuspended()) {
       MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
              ("HTMLMediaElement::AudioChannelAgentCallback, ResumeFromAudioChannel, "
-              "this = %p, Error : resume without suspended!\n", this));
+              "this = %p, don't need to be resumed!\n", this));
       return;
     }
 
     SetSuspended(nsISuspendedTypes::NONE_SUSPENDED);
     IgnoredErrorResult rv;
     RefPtr<Promise> toBeIgnored = mOwner->Play(rv);
     MOZ_ASSERT_IF(toBeIgnored && toBeIgnored->State() == Promise::PromiseState::Rejected,
                   rv.Failed());
@@ -2753,17 +2770,19 @@ HTMLMediaElement::Pause(ErrorResult& aRv
   }
 
   bool oldPaused = mPaused;
   mPaused = true;
   mAutoplaying = false;
   // We changed mPaused and mAutoplaying which can affect AddRemoveSelfReference
   AddRemoveSelfReference();
   UpdateSrcMediaStreamPlaying();
-  UpdateAudioChannelPlayingState();
+  if (mAudioChannelWrapper) {
+    mAudioChannelWrapper->NotifyPlayStateChanged();
+  }
 
   if (!oldPaused) {
     FireTimeUpdate(false);
     DispatchAsyncEvent(NS_LITERAL_STRING("pause"));
     AsyncRejectPendingPlayPromises(NS_ERROR_DOM_MEDIA_ABORT_ERR);
   }
 }