Bug 872925 - Game pack keeps playing audio when running in the background, even though the app has no permission to do so. r=derf

This commit is contained in:
Andrea Marchesini 2013-05-21 13:49:17 -04:00
parent a22068c80e
commit 8f9cb63b53
3 changed files with 53 additions and 50 deletions

View File

@ -448,7 +448,7 @@ public:
bool Muted() const
{
return mMuted;
return mMuted & MUTED_BY_CONTENT;
}
// XPCOM SetMuted() is OK
@ -786,9 +786,9 @@ protected:
void ProcessMediaFragmentURI();
/**
* Mute or unmute the audio, without changing the value that |muted| reports.
* Mute or unmute the audio and change the value that the |muted| map.
*/
void SetMutedInternal(bool aMuted);
void SetMutedInternal(uint32_t aMuted);
/**
* Suspend (if aPauseForInactiveDocument) or resume element playback and
@ -1009,8 +1009,13 @@ protected:
// 'Pause' method, or playback not yet having started.
WakeLockBoolWrapper mPaused;
// True if the sound is muted.
bool mMuted;
enum MutedReasons {
MUTED_BY_CONTENT = 0x01,
MUTED_BY_INVALID_PLAYBACK_RATE = 0x02,
MUTED_BY_AUDIO_CHANNEL = 0x04
};
uint32_t mMuted;
// True if the sound is being captured.
bool mAudioCaptured;
@ -1093,9 +1098,6 @@ protected:
// Audio Channel Type.
AudioChannelType mAudioChannelType;
// The audiochannel has been suspended.
bool mChannelSuspended;
// Is this media element playing?
bool mPlayingThroughTheAudioChannel;

View File

@ -129,7 +129,7 @@ HTMLAudioElement::MozSetup(uint32_t aChannels, uint32_t aRate, ErrorResult& aRv)
}
MetadataLoaded(aChannels, aRate, true, false, nullptr);
mAudioStream->SetVolume(mVolume);
mAudioStream->SetVolume(mMuted ? 0.0 : mVolume);
}
uint32_t
@ -248,11 +248,12 @@ HTMLAudioElement::CanPlayChanged(bool canPlay)
return HTMLMediaElement::CanPlayChanged(canPlay);
}
#ifdef MOZ_B2G
if (mChannelSuspended == !canPlay) {
return NS_OK;
if (canPlay) {
SetMutedInternal(mMuted & ~MUTED_BY_AUDIO_CHANNEL);
} else {
SetMutedInternal(mMuted | MUTED_BY_AUDIO_CHANNEL);
}
mChannelSuspended = !canPlay;
SetMutedInternal(mChannelSuspended);
#endif
return NS_OK;
}
@ -299,6 +300,7 @@ HTMLAudioElement::UpdateAudioChannelPlayingState()
if (mPlayingThroughTheAudioChannel) {
bool canPlay;
mAudioChannelAgent->StartPlaying(&canPlay);
CanPlayChanged(canPlay);
} else {
mAudioChannelAgent->StopPlaying();
mAudioChannelAgent = nullptr;

View File

@ -1506,15 +1506,8 @@ HTMLMediaElement::SetVolume(double aVolume, ErrorResult& aRv)
mVolume = aVolume;
if (!mMuted) {
if (mDecoder) {
mDecoder->SetVolume(mVolume);
} else if (mAudioStream) {
mAudioStream->SetVolume(mVolume);
} else if (mSrcStream) {
GetSrcMediaStream()->SetAudioOutputVolume(this, float(mVolume));
}
}
// Here we want just to update the volume.
SetMutedInternal(mMuted);
DispatchAsyncEvent(NS_LITERAL_STRING("volumechange"));
}
@ -1683,9 +1676,16 @@ NS_IMETHODIMP HTMLMediaElement::GetMuted(bool* aMuted)
return NS_OK;
}
void HTMLMediaElement::SetMutedInternal(bool aMuted)
void HTMLMediaElement::SetMutedInternal(uint32_t aMuted)
{
float effectiveVolume = aMuted ? 0.0f : float(mVolume);
uint32_t oldMuted = mMuted;
mMuted = aMuted;
if (!!aMuted == !!oldMuted) {
return;
}
float effectiveVolume = mMuted ? 0.0f : float(mVolume);
if (mDecoder) {
mDecoder->SetVolume(effectiveVolume);
@ -1698,11 +1698,11 @@ void HTMLMediaElement::SetMutedInternal(bool aMuted)
NS_IMETHODIMP HTMLMediaElement::SetMuted(bool aMuted)
{
if (aMuted == mMuted)
return NS_OK;
mMuted = aMuted;
SetMutedInternal(aMuted);
if (aMuted) {
SetMutedInternal(mMuted | MUTED_BY_CONTENT);
} else {
SetMutedInternal(mMuted & ~MUTED_BY_CONTENT);
}
DispatchAsyncEvent(NS_LITERAL_STRING("volumechange"));
return NS_OK;
@ -1910,7 +1910,7 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo)
mAutoplaying(true),
mAutoplayEnabled(true),
mPaused(true),
mMuted(false),
mMuted(0),
mAudioCaptured(false),
mPlayingBeforeSeek(false),
mPausedForInactiveDocumentOrChannel(false),
@ -1932,7 +1932,6 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo)
mHasAudio(false),
mDownloadSuspendedByCache(false),
mAudioChannelType(AUDIO_CHANNEL_NORMAL),
mChannelSuspended(false),
mPlayingThroughTheAudioChannel(false)
{
#ifdef PR_LOGGING
@ -2238,8 +2237,9 @@ bool HTMLMediaElement::CheckAudioChannelPermissions(const nsAString& aString)
void HTMLMediaElement::DoneCreatingElement()
{
if (HasAttr(kNameSpaceID_None, nsGkAtoms::muted))
mMuted = true;
if (HasAttr(kNameSpaceID_None, nsGkAtoms::muted)) {
mMuted |= MUTED_BY_CONTENT;
}
}
bool HTMLMediaElement::IsHTMLFocusable(bool aWithMouse,
@ -3278,13 +3278,14 @@ void HTMLMediaElement::SuspendOrResumeElement(bool aPauseElement, bool aSuspendE
void HTMLMediaElement::NotifyOwnerDocumentActivityChanged()
{
nsIDocument* ownerDoc = OwnerDoc();
// SetVisibilityState will update mChannelSuspended via the CanPlayChanged callback.
// SetVisibilityState will update mMuted with MUTED_BY_AUDIO_CHANNEL via the
// CanPlayChanged callback.
if (UseAudioChannelService() && mPlayingThroughTheAudioChannel &&
mAudioChannelAgent) {
mAudioChannelAgent->SetVisibilityState(!ownerDoc->Hidden());
}
bool suspendEvents = !ownerDoc->IsActive() || !ownerDoc->IsVisible();
bool pauseElement = suspendEvents || mChannelSuspended;
bool pauseElement = suspendEvents || (mMuted & MUTED_BY_AUDIO_CHANNEL);
SuspendOrResumeElement(pauseElement, suspendEvents);
@ -3661,14 +3662,12 @@ HTMLMediaElement::SetPlaybackRate(double aPlaybackRate, ErrorResult& aRv)
mPlaybackRate = ClampPlaybackRate(aPlaybackRate);
if (!mMuted) {
if (mPlaybackRate < 0 ||
mPlaybackRate > THRESHOLD_HIGH_PLAYBACKRATE_AUDIO ||
mPlaybackRate < THRESHOLD_LOW_PLAYBACKRATE_AUDIO) {
SetMutedInternal(true);
} else {
SetMutedInternal(false);
}
if (mPlaybackRate < 0 ||
mPlaybackRate > THRESHOLD_HIGH_PLAYBACKRATE_AUDIO ||
mPlaybackRate < THRESHOLD_LOW_PLAYBACKRATE_AUDIO) {
SetMutedInternal(mMuted | MUTED_BY_INVALID_PLAYBACK_RATE);
} else {
SetMutedInternal(mMuted & ~MUTED_BY_INVALID_PLAYBACK_RATE);
}
if (mDecoder) {
@ -3712,16 +3711,16 @@ nsresult HTMLMediaElement::UpdateChannelMuteState(bool aCanPlay)
return NS_OK;
}
// We have to mute this channel:
if (!aCanPlay && !mChannelSuspended) {
mChannelSuspended = true;
// We have to mute this channel.
if (!aCanPlay && !(mMuted & MUTED_BY_AUDIO_CHANNEL)) {
SetMutedInternal(mMuted | MUTED_BY_AUDIO_CHANNEL);
DispatchAsyncEvent(NS_LITERAL_STRING("mozinterruptbegin"));
} else if (aCanPlay && mChannelSuspended) {
mChannelSuspended = false;
} else if (aCanPlay && (mMuted & MUTED_BY_AUDIO_CHANNEL)) {
SetMutedInternal(mMuted & ~MUTED_BY_AUDIO_CHANNEL);
DispatchAsyncEvent(NS_LITERAL_STRING("mozinterruptend"));
}
SuspendOrResumeElement(mChannelSuspended, false);
SuspendOrResumeElement(mMuted & MUTED_BY_AUDIO_CHANNEL, false);
return NS_OK;
}
@ -3753,7 +3752,7 @@ void HTMLMediaElement::UpdateAudioChannelPlayingState()
if (mPlayingThroughTheAudioChannel) {
bool canPlay;
mAudioChannelAgent->StartPlaying(&canPlay);
mPaused.SetCanPlay(canPlay);
CanPlayChanged(canPlay);
} else {
mAudioChannelAgent->StopPlaying();
mAudioChannelAgent = nullptr;