diff --git a/dom/audiochannel/AudioChannelService.cpp b/dom/audiochannel/AudioChannelService.cpp index a17a2b21eb6..b23423f8a14 100644 --- a/dom/audiochannel/AudioChannelService.cpp +++ b/dom/audiochannel/AudioChannelService.cpp @@ -113,6 +113,18 @@ AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent, aWithVideo); mAgents.Put(aAgent, data); RegisterType(aType, CONTENT_PROCESS_ID_MAIN, aWithVideo); + + // If this is the first agent for this window, we must notify the observers. + uint32_t count = CountWindow(aAgent->Window()); + if (count == 1) { + nsCOMPtr observerService = + services::GetObserverService(); + if (observerService) { + observerService->NotifyObservers(ToSupports(aAgent->Window()), + "media-playback", + NS_LITERAL_STRING("active").get()); + } + } } void @@ -181,6 +193,18 @@ AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent) mSpeakerManager[i]->SetAudioChannelActive(active); } #endif + + // If this is the last agent for this window, we must notify the observers. + uint32_t count = CountWindow(aAgent->Window()); + if (count == 0) { + nsCOMPtr observerService = + services::GetObserverService(); + if (observerService) { + observerService->NotifyObservers(ToSupports(aAgent->Window()), + "media-playback", + NS_LITERAL_STRING("inactive").get()); + } + } } void @@ -822,3 +846,37 @@ AudioChannelService::RefreshAgentsVolume(nsPIDOMWindow* aWindow) data.mAgents[i]->WindowVolumeChanged(); } } + +struct CountWindowData +{ + CountWindowData(nsIDOMWindow* aWindow) + : mWindow(aWindow) + , mCount(0) + {} + + nsIDOMWindow* mWindow; + uint32_t mCount; +}; + +PLDHashOperator +AudioChannelService::CountWindowEnumerator(AudioChannelAgent* aAgent, + AudioChannelAgentData* aUnused, + void* aPtr) +{ + CountWindowData* data = static_cast(aPtr); + MOZ_ASSERT(aAgent); + + if (aAgent->Window() == data->mWindow) { + ++data->mCount; + } + + return PL_DHASH_NEXT; +} + +uint32_t +AudioChannelService::CountWindow(nsIDOMWindow* aWindow) +{ + CountWindowData data(aWindow); + mAgents.EnumerateRead(CountWindowEnumerator, &data); + return data.mCount; +} diff --git a/dom/audiochannel/AudioChannelService.h b/dom/audiochannel/AudioChannelService.h index 7aa7d98003e..011ea54fefd 100644 --- a/dom/audiochannel/AudioChannelService.h +++ b/dom/audiochannel/AudioChannelService.h @@ -188,6 +188,14 @@ protected: AudioChannelAgentData* aUnused, void *aPtr); + static PLDHashOperator + CountWindowEnumerator(AudioChannelAgent* aAgent, + AudioChannelAgentData* aUnused, + void *aPtr); + + // This returns the number of agents from this aWindow. + uint32_t CountWindow(nsIDOMWindow* aWindow); + nsClassHashtable< nsPtrHashKey, AudioChannelAgentData > mAgents; #ifdef MOZ_WIDGET_GONK nsTArray mSpeakerManager; diff --git a/dom/base/test/audio.ogg b/dom/base/test/audio.ogg new file mode 100644 index 00000000000..d7f6a0ccf47 Binary files /dev/null and b/dom/base/test/audio.ogg differ diff --git a/dom/base/test/mochitest.ini b/dom/base/test/mochitest.ini index f5613e88a14..622be567d25 100644 --- a/dom/base/test/mochitest.ini +++ b/dom/base/test/mochitest.ini @@ -1,5 +1,6 @@ [DEFAULT] support-files = + audio.ogg iframe_messageChannel_cloning.html iframe_messageChannel_pingpong.html iframe_messageChannel_post.html @@ -9,6 +10,7 @@ support-files = [test_Image_constructor.html] [test_appname_override.html] [test_audioWindowUtils.html] +[test_audioNotification.html] [test_bug913761.html] [test_bug978522.html] [test_bug979109.html] diff --git a/dom/base/test/test_audioNotification.html b/dom/base/test/test_audioNotification.html new file mode 100644 index 00000000000..b035ecd9295 --- /dev/null +++ b/dom/base/test/test_audioNotification.html @@ -0,0 +1,75 @@ + + + + Test for audio controller in windows + + + + +
+
+ + + + +