diff --git a/dom/audiochannel/AudioChannelService.cpp b/dom/audiochannel/AudioChannelService.cpp index ae5681ad5bbe..e55136797e18 100644 --- a/dom/audiochannel/AudioChannelService.cpp +++ b/dom/audiochannel/AudioChannelService.cpp @@ -43,34 +43,59 @@ namespace { // If true, any new AudioChannelAgent will be muted when created. bool sAudioChannelMutedByDefault = false; +class NotifyChannelActiveRunnable final : public nsRunnable +{ +public: + NotifyChannelActiveRunnable(uint64_t aWindowID, AudioChannel aAudioChannel, + bool aActive) + : mWindowID(aWindowID) + , mAudioChannel(aAudioChannel) + , mActive(aActive) + {} + + NS_IMETHOD Run() override + { + nsCOMPtr observerService = + services::GetObserverService(); + if (NS_WARN_IF(!observerService)) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr wrapper = + do_CreateInstance(NS_SUPPORTS_PRUINT64_CONTRACTID); + if (NS_WARN_IF(!wrapper)) { + return NS_ERROR_FAILURE; + } + + wrapper->SetData(mWindowID); + + nsAutoString name; + AudioChannelService::GetAudioChannelString(mAudioChannel, name); + + nsAutoCString topic; + topic.Assign("audiochannel-activity-"); + topic.Append(NS_ConvertUTF16toUTF8(name)); + + observerService->NotifyObservers(wrapper, topic.get(), + mActive + ? MOZ_UTF16("active") + : MOZ_UTF16("inactive")); + return NS_OK; + } + +private: + const uint64_t mWindowID; + const AudioChannel mAudioChannel; + const bool mActive; +}; + void NotifyChannelActive(uint64_t aWindowID, AudioChannel aAudioChannel, bool aActive) { - nsCOMPtr observerService = - services::GetObserverService(); - if (NS_WARN_IF(!observerService)) { - return; - } - - nsCOMPtr wrapper = - do_CreateInstance(NS_SUPPORTS_PRUINT64_CONTRACTID); - if (!wrapper) { - return; - } - - wrapper->SetData(aWindowID); - - nsAutoString name; - AudioChannelService::GetAudioChannelString(aAudioChannel, name); - - nsAutoCString topic; - topic.Assign("audiochannel-activity-"); - topic.Append(NS_ConvertUTF16toUTF8(name)); - - observerService->NotifyObservers(wrapper, topic.get(), - aActive - ? MOZ_UTF16("active") : MOZ_UTF16("inactive")); + nsRefPtr runnable = + new NotifyChannelActiveRunnable(aWindowID, aAudioChannel, aActive); + NS_DispatchToCurrentThread(runnable); } already_AddRefed @@ -94,6 +119,34 @@ IsParentProcess() return XRE_GetProcessType() == GeckoProcessType_Default; } +class MediaPlaybackRunnable : public nsRunnable +{ +public: + MediaPlaybackRunnable(nsIDOMWindow* aWindow, bool aActive) + : mWindow(aWindow) + , mActive(aActive) + {} + + NS_IMETHOD Run() + { + nsCOMPtr observerService = + services::GetObserverService(); + if (observerService) { + observerService->NotifyObservers( + ToSupports(mWindow), + "media-playback", + mActive ? NS_LITERAL_STRING("active").get() + : NS_LITERAL_STRING("inactive").get()); + } + + return NS_OK; + } + +private: + nsCOMPtr mWindow; + bool mActive; +}; + } // anonymous namespace StaticRefPtr gAudioChannelService; @@ -208,13 +261,9 @@ AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent, // If this is the first agent for this window, we must notify the observers. if (winData->mAgents.Length() == 1) { - nsCOMPtr observerService = - services::GetObserverService(); - if (observerService) { - observerService->NotifyObservers(ToSupports(aAgent->Window()), - "media-playback", - NS_LITERAL_STRING("active").get()); - } + nsRefPtr runnable = + new MediaPlaybackRunnable(aAgent->Window(), true /* active */); + NS_DispatchToCurrentThread(runnable); } MaybeSendStatusUpdate(); @@ -258,13 +307,9 @@ AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent) // If this is the last agent for this window, we must notify the observers. if (winData->mAgents.IsEmpty()) { - nsCOMPtr observerService = - services::GetObserverService(); - if (observerService) { - observerService->NotifyObservers(ToSupports(aAgent->Window()), - "media-playback", - NS_LITERAL_STRING("inactive").get()); - } + nsRefPtr runnable = + new MediaPlaybackRunnable(aAgent->Window(), false /* active */); + NS_DispatchToCurrentThread(runnable); } MaybeSendStatusUpdate();