Backed out changeset d09b20eeb382 (bug 1242874)

This commit is contained in:
Carsten "Tomcat" Book
2016-04-28 13:59:04 +02:00
parent 30fc4c7852
commit e47f7c80c9
13 changed files with 150 additions and 371 deletions

View File

@@ -223,16 +223,11 @@ NS_IMETHODIMP AudioChannelAgent::NotifyStartedPlaying(float *aVolume,
service->RegisterAudioChannelAgent(this,
static_cast<AudioChannel>(mAudioChannelType));
AudioPlaybackConfig config = service->GetMediaConfig(mWindow,
mAudioChannelType);
service->GetState(mWindow, mAudioChannelType, aVolume, aMuted);
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("AudioChannelAgent, NotifyStartedPlaying, this = %p, "
"mute = %d, volume = %f, suspend = %d\n", this,
config.mMuted, config.mVolume, config.mSuspend));
*aVolume = config.mVolume;
*aMuted = config.mMuted;
("AudioChannelAgent, NotifyStartedPlaying, this = %p, mute = %d, "
"volume = %f\n", this, *aMuted, *aVolume));
mIsRegToService = true;
return NS_OK;
@@ -275,49 +270,19 @@ AudioChannelAgent::WindowVolumeChanged()
return;
}
AudioPlaybackConfig config = GetMediaConfig();
float volume = 1.0;
bool muted = false;
RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
if (service) {
service->GetState(mWindow, mAudioChannelType, &volume, &muted);
}
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("AudioChannelAgent, WindowVolumeChanged, this = %p, mute = %d, "
"volume = %f\n", this, config.mMuted, config.mVolume));
"volume = %f\n", this, muted, volume));
callback->WindowVolumeChanged(config.mVolume, config.mMuted);
}
void
AudioChannelAgent::WindowSuspendChanged(nsSuspendedTypes aSuspend)
{
nsCOMPtr<nsIAudioChannelAgentCallback> callback = GetCallback();
if (!callback) {
return;
}
if (!IsDisposableSuspend(aSuspend)) {
aSuspend = GetMediaConfig().mSuspend;
}
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("AudioChannelAgent, WindowSuspendChanged, this = %p, "
"suspended = %d\n", this, aSuspend));
callback->WindowSuspendChanged(aSuspend);
}
AudioPlaybackConfig
AudioChannelAgent::GetMediaConfig()
{
RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
AudioPlaybackConfig config(1.0, false, nsISuspendedTypes::NONE_SUSPENDED);
if (service) {
config = service->GetMediaConfig(mWindow, mAudioChannelType);
}
return config;
}
bool
AudioChannelAgent::IsDisposableSuspend(nsSuspendedTypes aSuspend) const
{
return (aSuspend == nsISuspendedTypes::SUSPENDED_PAUSE_DISPOSABLE ||
aSuspend == nsISuspendedTypes::SUSPENDED_STOP_DISPOSABLE);
callback->WindowVolumeChanged(volume, muted);
}
uint64_t

View File

