Bug 1346872 - part1 : notify audible state change when AudioDestinationNode was muted or suspended. draft
authorAlastor Wu <alwu@mozilla.com>
Thu, 30 Mar 2017 14:25:37 +0800
changeset 553508 3d25a41f5f6ce519fbfd061307c1666a9f097dea
parent 552146 5182b2c4b963ed87d038c7d9a4021463917076cd
child 553509 5a26483edd2fb8d03bf08c971dc64ca8a01949a6
push id51658
push useralwu@mozilla.com
push dateThu, 30 Mar 2017 06:27:26 +0000
bugs1346872
milestone55.0a1
Bug 1346872 - part1 : notify audible state change when AudioDestinationNode was muted or suspended. Web audio should also notify AudioChannelService about its audible state change. MozReview-Commit-ID: BtjUkHKPETg
dom/media/webaudio/AudioDestinationNode.cpp
dom/media/webaudio/AudioDestinationNode.h
--- a/dom/media/webaudio/AudioDestinationNode.cpp
+++ b/dom/media/webaudio/AudioDestinationNode.cpp
@@ -328,16 +328,17 @@ AudioDestinationNode::AudioDestinationNo
                                            uint32_t aLength, float aSampleRate)
   : AudioNode(aContext, aIsOffline ? aNumberOfChannels : 2,
               ChannelCountMode::Explicit, ChannelInterpretation::Speakers)
   , mFramesToProduce(aLength)
   , mAudioChannel(AudioChannel::Normal)
   , mIsOffline(aIsOffline)
   , mAudioChannelSuspended(false)
   , mCaptured(false)
+  , mAudible(AudioChannelService::AudibleState::eAudible)
 {
   MediaStreamGraph* graph = aIsOffline ?
                             MediaStreamGraph::CreateNonRealtimeInstance(aSampleRate) :
                             MediaStreamGraph::GetInstance(MediaStreamGraph::AUDIO_THREAD_DRIVER, aChannel);
   AudioNodeEngine* engine = aIsOffline ?
                             new OfflineDestinationNodeEngine(this, aNumberOfChannels,
                                                              aLength, aSampleRate) :
                             static_cast<AudioNodeEngine*>(new DestinationNodeEngine(this));
@@ -380,16 +381,18 @@ AudioDestinationNode::SizeOfIncludingThi
 }
 
 void
 AudioDestinationNode::DestroyAudioChannelAgent()
 {
   if (mAudioChannelAgent && !Context()->IsOffline()) {
     mAudioChannelAgent->NotifyStoppedPlaying();
     mAudioChannelAgent = nullptr;
+    // Reset the state, and it would always be regard as audible.
+    mAudible = AudioChannelService::AudibleState::eAudible;
   }
 }
 
 void
 AudioDestinationNode::DestroyMediaStream()
 {
   DestroyAudioChannelAgent();
 
@@ -509,16 +512,25 @@ AudioDestinationNode::WindowVolumeChange
 
   MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
          ("AudioDestinationNode, WindowVolumeChanged, "
           "this = %p, aVolume = %f, aMuted = %s\n",
           this, aVolume, aMuted ? "true" : "false"));
 
   float volume = aMuted ? 0.0 : aVolume;
   mStream->SetAudioOutputVolume(&gWebAudioOutputKey, volume);
+
+  AudioChannelService::AudibleState audible = volume > 0.0 ?
+    AudioChannelService::AudibleState::eAudible :
+    AudioChannelService::AudibleState::eNotAudible;
+  if (mAudible != audible) {
+    mAudible = audible;
+    mAudioChannelAgent->NotifyStartedAudible(mAudible,
+                                             AudioChannelService::AudibleChangedReasons::eVolumeChanged);
+  }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 AudioDestinationNode::WindowSuspendChanged(nsSuspendedTypes aSuspend)
 {
   if (!mStream) {
     return NS_OK;
@@ -536,16 +548,26 @@ AudioDestinationNode::WindowSuspendChang
   mAudioChannelSuspended = suspended;
   Context()->DispatchTrustedEvent(!suspended ?
     NS_LITERAL_STRING("mozinterruptend") :
     NS_LITERAL_STRING("mozinterruptbegin"));
 
   DisabledTrackMode disabledMode = suspended ? DisabledTrackMode::SILENCE_BLACK
                                              : DisabledTrackMode::ENABLED;
   mStream->SetTrackEnabled(AudioNodeStream::AUDIO_TRACK, disabledMode);
+
+  AudioChannelService::AudibleState audible =
+    aSuspend == nsISuspendedTypes::NONE_SUSPENDED ?
+      AudioChannelService::AudibleState::eAudible :
+      AudioChannelService::AudibleState::eNotAudible;
+  if (mAudible != audible) {
+    mAudible = audible;
+    mAudioChannelAgent->NotifyStartedAudible(audible,
+                                             AudioChannelService::AudibleChangedReasons::ePauseStateChanged);
+  }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 AudioDestinationNode::WindowAudioCaptureChanged(bool aCapture)
 {
   MOZ_ASSERT(mAudioChannelAgent);
 
@@ -671,22 +693,24 @@ AudioDestinationNode::InputMuted(bool aM
     if (aMuted) {
       return;
     }
     CreateAudioChannelAgent();
   }
 
   if (aMuted) {
     mAudioChannelAgent->NotifyStoppedPlaying();
+    // Reset the state, and it would always be regard as audible.
+    mAudible = AudioChannelService::AudibleState::eAudible;
     return;
   }
 
   AudioPlaybackConfig config;
   nsresult rv = mAudioChannelAgent->NotifyStartedPlaying(&config,
-                                                         AudioChannelService::AudibleState::eAudible);
+                                                         mAudible);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return;
   }
 
   WindowVolumeChanged(config.mVolume, config.mMuted);
   WindowSuspendChanged(config.mSuspend);
 }
 
--- a/dom/media/webaudio/AudioDestinationNode.h
+++ b/dom/media/webaudio/AudioDestinationNode.h
@@ -2,17 +2,17 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef AudioDestinationNode_h_
 #define AudioDestinationNode_h_
 
-#include "mozilla/dom/AudioChannelBinding.h"
+#include "AudioChannelService.h"
 #include "AudioNode.h"
 #include "nsIAudioChannelAgent.h"
 
 namespace mozilla {
 namespace dom {
 
 class AudioContext;
 
@@ -101,15 +101,16 @@ private:
   RefPtr<Promise> mOfflineRenderingPromise;
 
   // Audio Channel Type.
   AudioChannel mAudioChannel;
   bool mIsOffline;
   bool mAudioChannelSuspended;
 
   bool mCaptured;
+  AudioChannelService::AudibleState mAudible;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif