mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 923247 - patch 2 - mute and volume per window, r=ehsan, r=roc
This commit is contained in:
parent
af673bd5ac
commit
957cd4aa97
@ -245,6 +245,12 @@ HTMLAudioElement::CanPlayChanged(int32_t canPlay)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLAudioElement::WindowVolumeChanged()
|
||||
{
|
||||
return HTMLMediaElement::WindowVolumeChanged();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLAudioElement::Notify(nsITimer* aTimer)
|
||||
{
|
||||
|
@ -1729,6 +1729,14 @@ void HTMLMediaElement::SetVolumeInternal()
|
||||
float effectiveVolume = mMuted ? 0.0f :
|
||||
mAudioChannelFaded ? float(mVolume) * FADED_VOLUME_RATIO : float(mVolume);
|
||||
|
||||
if (mAudioChannelAgent) {
|
||||
float volume;
|
||||
nsresult rv = mAudioChannelAgent->GetWindowVolume(&volume);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
effectiveVolume *= volume;
|
||||
}
|
||||
}
|
||||
|
||||
if (mDecoder) {
|
||||
mDecoder->SetVolume(effectiveVolume);
|
||||
} else if (mAudioStream) {
|
||||
@ -3921,6 +3929,12 @@ NS_IMETHODIMP HTMLMediaElement::CanPlayChanged(int32_t canPlay)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP HTMLMediaElement::WindowVolumeChanged()
|
||||
{
|
||||
SetVolumeInternal();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute TextTrackList textTracks; */
|
||||
TextTrackList*
|
||||
HTMLMediaElement::TextTracks() const
|
||||
|
@ -64,8 +64,6 @@ NS_IMPL_RELEASE_INHERITED(AudioContext, nsDOMEventTargetHelper)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(AudioContext)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
||||
|
||||
static uint8_t gWebAudioOutputKey;
|
||||
|
||||
static float GetSampleRateForAudioContext(bool aIsOffline, float aSampleRate)
|
||||
{
|
||||
if (aIsOffline) {
|
||||
@ -95,7 +93,6 @@ AudioContext::AudioContext(nsPIDOMWindow* aWindow,
|
||||
// bound to the window.
|
||||
mDestination = new AudioDestinationNode(this, aIsOffline, aNumberOfChannels,
|
||||
aLength, aSampleRate);
|
||||
mDestination->Stream()->AddAudioOutput(&gWebAudioOutputKey);
|
||||
// We skip calling SetIsOnlyNodeForContext during mDestination's constructor,
|
||||
// because we can only call SetIsOnlyNodeForContext after mDestination has
|
||||
// been set up.
|
||||
|
@ -23,6 +23,8 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static uint8_t gWebAudioOutputKey;
|
||||
|
||||
class OfflineDestinationNodeEngine : public AudioNodeEngine
|
||||
{
|
||||
public:
|
||||
@ -233,6 +235,7 @@ AudioDestinationNode::AudioDestinationNode(AudioContext* aContext,
|
||||
|
||||
mStream = graph->CreateAudioNodeStream(engine, MediaStreamGraph::EXTERNAL_STREAM);
|
||||
mStream->AddMainThreadListener(this);
|
||||
mStream->AddAudioOutput(&gWebAudioOutputKey);
|
||||
|
||||
if (!aIsOffline && UseAudioChannelService()) {
|
||||
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner());
|
||||
@ -380,6 +383,23 @@ AudioDestinationNode::CanPlayChanged(int32_t aCanPlay)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AudioDestinationNode::WindowVolumeChanged()
|
||||
{
|
||||
MOZ_ASSERT(mAudioChannelAgent);
|
||||
|
||||
if (!mStream) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
float volume;
|
||||
nsresult rv = mAudioChannelAgent->GetWindowVolume(&volume);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mStream->SetAudioOutputVolume(&gWebAudioOutputKey, volume);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
AudioChannel
|
||||
AudioDestinationNode::MozAudioChannelType() const
|
||||
{
|
||||
|
@ -38,6 +38,7 @@ public:
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioDestinationNode, AudioNode)
|
||||
NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
||||
@ -61,9 +62,6 @@ public:
|
||||
// nsIDOMEventListener
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
||||
|
||||
// nsIAudioChannelAgentCallback
|
||||
NS_IMETHOD CanPlayChanged(int32_t aCanPlay);
|
||||
|
||||
AudioChannel MozAudioChannelType() const;
|
||||
void SetMozAudioChannelType(AudioChannel aValue, ErrorResult& aRv);
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "AudioChannelCommon.h"
|
||||
#include "AudioChannelService.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
@ -183,3 +184,29 @@ AudioChannelAgent::GetCallback()
|
||||
}
|
||||
return callback.forget();
|
||||
}
|
||||
|
||||
void
|
||||
AudioChannelAgent::WindowVolumeChanged()
|
||||
{
|
||||
nsCOMPtr<nsIAudioChannelAgentCallback> callback = GetCallback();
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback->WindowVolumeChanged();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AudioChannelAgent::GetWindowVolume(float* aVolume)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aVolume);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mWindow);
|
||||
if (!win) {
|
||||
*aVolume = 1.0f;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*aVolume = win->GetAudioGlobalVolume();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -34,6 +34,13 @@ public:
|
||||
AudioChannelAgent();
|
||||
virtual void NotifyAudioChannelStateChanged();
|
||||
|
||||
void WindowVolumeChanged();
|
||||
|
||||
nsIDOMWindow* Window() const
|
||||
{
|
||||
return mWindow;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual ~AudioChannelAgent();
|
||||
|
||||
|
@ -780,3 +780,44 @@ AudioChannelService::GetInternalType(AudioChannelType aType,
|
||||
|
||||
MOZ_CRASH("unexpected audio channel type");
|
||||
}
|
||||
|
||||
struct RefreshAgentsVolumeData
|
||||
{
|
||||
RefreshAgentsVolumeData(nsPIDOMWindow* aWindow)
|
||||
: mWindow(aWindow)
|
||||
{}
|
||||
|
||||
nsPIDOMWindow* mWindow;
|
||||
nsTArray<nsRefPtr<AudioChannelAgent>> mAgents;
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
AudioChannelService::RefreshAgentsVolumeEnumerator(AudioChannelAgent* aAgent,
|
||||
AudioChannelAgentData* aUnused,
|
||||
void* aPtr)
|
||||
{
|
||||
MOZ_ASSERT(aAgent);
|
||||
RefreshAgentsVolumeData* data = static_cast<RefreshAgentsVolumeData*>(aPtr);
|
||||
MOZ_ASSERT(data);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aAgent->Window());
|
||||
if (window && !window->IsInnerWindow()) {
|
||||
window = window->GetCurrentInnerWindow();
|
||||
}
|
||||
|
||||
if (window == data->mWindow) {
|
||||
data->mAgents.AppendElement(aAgent);
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
void
|
||||
AudioChannelService::RefreshAgentsVolume(nsPIDOMWindow* aWindow)
|
||||
{
|
||||
RefreshAgentsVolumeData data(aWindow);
|
||||
mAgents.EnumerateRead(RefreshAgentsVolumeEnumerator, &data);
|
||||
|
||||
for (uint32_t i = 0; i < data.mAgents.Length(); ++i) {
|
||||
data.mAgents[i]->WindowVolumeChanged();
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include "AudioChannelAgent.h"
|
||||
#include "nsClassHashtable.h"
|
||||
|
||||
class nsPIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
@ -85,6 +87,8 @@ public:
|
||||
|
||||
bool AnyAudioChannelIsActive();
|
||||
|
||||
void RefreshAgentsVolume(nsPIDOMWindow* aWindow);
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
void RegisterSpeakerManager(SpeakerManagerService* aSpeakerManager)
|
||||
{
|
||||
@ -179,6 +183,11 @@ protected:
|
||||
NotifyEnumerator(AudioChannelAgent* aAgent,
|
||||
AudioChannelAgentData* aData, void *aUnused);
|
||||
|
||||
static PLDHashOperator
|
||||
RefreshAgentsVolumeEnumerator(AudioChannelAgent* aAgent,
|
||||
AudioChannelAgentData* aUnused,
|
||||
void *aPtr);
|
||||
|
||||
nsClassHashtable< nsPtrHashKey<AudioChannelAgent>, AudioChannelAgentData > mAgents;
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsTArray<SpeakerManagerService*> mSpeakerManager;
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
interface nsIDOMWindow;
|
||||
|
||||
[function, scriptable, uuid(86975108-cd78-4796-8fc8-6cd777cd6eba)]
|
||||
[scriptable, uuid(194b55d9-39c0-45c6-b8ef-b8049f978ea5)]
|
||||
interface nsIAudioChannelAgentCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -19,6 +19,11 @@ interface nsIAudioChannelAgentCallback : nsISupports
|
||||
* it is faded state then the volume of media should be reduced.
|
||||
*/
|
||||
void canPlayChanged(in long canPlay);
|
||||
|
||||
/**
|
||||
* Notified when the window volume/mute is changed
|
||||
*/
|
||||
void windowVolumeChanged();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -35,7 +40,7 @@ interface nsIAudioChannelAgentCallback : nsISupports
|
||||
* 1. Changes to the playable status of this channel.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(86ef883d-9cec-4c04-994f-5de198286e7c)]
|
||||
[scriptable, uuid(2b0222a5-8f7b-49d2-9ab8-cd01b744b23e)]
|
||||
interface nsIAudioChannelAgent : nsISupports
|
||||
{
|
||||
const long AUDIO_AGENT_CHANNEL_NORMAL = 0;
|
||||
@ -128,5 +133,10 @@ interface nsIAudioChannelAgent : nsISupports
|
||||
* True if the window associated with the agent is visible.
|
||||
*/
|
||||
void setVisibilityState(in boolean visible);
|
||||
|
||||
/**
|
||||
* Retrieve the volume from the window.
|
||||
*/
|
||||
readonly attribute float windowVolume;
|
||||
};
|
||||
|
||||
|
@ -104,6 +104,11 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP WindowVolumeChanged()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult GetCanPlay(AudioChannelState *_ret)
|
||||
{
|
||||
int loop = 0;
|
||||
|
@ -3732,3 +3732,53 @@ nsDOMWindowUtils::GetOMTAOrComputedStyle(nsIDOMElement* aElement,
|
||||
return style->GetPropertyValue(aProperty, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::GetAudioMuted(bool* aMuted)
|
||||
{
|
||||
if (!nsContentUtils::IsCallerChrome()) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
|
||||
NS_ENSURE_STATE(window);
|
||||
|
||||
*aMuted = window->GetAudioMuted();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::SetAudioMuted(bool aMuted)
|
||||
{
|
||||
if (!nsContentUtils::IsCallerChrome()) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
|
||||
NS_ENSURE_STATE(window);
|
||||
|
||||
window->SetAudioMuted(aMuted);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::GetAudioVolume(float* aVolume)
|
||||
{
|
||||
if (!nsContentUtils::IsCallerChrome()) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
|
||||
NS_ENSURE_STATE(window);
|
||||
|
||||
*aVolume = window->GetAudioVolume();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::SetAudioVolume(float aVolume)
|
||||
{
|
||||
if (!nsContentUtils::IsCallerChrome()) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
|
||||
NS_ENSURE_STATE(window);
|
||||
|
||||
return window->SetAudioVolume(aVolume);
|
||||
}
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Debug.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "AudioChannelService.h"
|
||||
|
||||
// Interfaces Needed
|
||||
#include "nsIFrame.h"
|
||||
@ -564,6 +565,7 @@ nsPIDOMWindow::nsPIDOMWindow(nsPIDOMWindow *aOuterWindow)
|
||||
mMayHavePointerEnterLeaveEventListener(false),
|
||||
mIsModalContentWindow(false),
|
||||
mIsActive(false), mIsBackground(false),
|
||||
mAudioMuted(false), mAudioVolume(1.0),
|
||||
mInnerWindow(nullptr), mOuterWindow(aOuterWindow),
|
||||
// Make sure no actual window ends up with mWindowID == 0
|
||||
mWindowID(++gNextWindowID), mHasNotifiedGlobalCreated(false),
|
||||
@ -3582,6 +3584,100 @@ nsPIDOMWindow::CreatePerformanceObjectIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsPIDOMWindow::GetAudioMuted() const
|
||||
{
|
||||
if (!IsInnerWindow()) {
|
||||
return mInnerWindow->GetAudioMuted();
|
||||
}
|
||||
|
||||
return mAudioMuted;
|
||||
}
|
||||
|
||||
void
|
||||
nsPIDOMWindow::SetAudioMuted(bool aMuted)
|
||||
{
|
||||
if (!IsInnerWindow()) {
|
||||
mInnerWindow->SetAudioMuted(aMuted);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mAudioMuted == aMuted) {
|
||||
return;
|
||||
}
|
||||
|
||||
mAudioMuted = aMuted;
|
||||
RefreshMediaElements();
|
||||
}
|
||||
|
||||
float
|
||||
nsPIDOMWindow::GetAudioVolume() const
|
||||
{
|
||||
if (!IsInnerWindow()) {
|
||||
return mInnerWindow->GetAudioVolume();
|
||||
}
|
||||
|
||||
return mAudioVolume;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPIDOMWindow::SetAudioVolume(float aVolume)
|
||||
{
|
||||
if (!IsInnerWindow()) {
|
||||
return mInnerWindow->SetAudioVolume(aVolume);
|
||||
}
|
||||
|
||||
if (aVolume < 0.0) {
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
}
|
||||
|
||||
if (mAudioVolume == aVolume) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mAudioVolume = aVolume;
|
||||
RefreshMediaElements();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
float
|
||||
nsPIDOMWindow::GetAudioGlobalVolume()
|
||||
{
|
||||
float globalVolume = 1.0;
|
||||
nsCOMPtr<nsPIDOMWindow> window = this;
|
||||
|
||||
do {
|
||||
if (window->GetAudioMuted()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
globalVolume *= window->GetAudioVolume();
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> win;
|
||||
window->GetParent(getter_AddRefs(win));
|
||||
if (window == win) {
|
||||
break;
|
||||
}
|
||||
|
||||
window = do_QueryInterface(win);
|
||||
|
||||
// If there is not parent, or we are the toplevel or the volume is
|
||||
// already 0.0, we don't continue.
|
||||
} while (window && window != this && globalVolume);
|
||||
|
||||
return globalVolume;
|
||||
}
|
||||
|
||||
void
|
||||
nsPIDOMWindow::RefreshMediaElements()
|
||||
{
|
||||
nsRefPtr<AudioChannelService> service =
|
||||
AudioChannelService::GetAudioChannelService();
|
||||
if (service) {
|
||||
service->RefreshAgentsVolume(this);
|
||||
}
|
||||
}
|
||||
|
||||
// nsISpeechSynthesisGetter
|
||||
|
||||
#ifdef MOZ_WEBSPEECH
|
||||
|
@ -190,11 +190,23 @@ public:
|
||||
|
||||
virtual NS_HIDDEN_(bool) IsRunningTimeout() = 0;
|
||||
|
||||
// Audio API
|
||||
bool GetAudioMuted() const;
|
||||
void SetAudioMuted(bool aMuted);
|
||||
|
||||
float GetAudioVolume() const;
|
||||
nsresult SetAudioVolume(float aVolume);
|
||||
|
||||
float GetAudioGlobalVolume();
|
||||
|
||||
protected:
|
||||
// Lazily instantiate an about:blank document if necessary, and if
|
||||
// we have what it takes to do so.
|
||||
void MaybeCreateDoc();
|
||||
|
||||
float GetAudioGlobalVolumeInternal(float aVolume);
|
||||
void RefreshMediaElements();
|
||||
|
||||
public:
|
||||
// Internal getter/setter for the frame element, this version of the
|
||||
// getter crosses chrome boundaries whereas the public scriptable
|
||||
@ -768,6 +780,9 @@ protected:
|
||||
// "active". Only used on outer windows.
|
||||
bool mIsBackground;
|
||||
|
||||
bool mAudioMuted;
|
||||
float mAudioVolume;
|
||||
|
||||
// And these are the references between inner and outer windows.
|
||||
nsPIDOMWindow *mInnerWindow;
|
||||
nsCOMPtr<nsPIDOMWindow> mOuterWindow;
|
||||
|
@ -8,6 +8,7 @@ support-files =
|
||||
|
||||
[test_Image_constructor.html]
|
||||
[test_appname_override.html]
|
||||
[test_audioWindowUtils.html]
|
||||
[test_bug913761.html]
|
||||
[test_bug978522.html]
|
||||
[test_bug979109.html]
|
||||
|
92
dom/base/test/test_audioWindowUtils.html
Normal file
92
dom/base/test/test_audioWindowUtils.html
Normal file
@ -0,0 +1,92 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for audio controller in windows</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="about:blank" id="iframe"></iframe>
|
||||
<script type="application/javascript">
|
||||
|
||||
function runTest() {
|
||||
var utils = SpecialPowers.wrap(window).
|
||||
QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor).
|
||||
getInterface(SpecialPowers.Ci.nsIDOMWindowUtils);
|
||||
ok(utils, "nsIDOMWindowUtils");
|
||||
|
||||
is(utils.audioMuted, false, "By default utils.audioMuted is false");
|
||||
utils.audioMuted = true;
|
||||
is(utils.audioMuted, true, "utils.audioMuted is true");
|
||||
utils.audioMuted = false;
|
||||
is(utils.audioMuted, false, "utils.audioMuted is true");
|
||||
|
||||
is(utils.audioVolume, 1.0, "By default utils.audioVolume is 1.0");
|
||||
utils.audioVolume = 0.4;
|
||||
is(utils.audioVolume.toFixed(2), 0.4, "utils.audioVolume is ok");
|
||||
utils.audioMuted = true;
|
||||
is(utils.audioMuted, true, "utils.audioMuted is true");
|
||||
is(utils.audioVolume.toFixed(2), 0.4, "utils.audioVolume is ok");
|
||||
utils.audioMuted = false;
|
||||
|
||||
utils.audioVolume = 2.0;
|
||||
is(utils.audioVolume, 2.0, "utils.audioVolume is ok");
|
||||
|
||||
try {
|
||||
utils.audioVolume = -42;
|
||||
ok(false, "This should throw");
|
||||
} catch(e) {
|
||||
ok(true, "This should throw");
|
||||
}
|
||||
|
||||
utils.audioVolume = 0;
|
||||
is(utils.audioVolume, 0.0, "utils.audioVolume is ok");
|
||||
utils.audioVolume = 1.0;
|
||||
is(utils.audioVolume, 1.0, "utils.audioVolume is ok");
|
||||
|
||||
var iframe = document.getElementById("iframe");
|
||||
ok(iframe, "IFrame exists");
|
||||
|
||||
utils = SpecialPowers.wrap(iframe.contentWindow).
|
||||
QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor).
|
||||
getInterface(SpecialPowers.Ci.nsIDOMWindowUtils);
|
||||
ok(utils, "nsIDOMWindowUtils");
|
||||
|
||||
is(utils.audioMuted, false, "By default utils.audioMuted is false");
|
||||
utils.audioMuted = true;
|
||||
is(utils.audioMuted, true, "utils.audioMuted is true");
|
||||
utils.audioMuted = false;
|
||||
is(utils.audioMuted, false, "utils.audioMuted is true");
|
||||
|
||||
is(utils.audioVolume, 1.0, "By default utils.audioVolume is 1.0");
|
||||
utils.audioVolume = 0.4;
|
||||
is(utils.audioVolume.toFixed(2), 0.4, "utils.audioVolume is ok");
|
||||
utils.audioMuted = true;
|
||||
is(utils.audioMuted, true, "utils.audioMuted is true");
|
||||
is(utils.audioVolume.toFixed(2), 0.4, "utils.audioVolume is ok");
|
||||
utils.audioMuted = false;
|
||||
|
||||
utils.audioVolume = 2.0;
|
||||
is(utils.audioVolume, 2.0, "utils.audioVolume is ok");
|
||||
|
||||
try {
|
||||
utils.audioVolume = -42;
|
||||
ok(false, "This should throw");
|
||||
} catch(e) {
|
||||
ok(true, "This should throw");
|
||||
}
|
||||
|
||||
utils.audioVolume = 0;
|
||||
is(utils.audioVolume, 0.0, "utils.audioVolume is ok");
|
||||
utils.audioVolume = 1.0;
|
||||
is(utils.audioVolume, 1.0, "utils.audioVolume is ok");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv({ "set": [["media.useAudioChannelService", true]]}, runTest);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -389,6 +389,12 @@ FMRadio::CanPlayChanged(int32_t aCanPlay)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FMRadio::WindowVolumeChanged(float aVolume)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
void
|
||||
FMRadio::SetCanPlay(bool aCanPlay)
|
||||
{
|
||||
|
@ -34,6 +34,7 @@ public:
|
||||
FMRadio();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK
|
||||
|
||||
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper)
|
||||
|
||||
@ -82,9 +83,6 @@ public:
|
||||
IMPL_EVENT_HANDLER(antennaavailablechange);
|
||||
IMPL_EVENT_HANDLER(frequencychange);
|
||||
|
||||
// nsIAudioChannelAgentCallback
|
||||
NS_IMETHOD CanPlayChanged(int32_t aCanPlay);
|
||||
|
||||
// nsIDOMEventListener
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
||||
|
||||
|
@ -43,7 +43,7 @@ interface nsIDOMEventTarget;
|
||||
interface nsIRunnable;
|
||||
interface nsICompositionStringSynthesizer;
|
||||
|
||||
[scriptable, uuid(27efada9-b8ea-4d70-a2e6-f46b9ba905f4)]
|
||||
[scriptable, uuid(ef70a299-033c-4adc-b214-6649aed9d828)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
@ -1582,4 +1582,17 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
*/
|
||||
AString getOMTAOrComputedStyle(in nsIDOMElement aElement,
|
||||
in AString aProperty);
|
||||
|
||||
/**
|
||||
* With this it's possible to mute all the MediaElements in this window.
|
||||
* We have audioMuted and audioVolume to preserve the volume across
|
||||
* mute/umute.
|
||||
*/
|
||||
attribute boolean audioMuted;
|
||||
|
||||
/**
|
||||
* range: greater or equal to 0. The real volume level is affected by the
|
||||
* volume of all ancestor windows.
|
||||
*/
|
||||
attribute float audioVolume;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user