Bug 1339230 - part1 : only need to do audio competing for active agent. draft
authorAlastor Wu <alwu@mozilla.com>
Fri, 24 Feb 2017 17:15:20 +0800
changeset 489025 a9b94043a73f2fe7e052e2bb35a2b4752a084a85
parent 488302 32dcdde1fc64fc39a9065dc4218265dbc727673f
child 489026 3fb3731392bb36b503412c6dcb485404f7550f73
push id46736
push useralwu@mozilla.com
push dateFri, 24 Feb 2017 09:17:40 +0000
bugs1339230
milestone54.0a1
Bug 1339230 - part1 : only need to do audio competing for active agent. In Fennec, the audio competiting is to stop the playing tab if there is new incoming tab. We only implement the way to pause the tab, not including to resume the tab, so we just need to run the audio competing related stuffs when the agent is active. MozReview-Commit-ID: 3F0M2jLw9VY
dom/audiochannel/AudioChannelService.cpp
dom/audiochannel/AudioChannelService.h
--- a/dom/audiochannel/AudioChannelService.cpp
+++ b/dom/audiochannel/AudioChannelService.cpp
@@ -1082,27 +1082,26 @@ AudioChannelService::ChildStatusReceived
     mPlayingChildren.AppendElement(data);
   }
 
   data->mActiveTelephonyChannel = aTelephonyChannel;
   data->mActiveContentOrNormalChannel = aContentOrNormalChannel;
 }
 
 void
-AudioChannelService::RefreshAgentsAudioFocusChanged(AudioChannelAgent* aAgent,
-                                                    bool aActive)
+AudioChannelService::RefreshAgentsAudioFocusChanged(AudioChannelAgent* aAgent)
 {
   MOZ_ASSERT(aAgent);
 
   nsTObserverArray<nsAutoPtr<AudioChannelWindow>>::ForwardIterator
     iter(mWindows);
   while (iter.HasMore()) {
     AudioChannelWindow* winData = iter.GetNext();
     if (winData->mOwningAudioFocus) {
-      winData->AudioFocusChanged(aAgent, aActive);
+      winData->AudioFocusChanged(aAgent);
     }
   }
 }
 
 void
 AudioChannelService::NotifyMediaResumedFromBlock(nsPIDOMWindowOuter* aWindow)
 {
   MOZ_ASSERT(aWindow);
@@ -1151,18 +1150,17 @@ AudioChannelService::AudioChannelWindow:
 
   MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
          ("AudioChannelWindow, RequestAudioFocus, this = %p, "
           "agent = %p, owning audio focus = %d\n",
           this, aAgent, mOwningAudioFocus));
 }
 
 void
-AudioChannelService::AudioChannelWindow::NotifyAudioCompetingChanged(AudioChannelAgent* aAgent,
-                                                                     bool aActive)
+AudioChannelService::AudioChannelWindow::NotifyAudioCompetingChanged(AudioChannelAgent* aAgent)
 {
   // This function may be called after RemoveAgentAndReduceAgentsNum(), so the
   // agent may be not contained in mAgent. In addition, the agent would still
   // be alive because we have kungFuDeathGrip in UnregisterAudioChannelAgent().
   MOZ_ASSERT(aAgent);
 
   RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
   MOZ_ASSERT(service);
@@ -1172,20 +1170,20 @@ AudioChannelService::AudioChannelWindow:
   }
 
   if (!IsAgentInvolvingInAudioCompeting(aAgent)) {
     return;
   }
 
   MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
          ("AudioChannelWindow, NotifyAudioCompetingChanged, this = %p, "
-          "agent = %p, active = %d\n",
-          this, aAgent, aActive));
+          "agent = %p\n",
+          this, aAgent));
 