@@ -23,8 +23,6 @@ class nsPIDOMWindowOuter;
namespace mozilla {
namespace dom {
class AudioPlaybackConfig;
/* Header file */
class AudioChannelAgent : public nsIAudioChannelAgent
{
@@ -37,7 +35,6 @@ public:
AudioChannelAgent();
void WindowVolumeChanged();
void WindowSuspendChanged(nsSuspendedTypes aSuspend);
void WindowAudioCaptureChanged(uint64_t aInnerWindowID, bool aCapture);
nsPIDOMWindowOuter* Window() const
@@ -51,9 +48,6 @@ public:
private:
virtual ~AudioChannelAgent();
AudioPlaybackConfig GetMediaConfig();
bool IsDisposableSuspend(nsSuspendedTypes aSuspend) const;
// Returns mCallback if that's non-null, or otherwise tries to get an
// nsIAudioChannelAgentCallback out of mWeakCallback.
already_AddRefed<nsIAudioChannelAgentCallback> GetCallback();

View File

@@ -353,22 +353,24 @@ AudioChannelService::UnregisterTabParent(TabParent* aTabParent)
mTabParents.RemoveElement(aTabParent);
}
AudioPlaybackConfig
AudioChannelService::GetMediaConfig(nsPIDOMWindowOuter* aWindow,
uint32_t aAudioChannel) const
void
AudioChannelService::GetState(nsPIDOMWindowOuter* aWindow, uint32_t aAudioChannel,
float* aVolume, bool* aMuted)
{
MOZ_ASSERT(!aWindow || aWindow->IsOuterWindow());
MOZ_ASSERT(aVolume && aMuted);
MOZ_ASSERT(aAudioChannel < NUMBER_OF_AUDIO_CHANNELS);
AudioPlaybackConfig config(1.0, false,
nsISuspendedTypes::NONE_SUSPENDED);
if (!aWindow || !aWindow->IsOuterWindow()) {
config.SetConfig(0.0, true,
nsISuspendedTypes::SUSPENDED_BLOCK);
return config;
*aVolume = 0.0;
*aMuted = true;
return;
}
*aVolume = 1.0;
*aMuted = false;
AudioChannelWindow* winData = nullptr;
nsCOMPtr<nsPIDOMWindowOuter> window = aWindow;
@@ -377,16 +379,13 @@ AudioChannelService::GetMediaConfig(nsPIDOMWindowOuter* aWindow,
do {
winData = GetWindowData(window->WindowID());
if (winData) {
config.mVolume *= winData->mChannels[aAudioChannel].mVolume;
config.mMuted = config.mMuted || winData->mChannels[aAudioChannel].mMuted;
*aVolume *= winData->mChannels[aAudioChannel].mVolume;
*aMuted = *aMuted || winData->mChannels[aAudioChannel].mMuted;
}
config.mVolume *= window->GetAudioVolume();
config.mMuted = config.mMuted || window->GetAudioMuted();
// If the mSuspend is already suspended, we don't need to set it again.
config.mSuspend = (config.mSuspend == nsISuspendedTypes::NONE_SUSPENDED) ?
window->GetMediaSuspend() : config.mSuspend;
*aVolume *= window->GetAudioVolume();
// TODO : distiguish between suspend and mute, it would be done in bug1242874.
*aMuted = *aMuted || window->GetMediaSuspended() || window->GetAudioMuted();
nsCOMPtr<nsPIDOMWindowOuter> win = window->GetScriptableParentOrNull();
if (!win) {
@@ -397,8 +396,6 @@ AudioChannelService::GetMediaConfig(nsPIDOMWindowOuter* aWindow,
// If there is no parent, or we are the toplevel we don't continue.
} while (window && window != aWindow);
return config;
}
bool
@@ -603,8 +600,7 @@ AudioChannelService::RefreshAgentsVolumeAndPropagate(AudioChannel aAudioChannel,
}
void
AudioChannelService::RefreshAgents(nsPIDOMWindowOuter* aWindow,
mozilla::function<void(AudioChannelAgent*)> aFunc)
AudioChannelService::RefreshAgentsVolume(nsPIDOMWindowOuter* aWindow)
{
MOZ_ASSERT(aWindow);
MOZ_ASSERT(aWindow->IsOuterWindow());
@@ -622,27 +618,10 @@ AudioChannelService::RefreshAgents(nsPIDOMWindowOuter* aWindow,
nsTObserverArray<AudioChannelAgent*>::ForwardIterator
iter(winData->mAgents);
while (iter.HasMore()) {
aFunc(iter.GetNext());
iter.GetNext()->WindowVolumeChanged();
}
}
void
AudioChannelService::RefreshAgentsVolume(nsPIDOMWindowOuter* aWindow)
{
RefreshAgents(aWindow, [] (AudioChannelAgent* agent) {
agent->WindowVolumeChanged();
});
}
void
AudioChannelService::RefreshAgentsSuspend(nsPIDOMWindowOuter* aWindow,
nsSuspendedTypes aSuspend)
{
RefreshAgents(aWindow, [aSuspend] (AudioChannelAgent* agent) {
agent->WindowSuspendChanged(aSuspend);
});
}
void
AudioChannelService::SetWindowAudioCaptured(nsPIDOMWindowOuter* aWindow,
uint64_t aInnerWindowID,

View File

@@ -16,7 +16,6 @@
#include "AudioChannelAgent.h"
#include "nsAttrValue.h"
#include "mozilla/dom/AudioChannelBinding.h"
#include "mozilla/Function.h"
class nsIRunnable;
class nsPIDOMWindowOuter;
@@ -33,33 +32,6 @@ class TabParent;
#define NUMBER_OF_AUDIO_CHANNELS (uint32_t)AudioChannel::EndGuard_
class AudioPlaybackConfig
{
public:
AudioPlaybackConfig()
: mVolume(1.0)
, mMuted(false)
, mSuspend(nsISuspendedTypes::NONE_SUSPENDED)
{}
AudioPlaybackConfig(float aVolume, bool aMuted, uint32_t aSuspended)
: mVolume(aVolume)
, mMuted(aMuted)
, mSuspend(aSuspended)
{}
void SetConfig(float aVolume, bool aMuted, uint32_t aSuspended)
{
mVolume = aVolume;
mMuted = aMuted;
mSuspend = aSuspended;
}
float mVolume;
bool mMuted;
uint32_t mSuspend;
};
class AudioChannelService final : public nsIAudioChannelService
, public nsIObserver
{
@@ -100,10 +72,10 @@ public:
/**
* Return the state to indicate this audioChannel for his window should keep
* playing/muted/suspended.
* playing/muted.
*/
AudioPlaybackConfig GetMediaConfig(nsPIDOMWindowOuter* aWindow,
uint32_t aAudioChannel) const;
void GetState(nsPIDOMWindowOuter* aWindow, uint32_t aChannel,
float* aVolume, bool* aMuted);
/* Methods for the BrowserElementAudioChannel */
float GetAudioChannelVolume(nsPIDOMWindowOuter* aWindow, AudioChannel aChannel);
@@ -142,8 +114,6 @@ public:
bool AnyAudioChannelIsActive();
void RefreshAgentsVolume(nsPIDOMWindowOuter* aWindow);
void RefreshAgentsSuspend(nsPIDOMWindowOuter* aWindow,
nsSuspendedTypes aSuspend);
void RefreshAgentsVolumeAndPropagate(AudioChannel aAudioChannel,
nsPIDOMWindowOuter* aWindow);
@@ -185,9 +155,6 @@ private:
AudioChannelService();
~AudioChannelService();
void RefreshAgents(nsPIDOMWindowOuter* aWindow,
mozilla::function<void(AudioChannelAgent*)> aFunc);
static void CreateServiceIfNeeded();
/**
@@ -203,15 +170,17 @@ private:
void SetDefaultVolumeControlChannelInternal(int32_t aChannel,
bool aVisible, uint64_t aChildID);
class AudioChannelConfig final : public AudioPlaybackConfig
struct AudioChannelConfig final
{
public:
AudioChannelConfig()
: AudioPlaybackConfig(1.0, IsAudioChannelMutedByDefault(),
nsISuspendedTypes::NONE_SUSPENDED)
: mVolume(1.0)
, mMuted(IsAudioChannelMutedByDefault())
, mNumberOfAgents(0)
{}
float mVolume;
bool mMuted;
uint32_t mNumberOfAgents;
};

View File

@@ -3796,7 +3796,7 @@ nsPIDOMWindowOuter::RefreshMediaElementsSuspend(SuspendTypes aSuspend)
{
RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
if (service) {
service->RefreshAgentsSuspend(GetOuterWindow(), aSuspend);
// TODO : Impelement in next patch.
}
}

View File

@@ -463,16 +463,15 @@ FMRadio::EnableAudioChannelAgent()
NS_IMETHODIMP
FMRadio::WindowVolumeChanged(float aVolume, bool aMuted)
{
// TODO : Not support to change volume now, so we just close it.
IFMRadioService::Singleton()->EnableAudio(!aMuted);
// TODO: what about the volume?
return NS_OK;
}
NS_IMETHODIMP
FMRadio::WindowSuspendChanged(nsSuspendedTypes aSuspend)
{
bool enable = (aSuspend == nsISuspendedTypes::NONE_SUSPENDED);
IFMRadioService::Singleton()->EnableAudio(enable);
// TODO : implementation.
return NS_OK;
}

View File

@@ -1162,6 +1162,11 @@ static bool IsAutoplayEnabled()
return Preferences::GetBool("media.autoplay.enabled");
}
static bool UseAudioChannelAPI()
{
return Preferences::GetBool("media.useAudioChannelAPI");
}
void HTMLMediaElement::UpdatePreloadAction()
{
PreloadAction nextAction = PRELOAD_UNDEFINED;
@@ -2239,7 +2244,6 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
mAutoplayEnabled(true),
mPaused(true),
mMuted(0),
mAudioChannelSuspended(nsISuspendedTypes::NONE_SUSPENDED),
mStatsShowing(false),
mAllowCasting(false),
mIsCasting(false),
@@ -2391,7 +2395,20 @@ HTMLMediaElement::Play(ErrorResult& aRv)
nsresult
HTMLMediaElement::PlayInternal(bool aCallerIsChrome)
{
if (!IsAllowedToPlay()) {
// Prevent media element from being auto-started by a script when
// media.autoplay.enabled=false
if (!mHasUserInteraction
&& !IsAutoplayEnabled()
&& !EventStateManager::IsHandlingUserInput()
&& !aCallerIsChrome) {
LOG(LogLevel::Debug, ("%p Blocked attempt to autoplay media.", this));
#if defined(MOZ_WIDGET_ANDROID)
nsContentUtils::DispatchTrustedEvent(OwnerDoc(),
static_cast<nsIContent*>(this),
NS_LITERAL_STRING("MozAutoplayMediaBlocked"),
false,
false);
#endif
return NS_OK;
}
@@ -2456,8 +2473,6 @@ HTMLMediaElement::PlayInternal(bool aCallerIsChrome)
mPaused = false;
mAutoplaying = false;
SetAudioChannelSuspended(nsISuspendedTypes::NONE_SUSPENDED);
// We changed mPaused and mAutoplaying which can affect AddRemoveSelfReference
// and our preload status.
AddRemoveSelfReference();
@@ -4523,7 +4538,12 @@ bool HTMLMediaElement::IsBeingDestroyed()
void HTMLMediaElement::NotifyOwnerDocumentActivityChanged()
{
bool pauseElement = NotifyOwnerDocumentActivityChangedInternal();
if (pauseElement && mAudioChannelAgent) {
if (pauseElement && mAudioChannelAgent &&
// On B2G, NotifyOwnerDocumentActivityChangedInternal may return true for
// two reasons: the document no longer being active, or the element being
// paused by the audio channel. However we are only interested in the
// first case here, so we need to filter out the second case.
(!UseAudioChannelAPI() || !ComputedMuted())) {
// If the element is being paused since we are navigating away from the
// document, notify the audio channel agent.
// Be careful to ignore this event during a docshell frame swap.
@@ -4547,6 +4567,14 @@ HTMLMediaElement::NotifyOwnerDocumentActivityChangedInternal()
}
bool pauseElement = !IsActive();
// Only pause the element when we start playing. If we pause without playing
// audio, the resource loading would be affected unexpectedly. For example,
// the media element is muted by default, but we don't want this behavior
// interrupting the loading process.
if (UseAudioChannelAPI() && mAudioChannelAgent) {
pauseElement |= ComputedMuted();
}
SuspendOrResumeElement(pauseElement, !IsActive());
if (!mPausedForInactiveDocumentOrChannel &&
@@ -4960,6 +4988,33 @@ ImageContainer* HTMLMediaElement::GetImageContainer()
return container ? container->GetImageContainer() : nullptr;
}
nsresult HTMLMediaElement::UpdateChannelMuteState(float aVolume, bool aMuted)
{
if (mAudioChannelVolume != aVolume) {
mAudioChannelVolume = aVolume;
SetVolumeInternal();
}
// We have to mute this channel.
if (aMuted && !ComputedMuted()) {
SetMutedInternal(mMuted | MUTED_BY_AUDIO_CHANNEL);
if (UseAudioChannelAPI()) {
DispatchAsyncEvent(NS_LITERAL_STRING("mozinterruptbegin"));
}
} else if (!aMuted && ComputedMuted()) {
SetMutedInternal(mMuted & ~MUTED_BY_AUDIO_CHANNEL);
if (UseAudioChannelAPI()) {
DispatchAsyncEvent(NS_LITERAL_STRING("mozinterruptend"));
}
}
if (UseAudioChannelAPI()) {
SuspendOrResumeElement(ComputedMuted(), false);
}
return NS_OK;
}
bool
HTMLMediaElement::MaybeCreateAudioChannelAgent()
{
@@ -4980,11 +5035,6 @@ HTMLMediaElement::MaybeCreateAudioChannelAgent()
bool
HTMLMediaElement::IsPlayingThroughTheAudioChannel() const
{
// It might be resumed from remote, we should keep the audio channel agent.
if (IsSuspendedByAudioChannel()) {
return true;
}
// Are we paused or muted
if (mPaused || Muted()) {
return false;
@@ -5071,176 +5121,26 @@ HTMLMediaElement::NotifyAudioChannelAgent(bool aPlaying)
}
}
NS_IMETHODIMP
HTMLMediaElement::WindowVolumeChanged(float aVolume, bool aMuted)
NS_IMETHODIMP HTMLMediaElement::WindowVolumeChanged(float aVolume, bool aMuted)
{
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("HTMLMediaElement, WindowVolumeChanged, this = %p, "
"aVolume = %f, aMuted = %d\n", this, aVolume, aMuted));
MOZ_ASSERT(NS_IsMainThread());
if (mAudioChannelVolume != aVolume) {
mAudioChannelVolume = aVolume;
SetVolumeInternal();
}
UpdateChannelMuteState(aVolume, aMuted);
if (aMuted && !ComputedMuted()) {
SetMutedInternal(mMuted | MUTED_BY_AUDIO_CHANNEL);
} else if (!aMuted && ComputedMuted()) {
SetMutedInternal(mMuted & ~MUTED_BY_AUDIO_CHANNEL);
if (UseAudioChannelAPI()) {
mPaused.SetCanPlay(!aMuted);
}
return NS_OK;
}
NS_IMETHODIMP
HTMLMediaElement::WindowSuspendChanged(SuspendTypes aSuspend)
HTMLMediaElement::WindowSuspendChanged(nsSuspendedTypes aSuspend)
{
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("HTMLMediaElement, WindowSuspendChanged, this = %p, "
"aSuspend = %d\n", this, aSuspend));
switch (aSuspend) {
case nsISuspendedTypes::NONE_SUSPENDED:
ResumeFromAudioChannel();
break;
case nsISuspendedTypes::SUSPENDED_PAUSE:
case nsISuspendedTypes::SUSPENDED_PAUSE_DISPOSABLE:
PauseByAudioChannel(aSuspend);
break;
case nsISuspendedTypes::SUSPENDED_BLOCK:
BlockByAudioChannel();
break;
case nsISuspendedTypes::SUSPENDED_STOP_DISPOSABLE:
Pause();
break;
default:
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("HTMLMediaElement, WindowSuspendChanged, this = %p, "
"Error : unknown suspended type!\n", this));
}
// TODO : implementation.
return NS_OK;
}
void
HTMLMediaElement::ResumeFromAudioChannel()
{
if (!IsSuspendedByAudioChannel()) {
return;
}
switch (mAudioChannelSuspended) {
case nsISuspendedTypes::SUSPENDED_PAUSE:
case nsISuspendedTypes::SUSPENDED_PAUSE_DISPOSABLE:
ResumeFromAudioChannelPaused(mAudioChannelSuspended);
break;
case nsISuspendedTypes::SUSPENDED_BLOCK:
ResumeFromAudioChannelBlocked();
break;
default:
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("HTMLMediaElement, ResumeFromAudioChannel, this = %p, "
"Error : resume without suspended!\n", this));
}
}
void
HTMLMediaElement::ResumeFromAudioChannelPaused(SuspendTypes aSuspend)
{
MOZ_ASSERT(mAudioChannelSuspended == nsISuspendedTypes::SUSPENDED_PAUSE ||
mAudioChannelSuspended == nsISuspendedTypes::SUSPENDED_PAUSE_DISPOSABLE);
SetAudioChannelSuspended(nsISuspendedTypes::NONE_SUSPENDED);
nsresult rv = PlayInternal(nsContentUtils::IsCallerChrome());
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
DispatchAsyncEvent(NS_LITERAL_STRING("mozinterruptend"));
}
void
HTMLMediaElement::ResumeFromAudioChannelBlocked()
{
MOZ_ASSERT(mAudioChannelSuspended == nsISuspendedTypes::SUSPENDED_BLOCK);
SetAudioChannelSuspended(nsISuspendedTypes::NONE_SUSPENDED);
mPaused.SetCanPlay(true);
SuspendOrResumeElement(false /* resume */, false);
}
void
HTMLMediaElement::PauseByAudioChannel(SuspendTypes aSuspend)
{
if (IsSuspendedByAudioChannel()) {
return;
}
SetAudioChannelSuspended(aSuspend);
Pause();
DispatchAsyncEvent(NS_LITERAL_STRING("mozinterruptbegin"));
}
void
HTMLMediaElement::BlockByAudioChannel()
{
if (IsSuspendedByAudioChannel()) {
return;
}
SetAudioChannelSuspended(nsISuspendedTypes::SUSPENDED_BLOCK);
SuspendOrResumeElement(true /* suspend */, false);
mPaused.SetCanPlay(false);
}
void
HTMLMediaElement::SetAudioChannelSuspended(SuspendTypes aSuspend)
{
if (mAudioChannelSuspended == aSuspend) {
return;
}
mAudioChannelSuspended = aSuspend;
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("HTMLMediaElement, SetAudioChannelSuspended, this = %p, "
"aSuspend = %d\n", this, aSuspend));
}
bool
HTMLMediaElement::IsSuspendedByAudioChannel() const
{
return (mAudioChannelSuspended == nsISuspendedTypes::SUSPENDED_PAUSE ||
mAudioChannelSuspended == nsISuspendedTypes::SUSPENDED_PAUSE_DISPOSABLE ||
mAudioChannelSuspended == nsISuspendedTypes::SUSPENDED_BLOCK);
}
bool
HTMLMediaElement::IsAllowedToPlay()
{
// Prevent media element from being auto-started by a script when
// media.autoplay.enabled=false
if (!mHasUserInteraction &&
!IsAutoplayEnabled() &&
!EventStateManager::IsHandlingUserInput() &&
!nsContentUtils::IsCallerChrome()) {
#if defined(MOZ_WIDGET_ANDROID)
nsContentUtils::DispatchTrustedEvent(OwnerDoc(),
static_cast<nsIContent*>(this),
NS_LITERAL_STRING("MozAutoplayMediaBlocked"),
false,
false);
#endif
return false;
}
// The MediaElement can't start playback until it's resumed by audio channel.
if (mAudioChannelSuspended == nsISuspendedTypes::SUSPENDED_PAUSE ||
mAudioChannelSuspended == nsISuspendedTypes::SUSPENDED_BLOCK) {
return false;
}
return true;
}
#ifdef MOZ_EME
MediaKeys*
HTMLMediaElement::GetMediaKeys() const

View File

@@ -37,7 +37,6 @@
typedef uint16_t nsMediaNetworkState;
typedef uint16_t nsMediaReadyState;
typedef uint32_t SuspendTypes;
namespace mozilla {
class DecoderDoctorDiagnostics;
@@ -1115,6 +1114,9 @@ protected:
// Check the permissions for audiochannel.
bool CheckAudioChannelPermissions(const nsAString& aType);
// This method does the check for muting/nmuting the audio channel.
nsresult UpdateChannelMuteState(float aVolume, bool aMuted);
// Seeks to aTime seconds. aSeekType can be Exact to seek to exactly the
// seek target, or PrevSyncPoint if a quicker but less precise seek is
// desired, and we'll seek to the sync point (keyframe and/or start of the
@@ -1149,38 +1151,6 @@ protected:
// channel agent is ready to be used.
bool MaybeCreateAudioChannelAgent();
/**
* We have different kinds of suspended cases,
* - SUSPENDED_PAUSE
* It's used when we temporary lost platform audio focus. MediaElement can
* only be resumed when we gain the audio focus again.
*
* - SUSPENDED_PAUSE_DISPOSABLE
* It's used when user press the pause botton on the remote media-control.
* MediaElement can be resumed by reomte media-control or via play().
*
* - SUSPENDED_BLOCK
* It's used to reduce the power comsuption, we won't play the auto-play
* audio/video in the page we have never visited before. MediaElement would
* be resumed when the page is active. See bug647429 for more details.
*
* - SUSPENDED_STOP_DISPOSABLE
* When we permanently lost platform audio focus, we shuold stop playing
* and stop the audio channel agent. MediaElement can only be restarted by
* play().
*/
void PauseByAudioChannel(SuspendTypes aSuspend);
void BlockByAudioChannel();
void ResumeFromAudioChannel();
void ResumeFromAudioChannelPaused(SuspendTypes aSuspend);
void ResumeFromAudioChannelBlocked();
bool IsSuspendedByAudioChannel() const;
void SetAudioChannelSuspended(SuspendTypes aSuspend);
bool IsAllowedToPlay();
class nsAsyncEventRunner;
using nsGenericHTMLElement::DispatchEvent;
// For nsAsyncEventRunner.
@@ -1400,7 +1370,6 @@ protected:
};
uint32_t mMuted;
SuspendTypes mAudioChannelSuspended;
// True if the media statistics are currently being shown by the builtin
// video controls

View File

@@ -305,6 +305,11 @@ private:
bool mSuspended;
};
static bool UseAudioChannelAPI()
{
return Preferences::GetBool("media.useAudioChannelAPI");
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(AudioDestinationNode, AudioNode,
mAudioChannelAgent,
mOfflineRenderingPromise)
@@ -326,7 +331,7 @@ AudioDestinationNode::AudioDestinationNode(AudioContext* aContext,
, mFramesToProduce(aLength)
, mAudioChannel(AudioChannel::Normal)
, mIsOffline(aIsOffline)
, mAudioChannelSuspended(false)
, mAudioChannelAgentPlaying(false)
, mExtraCurrentTimeSinceLastStartedBlocking(0)
, mExtraCurrentTimeUpdatedSinceLastStableState(false)
, mCaptured(false)
@@ -498,36 +503,38 @@ AudioDestinationNode::StartRendering(Promise* aPromise)
mStream->Graph()->StartNonRealtimeProcessing(mFramesToProduce);
}
void
AudioDestinationNode::SetCanPlay(float aVolume, bool aMuted)
{
if (!mStream) {
return;
}
mStream->SetTrackEnabled(AudioNodeStream::AUDIO_TRACK, !aMuted);
mStream->SetAudioOutputVolume(&gWebAudioOutputKey, aVolume);
}
NS_IMETHODIMP
AudioDestinationNode::WindowVolumeChanged(float aVolume, bool aMuted)
{
if (!mStream) {
return NS_OK;
if (aMuted != mAudioChannelAgentPlaying) {
mAudioChannelAgentPlaying = aMuted;
if (UseAudioChannelAPI()) {
Context()->DispatchTrustedEvent(
!aMuted ? NS_LITERAL_STRING("mozinterruptend")
: NS_LITERAL_STRING("mozinterruptbegin"));
}
}
float volume = aMuted ? 0.0 : aVolume;
mStream->SetAudioOutputVolume(&gWebAudioOutputKey, volume);
SetCanPlay(aVolume, aMuted);
return NS_OK;
}
NS_IMETHODIMP
AudioDestinationNode::WindowSuspendChanged(nsSuspendedTypes aSuspend)
{
if (!mStream) {
return NS_OK;
}
bool suspended = (aSuspend != nsISuspendedTypes::NONE_SUSPENDED);
if (mAudioChannelSuspended == suspended) {
return NS_OK;
}
mAudioChannelSuspended = suspended;
Context()->DispatchTrustedEvent(!suspended ?
NS_LITERAL_STRING("mozinterruptend") :
NS_LITERAL_STRING("mozinterruptbegin"));
mStream->SetTrackEnabled(AudioNodeStream::AUDIO_TRACK, !suspended);
// TODO : implementation.
return NS_OK;
}

View File

@@ -99,6 +99,8 @@ private:
void SetMozAudioChannelType(AudioChannel aValue, ErrorResult& aRv);
bool CheckAudioChannelPermissions(AudioChannel aValue);
void SetCanPlay(float aVolume, bool aMuted);
void NotifyStableState();
void ScheduleStableStateNotification();
@@ -113,7 +115,7 @@ private:
// Audio Channel Type.
AudioChannel mAudioChannel;
bool mIsOffline;
bool mAudioChannelSuspended;
bool mAudioChannelAgentPlaying;
TimeStamp mStartedBlockingDueToBeingOnlyNode;
StreamTime mExtraCurrentTimeSinceLastStartedBlocking;

View File

@@ -736,11 +736,7 @@ nsSpeechTask::WindowVolumeChanged(float aVolume, bool aMuted)
NS_IMETHODIMP
nsSpeechTask::WindowSuspendChanged(nsSuspendedTypes aSuspend)
{
if (aSuspend == nsISuspendedTypes::NONE_SUSPENDED) {
Resume();
} else {
Pause();
}
// TODO : implementation.
return NS_OK;
}

View File

@@ -663,11 +663,12 @@ nsSynthVoiceRegistry::SpeakUtterance(SpeechSynthesisUtterance& aUtterance,
RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
if (service) {
if (nsCOMPtr<nsPIDOMWindowInner> topWindow = aUtterance.GetOwner()) {
// TODO : use audio channel agent, open new bug to fix it.
uint32_t channel = static_cast<uint32_t>(AudioChannelService::GetDefaultAudioChannel());
AudioPlaybackConfig config = service->GetMediaConfig(topWindow->GetOuterWindow(),
channel);
volume = config.mMuted ? 0.0f : config.mVolume * volume;
float audioVolume = 1.0f;
bool muted = false;
service->GetState(topWindow->GetOuterWindow(),
static_cast<uint32_t>(AudioChannelService::GetDefaultAudioChannel()),
&audioVolume, &muted);
volume = muted ? 0.0f : audioVolume * volume;
}
}

View File

@@ -1851,9 +1851,7 @@ nsNPAPIPluginInstance::WindowVolumeChanged(float aVolume, bool aMuted)
NS_IMETHODIMP
nsNPAPIPluginInstance::WindowSuspendChanged(nsSuspendedTypes aSuspend)
{
// It doesn't support suspended, so we just do something like mute/unmute.
WindowVolumeChanged(1.0, /* useless */
aSuspend != nsISuspendedTypes::NONE_SUSPENDED);
// TODO : implementation.
return NS_OK;
}