diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index 542853b4a51e..599bd4579989 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -474,6 +474,22 @@ + + + + + + + @@ -5064,14 +5080,10 @@ + + + + + + diff --git a/dom/audiochannel/AudioChannelService.cpp b/dom/audiochannel/AudioChannelService.cpp index 58cbcace549b..9ecca9ba8e8a 100644 --- a/dom/audiochannel/AudioChannelService.cpp +++ b/dom/audiochannel/AudioChannelService.cpp @@ -1251,6 +1251,7 @@ AudioChannelService::AudioChannelWindow::AppendAgent(AudioChannelAgent* aAgent, } else if (IsEnableAudioCompetingForAllAgents() && !aAudible) { NotifyAudioCompetingChanged(aAgent, true); } + MaybeNotifyMediaBlocked(aAgent); } void @@ -1399,3 +1400,30 @@ AudioChannelService::AudioChannelWindow::NotifyChannelActive(uint64_t aWindowID, DebugOnly rv = NS_DispatchToCurrentThread(runnable); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToCurrentThread failed"); } + +void +AudioChannelService::AudioChannelWindow::MaybeNotifyMediaBlocked(AudioChannelAgent* aAgent) +{ + nsCOMPtr window = aAgent->Window(); + if (!window) { + return; + } + + MOZ_ASSERT(window->IsOuterWindow()); + if (window->GetMediaSuspend() != nsISuspendedTypes::SUSPENDED_BLOCK) { + return; + } + + NS_DispatchToCurrentThread(NS_NewRunnableFunction([window] () -> void { + nsCOMPtr observerService = + services::GetObserverService(); + if (NS_WARN_IF(!observerService)) { + return; + } + + observerService->NotifyObservers(ToSupports(window), + "audio-playback", + u"block"); + }) + ); +} diff --git a/dom/audiochannel/AudioChannelService.h b/dom/audiochannel/AudioChannelService.h index a862c6571c82..a01cb58c65fd 100644 --- a/dom/audiochannel/AudioChannelService.h +++ b/dom/audiochannel/AudioChannelService.h @@ -298,6 +298,7 @@ private: void NotifyChannelActive(uint64_t aWindowID, AudioChannel aChannel, bool aActive); + void MaybeNotifyMediaBlocked(AudioChannelAgent* aAgent); void RequestAudioFocus(AudioChannelAgent* aAgent); void NotifyAudioCompetingChanged(AudioChannelAgent* aAgent, bool aActive); diff --git a/toolkit/content/browser-content.js b/toolkit/content/browser-content.js index f0cc157e84a1..4ae798fbdc01 100644 --- a/toolkit/content/browser-content.js +++ b/toolkit/content/browser-content.js @@ -1013,7 +1013,11 @@ var AudioPlaybackListener = { if (topic === "audio-playback") { if (subject && subject.top == global.content) { let name = "AudioPlayback:"; - name += (data === "active") ? "Start" : "Stop"; + if (data === "block") { + name += "Block"; + } else { + name += (data === "active") ? "Start" : "Stop"; + } sendAsyncMessage(name); } } else if (topic == "AudioFocusChanged" || topic == "MediaControl") { diff --git a/toolkit/content/widgets/browser.xml b/toolkit/content/widgets/browser.xml index f89191a088a3..a5f37b62a1c5 100644 --- a/toolkit/content/widgets/browser.xml +++ b/toolkit/content/widgets/browser.xml @@ -690,6 +690,12 @@ let event = document.createEvent("Events"); event.initEvent("DOMAudioPlaybackStarted", true, false); this.dispatchEvent(event); + if (this._audioBlocked) { + this._audioBlocked = false; + event = document.createEvent("Events"); + event.initEvent("DOMAudioPlaybackBlockStopped", true, false); + this.dispatchEvent(event); + } ]]> @@ -704,11 +710,28 @@ + + + + + + false + + false + + @@ -767,8 +791,12 @@ @@ -922,6 +950,7 @@ this.messageManager.addMessageListener("Autoscroll:Cancel", this); this.messageManager.addMessageListener("AudioPlayback:Start", this); this.messageManager.addMessageListener("AudioPlayback:Stop", this); + this.messageManager.addMessageListener("AudioPlayback:Block", this); } ]]> @@ -1008,6 +1037,9 @@ case "AudioPlayback:Stop": this.audioPlaybackStopped(); break; + case "AudioPlayback:Block": + this.audioPlaybackBlocked(); + break; } return undefined; ]]>