-  service->RefreshAgentsAudioFocusChanged(aAgent, aActive);
+  service->RefreshAgentsAudioFocusChanged(aAgent);
 }
 
 bool
 AudioChannelService::AudioChannelWindow::IsAgentInvolvingInAudioCompeting(AudioChannelAgent* aAgent) const
 {
   MOZ_ASSERT(aAgent);
 
   if(!mOwningAudioFocus) {
@@ -1205,18 +1203,17 @@ bool
 AudioChannelService::AudioChannelWindow::IsAudioCompetingInSameTab() const
 {
   bool hasMultipleActiveAgents = IsEnableAudioCompetingForAllAgents() ?
     mAgents.Length() > 1 : mAudibleAgents.Length() > 1;
   return mOwningAudioFocus && hasMultipleActiveAgents;
 }
 
 void
-AudioChannelService::AudioChannelWindow::AudioFocusChanged(AudioChannelAgent* aNewPlayingAgent,
-                                                           bool aActive)
+AudioChannelService::AudioChannelWindow::AudioFocusChanged(AudioChannelAgent* aNewPlayingAgent)
 {
   // This agent isn't always known for the current window, because it can comes
   // from other window.
   MOZ_ASSERT(aNewPlayingAgent);
 
   if (IsInactiveWindow()) {
     // These would happen in two situations,
     // (1) Audio in page A was ended, and another page B want to play audio.
@@ -1231,18 +1228,17 @@ AudioChannelService::AudioChannelWindow:
       MOZ_ASSERT(agent);
 
       // Don't need to update the playing state of new playing agent.
       if (agent == aNewPlayingAgent) {
         continue;
       }
 
       uint32_t type = GetCompetingBehavior(agent,
-                                           aNewPlayingAgent->AudioChannelType(),
-                                           aActive);
+                                           aNewPlayingAgent->AudioChannelType());
 
       // If window will be suspended, it needs to abandon the audio focus
       // because only one window can own audio focus at a time. However, we
       // would support multiple audio focus at the same time in the future.
       mOwningAudioFocus = (type == nsISuspendedTypes::NONE_SUSPENDED);
 
       // TODO : support other behaviors which are definded in MediaSession API.
       switch (type) {
@@ -1262,30 +1258,28 @@ AudioChannelService::AudioChannelWindow:
 bool
 AudioChannelService::AudioChannelWindow::IsContainingPlayingAgent(AudioChannelAgent* aAgent) const
 {
   return (aAgent->WindowID() == mWindowID);
 }
 
 uint32_t
 AudioChannelService::AudioChannelWindow::GetCompetingBehavior(AudioChannelAgent* aAgent,
-                                                              int32_t aIncomingChannelType,
-                                                              bool aIncomingChannelActive) const
+                                                              int32_t aIncomingChannelType) const
 {
   MOZ_ASSERT(aAgent);
   MOZ_ASSERT(IsEnableAudioCompetingForAllAgents() ?
     mAgents.Contains(aAgent) : mAudibleAgents.Contains(aAgent));
 
   uint32_t competingBehavior = nsISuspendedTypes::NONE_SUSPENDED;
   int32_t presentChannelType = aAgent->AudioChannelType();
 
   // TODO : add other competing cases for MediaSession API
   if (presentChannelType == int32_t(AudioChannel::Normal) &&
-      aIncomingChannelType == int32_t(AudioChannel::Normal) &&
-      aIncomingChannelActive) {
+      aIncomingChannelType == int32_t(AudioChannel::Normal)) {
     competingBehavior = nsISuspendedTypes::SUSPENDED_STOP_DISPOSABLE;
   }
 
   MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
          ("AudioChannelWindow, GetCompetingBehavior, this = %p, "
           "present type = %d, incoming channel = %d, behavior = %d\n",
           this, presentChannelType, aIncomingChannelType, competingBehavior));
 
@@ -1309,17 +1303,17 @@ AudioChannelService::AudioChannelWindow:
   AppendAgentAndIncreaseAgentsNum(aAgent);
   AudioCapturedChanged(aAgent, AudioCaptureState::eCapturing);
   if (aAudible == AudibleState::eAudible) {
     AudioAudibleChanged(aAgent,
                         AudibleState::eAudible,
                         AudibleChangedReasons::eDataAudibleChanged);
   } else if (IsEnableAudioCompetingForAllAgents() &&
              aAudible != AudibleState::eAudible) {
-    NotifyAudioCompetingChanged(aAgent, true);
+    NotifyAudioCompetingChanged(aAgent);
   }
 }
 
 void
 AudioChannelService::AudioChannelWindow::RemoveAgent(AudioChannelAgent* aAgent)
 {
   MOZ_ASSERT(aAgent);
 
@@ -1407,18 +1401,19 @@ AudioChannelService::AudioChannelWindow:
   MOZ_ASSERT(aAgent);
 
   if (aAudible == AudibleState::eAudible) {
     AppendAudibleAgentIfNotContained(aAgent, aReason);
   } else {
     RemoveAudibleAgentIfContained(aAgent, aReason);
   }
 
-  NotifyAudioCompetingChanged(aAgent, aAudible == AudibleState::eAudible);
-  if (aAudible != AudibleState::eNotAudible) {
+  if (aAudible == AudibleState::eAudible) {
+    NotifyAudioCompetingChanged(aAgent);
+  } else if (aAudible != AudibleState::eNotAudible) {
     MaybeNotifyMediaBlockStart(aAgent);
   }
 }
 
 void
 AudioChannelService::AudioChannelWindow::AppendAudibleAgentIfNotContained(AudioChannelAgent* aAgent,
                                                                           AudibleChangedReasons aReason)
 {
--- a/dom/audiochannel/AudioChannelService.h
+++ b/dom/audiochannel/AudioChannelService.h
@@ -228,18 +228,17 @@ private:
   void MaybeSendStatusUpdate();
 
   bool ContentOrNormalChannelIsActive();
 
   /* Send the default-volume-channel-changed notification */
   void SetDefaultVolumeControlChannelInternal(int32_t aChannel,
                                               bool aVisible, uint64_t aChildID);
 
-  void RefreshAgentsAudioFocusChanged(AudioChannelAgent* aAgent,
-                                      bool aActive);
+  void RefreshAgentsAudioFocusChanged(AudioChannelAgent* aAgent);
 
   class AudioChannelConfig final : public AudioPlaybackConfig
   {
   public:
     AudioChannelConfig()
       : AudioPlaybackConfig(1.0, IsAudioChannelMutedByDefault(),
                             nsISuspendedTypes::NONE_SUSPENDED)
       , mNumberOfAgents(0)
@@ -256,17 +255,17 @@ private:
       , mIsAudioCaptured(false)
       , mOwningAudioFocus(!AudioChannelService::IsEnableAudioCompeting())
       , mShouldSendBlockStopEvent(false)
     {
       // Workaround for bug1183033, system channel type can always playback.
       mChannels[(int16_t)AudioChannel::System].mMuted = false;
     }
 
-    void AudioFocusChanged(AudioChannelAgent* aNewPlayingAgent, bool aActive);
+    void AudioFocusChanged(AudioChannelAgent* aNewPlayingAgent);
     void AudioAudibleChanged(AudioChannelAgent* aAgent,
                              AudibleState aAudible,
                              AudibleChangedReasons aReason);
 
     void AppendAgent(AudioChannelAgent* aAgent, AudibleState aAudible);
     void RemoveAgent(AudioChannelAgent* aAgent);
 
     void NotifyMediaBlockStop(nsPIDOMWindowOuter* aWindow);
@@ -305,21 +304,22 @@ private:
                                    AudibleState aAudible,
                                    AudibleChangedReasons aReason);
 
     void NotifyChannelActive(uint64_t aWindowID, AudioChannel aChannel,
                              bool aActive);
     void MaybeNotifyMediaBlockStart(AudioChannelAgent* aAgent);
 
     void RequestAudioFocus(AudioChannelAgent* aAgent);
-    void NotifyAudioCompetingChanged(AudioChannelAgent* aAgent, bool aActive);
+
+    // We need to do audio competing only when the new incoming agent started.
+    void NotifyAudioCompetingChanged(AudioChannelAgent* aAgent);
 
     uint32_t GetCompetingBehavior(AudioChannelAgent* aAgent,
-                                  int32_t aIncomingChannelType,
-                                  bool aIncomingChannelActive) const;
+                                  int32_t aIncomingChannelType) const;
     bool IsAgentInvolvingInAudioCompeting(AudioChannelAgent* aAgent) const;
     bool IsAudioCompetingInSameTab() const;
     bool IsContainingPlayingAgent(AudioChannelAgent* aAgent) const;
 
     bool IsInactiveWindow() const;
   };
 
   AudioChannelWindow*