From f44bf80ff91df2548511dd3a3a013eeefb30d7c4 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Mon, 23 Nov 2015 11:35:14 +0000 Subject: [PATCH] Bug 1213154 - tab-sound-icon should be supported by bfcache, r=roc --- .../test/general/browser_audioTabIcon.js | 4 +- dom/html/HTMLMediaElement.cpp | 47 ++++++++++--------- dom/html/HTMLMediaElement.h | 4 +- dom/media/MediaDecoderOwner.h | 4 +- dom/media/gtest/MockMediaDecoderOwner.h | 4 +- dom/media/test/crashtests/crashtests.list | 2 +- 6 files changed, 34 insertions(+), 31 deletions(-) diff --git a/browser/base/content/test/general/browser_audioTabIcon.js b/browser/base/content/test/general/browser_audioTabIcon.js index d3f2b4492b0b..707e5a5b3c23 100644 --- a/browser/base/content/test/general/browser_audioTabIcon.js +++ b/browser/base/content/test/general/browser_audioTabIcon.js @@ -192,7 +192,7 @@ function* test_swapped_browser(oldTab, newBrowser, isPlaying) { }); let AudioPlaybackPromise = new Promise(resolve => { let observer = (subject, topic, data) => { - ok(false, "Should not see an audio-playback notification"); + ok(true, "Should see an audio-playback notification"); }; Services.obs.addObserver(observer, "audio-playback", false); setTimeout(() => { @@ -207,7 +207,7 @@ function* test_swapped_browser(oldTab, newBrowser, isPlaying) { ok(newTab.hasAttribute("muted"), "Expected the correct muted attribute on the new tab"); is(newTab.hasAttribute("soundplaying"), isPlaying, "Expected the correct soundplaying attribute on the new tab"); - // Wait to see if an audio-playback event is dispatched. This should not happen! + // Wait to see if an audio-playback event is dispatched. yield AudioPlaybackPromise; ok(newTab.hasAttribute("muted"), "Expected the correct muted attribute on the new tab"); diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index 06df311970ee..0f92557a5c18 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -107,12 +107,6 @@ static PRLogModuleInfo* gMediaElementEventsLog; #include "mozilla/EventStateManager.h" -#if defined(MOZ_B2G) && !defined(MOZ_GRAPHENE) -// This controls the b2g specific of pausing the media element when the -// AudioChannel tells us to mute it. -#define PAUSE_MEDIA_ELEMENT_FROM_AUDIOCHANNEL -#endif - using namespace mozilla::layers; using mozilla::net::nsMediaFragmentURIParser; @@ -578,6 +572,7 @@ void HTMLMediaElement::SetSrcObject(DOMMediaStream* aValue) { mSrcAttrStream = aValue; + UpdateAudioChannelPlayingState(); DoLoad(); } @@ -602,6 +597,7 @@ void HTMLMediaElement::SetMozSrcObject(DOMMediaStream* aValue) { mSrcAttrStream = aValue; + UpdateAudioChannelPlayingState(); DoLoad(); } @@ -768,6 +764,7 @@ void HTMLMediaElement::AbortExistingLoads() FireTimeUpdate(false); } DispatchAsyncEvent(NS_LITERAL_STRING("emptied")); + UpdateAudioChannelPlayingState(); } // We may have changed mPaused, mAutoplaying, and other @@ -1711,6 +1708,7 @@ HTMLMediaElement::Pause(ErrorResult& aRv) // We changed mPaused and mAutoplaying which can affect AddRemoveSelfReference AddRemoveSelfReference(); UpdateSrcMediaStreamPlaying(); + UpdateAudioChannelPlayingState(); if (!oldPaused) { FireTimeUpdate(false); @@ -2317,6 +2315,7 @@ HTMLMediaElement::PlayInternal(bool aCallerIsChrome) AddRemoveSelfReference(); UpdatePreloadAction(); UpdateSrcMediaStreamPlaying(); + UpdateAudioChannelPlayingState(); return NS_OK; } @@ -2897,6 +2896,7 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder, // We may want to suspend the new stream now. // This will also do an AddRemoveSelfReference. NotifyOwnerDocumentActivityChangedInternal(); + UpdateAudioChannelPlayingState(); if (!mPaused) { SetPlayedOrSeeked(true); @@ -3993,6 +3993,7 @@ void HTMLMediaElement::CheckAutoplayDataReady() // We changed mPaused which can affect AddRemoveSelfReference AddRemoveSelfReference(); UpdateSrcMediaStreamPlaying(); + UpdateAudioChannelPlayingState(); if (mDecoder) { SetPlayedOrSeeked(true); @@ -4007,13 +4008,13 @@ void HTMLMediaElement::CheckAutoplayDataReady() } -bool HTMLMediaElement::IsActive() +bool HTMLMediaElement::IsActive() const { nsIDocument* ownerDoc = OwnerDoc(); return ownerDoc && ownerDoc->IsActive() && ownerDoc->IsVisible(); } -bool HTMLMediaElement::IsHidden() +bool HTMLMediaElement::IsHidden() const { if (mElementInTreeState == ELEMENT_NOT_INTREE_HAD_INTREE) { return true; @@ -4192,6 +4193,7 @@ void HTMLMediaElement::SuspendOrResumeElement(bool aPauseElement, bool aSuspendE if (aPauseElement != mPausedForInactiveDocumentOrChannel) { mPausedForInactiveDocumentOrChannel = aPauseElement; UpdateSrcMediaStreamPlaying(); + UpdateAudioChannelPlayingState(); if (aPauseElement) { if (mMediaSource) { ReportMSETelemetry(); @@ -4251,15 +4253,12 @@ bool HTMLMediaElement::IsBeingDestroyed() void HTMLMediaElement::NotifyOwnerDocumentActivityChanged() { bool pauseElement = NotifyOwnerDocumentActivityChangedInternal(); - if (pauseElement && mAudioChannelAgent -#ifdef PAUSE_MEDIA_ELEMENT_FROM_AUDIOCHANNEL + 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. - && !ComputedMuted() -#endif - ) { + (!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. @@ -4283,15 +4282,13 @@ HTMLMediaElement::NotifyOwnerDocumentActivityChangedInternal() } bool pauseElement = !IsActive(); -#ifdef PAUSE_MEDIA_ELEMENT_FROM_AUDIOCHANNEL // 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 (mAudioChannelAgent) { + if (UseAudioChannelAPI() && mAudioChannelAgent) { pauseElement |= ComputedMuted(); } -#endif SuspendOrResumeElement(pauseElement, !IsActive()); @@ -4725,9 +4722,10 @@ nsresult HTMLMediaElement::UpdateChannelMuteState(float aVolume, bool aMuted) } } -#ifdef PAUSE_MEDIA_ELEMENT_FROM_AUDIOCHANNEL - SuspendOrResumeElement(ComputedMuted(), false); -#endif + if (UseAudioChannelAPI()) { + SuspendOrResumeElement(ComputedMuted(), false); + } + return NS_OK; } @@ -4761,6 +4759,11 @@ HTMLMediaElement::IsPlayingThroughTheAudioChannel() const return false; } + // We should consider any bfcached page or inactive document as non-playing. + if (!IsActive()) { + return false; + } + // A loop always is playing if (HasAttr(kNameSpaceID_None, nsGkAtoms::loop)) { return true; @@ -4837,9 +4840,9 @@ NS_IMETHODIMP HTMLMediaElement::WindowVolumeChanged(float aVolume, bool aMuted) UpdateChannelMuteState(aVolume, aMuted); -#ifdef PAUSE_MEDIA_ELEMENT_FROM_AUDIOCHANNEL - mPaused.SetCanPlay(!aMuted); -#endif + if (UseAudioChannelAPI()) { + mPaused.SetCanPlay(!aMuted); + } return NS_OK; } diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h index b9c376e108ab..1935c949f137 100644 --- a/dom/html/HTMLMediaElement.h +++ b/dom/html/HTMLMediaElement.h @@ -214,9 +214,9 @@ public: // suspended the channel. virtual void NotifySuspendedByCache(bool aIsSuspended) final override; - virtual bool IsActive() final override; + virtual bool IsActive() const final override; - virtual bool IsHidden() final override; + virtual bool IsHidden() const final override; // In order to create overlayImageContainer to support DOMHwMediaStream. VideoFrameContainer* GetOverlayImageVideoFrameContainer(); diff --git a/dom/media/MediaDecoderOwner.h b/dom/media/MediaDecoderOwner.h index d1cf56081239..dda03b7578a6 100644 --- a/dom/media/MediaDecoderOwner.h +++ b/dom/media/MediaDecoderOwner.h @@ -117,10 +117,10 @@ public: }; // Check if the decoder owner is active. - virtual bool IsActive() = 0; + virtual bool IsActive() const = 0; // Check if the decoder owner is hidden. - virtual bool IsHidden() = 0; + virtual bool IsHidden() const = 0; // Called by the media decoder and the video frame to get the // ImageContainer containing the video data. diff --git a/dom/media/gtest/MockMediaDecoderOwner.h b/dom/media/gtest/MockMediaDecoderOwner.h index 9e28d13a0bd7..148dfe879e68 100644 --- a/dom/media/gtest/MockMediaDecoderOwner.h +++ b/dom/media/gtest/MockMediaDecoderOwner.h @@ -36,8 +36,8 @@ public: virtual void DispatchEncrypted(const nsTArray& aInitData, const nsAString& aInitDataType) override {} #endif // MOZ_EME - virtual bool IsActive() override { return true; } - virtual bool IsHidden() override { return false; } + virtual bool IsActive() const override { return true; } + virtual bool IsHidden() const override { return false; } virtual void DownloadSuspended() override {} virtual void DownloadResumed(bool aForceNetworkLoading) override {} virtual void NotifySuspendedByCache(bool aIsSuspended) override {} diff --git a/dom/media/test/crashtests/crashtests.list b/dom/media/test/crashtests/crashtests.list index 63dbfe30c3b7..df560ab2a0cc 100644 --- a/dom/media/test/crashtests/crashtests.list +++ b/dom/media/test/crashtests/crashtests.list @@ -7,7 +7,7 @@ load 474744-1.html HTTP load 481136-1.html # needs to be HTTP to recognize the ogg as an audio file? load 492286-1.xhtml load 493915-1.html -load 495794-1.html +skip-if(B2G) load 495794-1.html # in b2g all the media are muted by default load 576612-1.html load 752784-1.html load 789075-1.html