diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h index da71e08aba32..4de86ef05400 100644 --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -1817,6 +1817,10 @@ GK_ATOM(onuserproximity, "onuserproximity") // light sensor support GK_ATOM(ondevicelight, "ondevicelight") +// Audio channel events +GK_ATOM(onmozinterruptbegin, "onmozinterruptbegin") +GK_ATOM(onmozinterruptend, "onmozinterruptbegin") + //--------------------------------------------------------------------------- // Special atoms //--------------------------------------------------------------------------- diff --git a/content/media/webaudio/AudioContext.cpp b/content/media/webaudio/AudioContext.cpp index 52976550e733..816b4e231a2b 100644 --- a/content/media/webaudio/AudioContext.cpp +++ b/content/media/webaudio/AudioContext.cpp @@ -14,6 +14,7 @@ #include "mozilla/dom/OfflineAudioContextBinding.h" #include "mozilla/dom/OwningNonNull.h" #include "MediaStreamGraph.h" +#include "AudioChannelService.h" #include "AudioDestinationNode.h" #include "AudioBufferSourceNode.h" #include "AudioBuffer.h" @@ -131,7 +132,9 @@ AudioContext::Constructor(const GlobalObject& aGlobal, return nullptr; } - nsRefPtr object = new AudioContext(window, false); + nsRefPtr object = + new AudioContext(window, false, + AudioChannelService::GetDefaultAudioChannel()); RegisterWeakMemoryReporter(object); diff --git a/content/media/webaudio/AudioContext.h b/content/media/webaudio/AudioContext.h index c1f4fe186c05..aae2ee6f1655 100644 --- a/content/media/webaudio/AudioContext.h +++ b/content/media/webaudio/AudioContext.h @@ -67,7 +67,7 @@ class AudioContext MOZ_FINAL : public DOMEventTargetHelper, { AudioContext(nsPIDOMWindow* aParentWindow, bool aIsOffline, - AudioChannel aChannel = AudioChannel::Normal, + AudioChannel aChannel, uint32_t aNumberOfChannels = 0, uint32_t aLength = 0, float aSampleRate = 0.0f); @@ -231,6 +231,9 @@ public: return aTime - ExtraCurrentTime(); } + IMPL_EVENT_HANDLER(mozinterruptbegin) + IMPL_EVENT_HANDLER(mozinterruptend) + private: /** * Returns the amount of extra time added to the current time of the diff --git a/content/media/webaudio/test/browser.ini b/content/media/webaudio/test/browser.ini new file mode 100644 index 000000000000..0f0790f3b633 --- /dev/null +++ b/content/media/webaudio/test/browser.ini @@ -0,0 +1,5 @@ +[DEFAULT] +support-files = + browser_mozAudioChannel.html + +[browser_mozAudioChannel.js] diff --git a/content/media/webaudio/test/browser_mozAudioChannel.html b/content/media/webaudio/test/browser_mozAudioChannel.html new file mode 100644 index 000000000000..cb655df9d1f0 --- /dev/null +++ b/content/media/webaudio/test/browser_mozAudioChannel.html @@ -0,0 +1,31 @@ + + +Test for mozinterruptbegin/end in AudioContext + +mozAudioChannelTest = FAIL + + diff --git a/content/media/webaudio/test/browser_mozAudioChannel.js b/content/media/webaudio/test/browser_mozAudioChannel.js new file mode 100644 index 000000000000..178250f42bb5 --- /dev/null +++ b/content/media/webaudio/test/browser_mozAudioChannel.js @@ -0,0 +1,71 @@ +/* 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/. */ + +function whenBrowserLoaded(aBrowser, aCallback) { + aBrowser.addEventListener("load", function onLoad(event) { + if (event.target == aBrowser.contentDocument) { + aBrowser.removeEventListener("load", onLoad, true); + executeSoon(aCallback); + } + }, true); +} + +function whenTabRestored(aTab, aCallback) { + aTab.addEventListener("SSTabRestored", function onRestored(aEvent) { + aTab.removeEventListener("SSTabRestored", onRestored, true); + executeSoon(function executeWhenTabRestored() { + aCallback(); + }); + }, true); +} + +function whenBrowserUnloaded(aBrowser, aCallback) { + aBrowser.addEventListener("unload", function onUnload() { + aBrowser.removeEventListener("unload", onUnload, true); + executeSoon(aCallback); + }, true); +} + +function test() { + + waitForExplicitFinish(); + + let testURL = "http://mochi.test:8888/browser/" + + "content/media/webaudio/test/browser_mozAudioChannel.html"; + + SpecialPowers.pushPrefEnv({"set": [["media.defaultAudioChannel", "content" ], + ["media.useAudioChannelService", true ]]}, + function() { + let tab1 = gBrowser.addTab(testURL); + gBrowser.selectedTab = tab1; + + whenBrowserLoaded(tab1.linkedBrowser, function() { + let doc = tab1.linkedBrowser.contentDocument; + is(doc.getElementById("mozAudioChannelTest").textContent, "READY", + "Test is ready to run"); + + SpecialPowers.pushPrefEnv({"set": [["media.defaultAudioChannel", "telephony" ]]}, + function() { + let tab2 = gBrowser.duplicateTab(tab1); + gBrowser.selectedTab = tab2; + whenTabRestored(tab2, function() { + is(doc.getElementById("mozAudioChannelTest").textContent, "mozinterruptbegin", + "AudioContext has been muted by the second tab."); + + whenBrowserUnloaded(tab2.linkedBrowser, function() { + is(doc.getElementById("mozAudioChannelTest").textContent, "mozinterruptend", + "AudioContext has been unmuted."); + gBrowser.removeTab(tab1); + finish(); + }); + + gBrowser.removeTab(tab2); + gBrowser.selectedTab = tab1; + }); + } + ); + }); + } + ); +} diff --git a/content/media/webaudio/test/moz.build b/content/media/webaudio/test/moz.build index 0b1d91ca7b17..5e35702847be 100644 --- a/content/media/webaudio/test/moz.build +++ b/content/media/webaudio/test/moz.build @@ -12,3 +12,7 @@ MOCHITEST_MANIFESTS += [ MOCHITEST_CHROME_MANIFESTS += [ 'chrome.ini' ] + +BROWSER_CHROME_MANIFESTS += [ + 'browser.ini' +] diff --git a/dom/webidl/AudioContext.webidl b/dom/webidl/AudioContext.webidl index 10a3d2d7d926..bfdb99485c6c 100644 --- a/dom/webidl/AudioContext.webidl +++ b/dom/webidl/AudioContext.webidl @@ -81,3 +81,14 @@ partial interface AudioContext { [Pref="media.useAudioChannelService", SetterThrows] attribute AudioChannel mozAudioChannelType; }; + +partial interface AudioContext { + // These 2 events are dispatched when the AudioContext object is muted by + // the AudioChannelService. It's call 'interrupt' because when this event is + // dispatched on a HTMLMediaElement, the audio stream is paused. + [Pref="media.useAudioChannelService"] + attribute EventHandler onmozinterruptbegin; + + [Pref="media.useAudioChannelService"] + attribute EventHandler onmozinterruptend; +};