Bug 1319771 - part2 : resume foreground window if it was still be blocked.
In previous patch, we modify the behavior of nsDocument, now it would only resume
window when document has active media components.
However, it causes another issue. If the tab really goes to foreground, but
there is no active media component, the tab would still be blocked and it won't
be resumed anymore.
Therefore, we need to resume it by ourself if the tab is on the foreground but
doesn't be resumed yet.
MozReview-Commit-ID: EdnQ7sRkSJK
--- a/dom/audiochannel/AudioChannelAgent.cpp
+++ b/dom/audiochannel/AudioChannelAgent.cpp
@@ -179,16 +179,19 @@ AudioChannelAgent::InitInternal(nsPIDOMW
mAudioChannelType = aChannelType;
if (aUseWeakRef) {
mWeakCallback = do_GetWeakReference(aCallback);
} else {
mCallback = aCallback;
}
+ RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
+ service->NotifyCreatedNewAgent(this);
+
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("AudioChannelAgent, InitInternal, this = %p, type = %d, "
"owner = %p, hasCallback = %d\n", this, mAudioChannelType,
mWindow.get(), (!!mCallback || !!mWeakCallback)));
return NS_OK;
}
--- a/dom/audiochannel/AudioChannelService.cpp
+++ b/dom/audiochannel/AudioChannelService.cpp
@@ -289,16 +289,29 @@ AudioChannelService::AudioChannelService
"dom.audiochannel.audioCompeting");
}
AudioChannelService::~AudioChannelService()
{
}
void
+AudioChannelService::NotifyCreatedNewAgent(AudioChannelAgent* aAgent)
+{
+ MOZ_ASSERT(aAgent);
+
+ nsCOMPtr<nsPIDOMWindowOuter> window = aAgent->Window();
+ if (!window) {
+ return;
+ }
+
+ window->NotifyCreatedNewMediaComponent();
+}
+
+void
AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
AudibleState aAudible)
{
MOZ_ASSERT(aAgent);
uint64_t windowID = aAgent->WindowID();
AudioChannelWindow* winData = GetWindowData(windowID);
if (!winData) {
--- a/dom/audiochannel/AudioChannelService.h
+++ b/dom/audiochannel/AudioChannelService.h
@@ -194,16 +194,18 @@ public:
static void GetAudioChannelString(AudioChannel aChannel, nsAString& aString);
static void GetDefaultAudioChannelString(nsAString& aString);
void Notify(uint64_t aWindowID);
void ChildStatusReceived(uint64_t aChildID, bool aTelephonyChannel,
bool aContentOrNormalChannel, bool aAnyChannel);
+ void NotifyCreatedNewAgent(AudioChannelAgent* aAgent);
+
private:
AudioChannelService();
~AudioChannelService();
void RefreshAgents(nsPIDOMWindowOuter* aWindow,
std::function<void(AudioChannelAgent*)> aFunc);
static void CreateServiceIfNeeded();
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -12075,20 +12075,17 @@ nsDocument::MaybeActiveMediaComponents()
return;
}
if (!mWindow) {
return;
}
mEverInForeground = true;
- if (GetWindow()->GetMediaSuspend() == nsISuspendedTypes::SUSPENDED_BLOCK &&
- AudioChannelService::IsServiceStarted()) {
- GetWindow()->SetMediaSuspend(nsISuspendedTypes::NONE_SUSPENDED);
- }
+ GetWindow()->MaybeActiveMediaComponents();
}
NS_IMETHODIMP
nsDocument::GetHidden(bool* aHidden)
{
*aHidden = Hidden();
return NS_OK;
}
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -4167,16 +4167,55 @@ nsPIDOMWindowInner::TimeoutManager()
}
bool
nsPIDOMWindowInner::IsRunningTimeout()
{
return TimeoutManager().IsRunningTimeout();
}
+void
+nsPIDOMWindowOuter::NotifyCreatedNewMediaComponent()
+{
+ if (mMediaSuspend != nsISuspendedTypes::SUSPENDED_BLOCK) {
+ return;
+ }
+
+ // If the document is already on the foreground but the suspend state is still
+ // suspend-block, that means the media component was created after calling
+ // MaybeActiveMediaComponents, so the window's suspend state doesn't be
+ // changed yet. Therefore, we need to call it again, because the state is only
+ // changed after there exists alive media within the window.
+ MaybeActiveMediaComponents();
+}
+
+void
+nsPIDOMWindowOuter::MaybeActiveMediaComponents()
+{
+ if (IsInnerWindow()) {
+ return mOuterWindow->MaybeActiveMediaComponents();
+ }
+
+ nsCOMPtr<nsPIDOMWindowInner> inner = GetCurrentInnerWindow();
+ if (!inner) {
+ return;
+ }
+
+ nsCOMPtr<nsIDocument> doc = inner->GetExtantDoc();
+ if (!doc) {
+ return;
+ }
+
+ if (!doc->Hidden() &&
+ mMediaSuspend == nsISuspendedTypes::SUSPENDED_BLOCK &&
+ AudioChannelService::IsServiceStarted()) {
+ SetMediaSuspend(nsISuspendedTypes::NONE_SUSPENDED);
+ }
+}
+
SuspendTypes
nsPIDOMWindowOuter::GetMediaSuspend() const
{
if (IsInnerWindow()) {
return mOuterWindow->GetMediaSuspend();
}
return mMediaSuspend;
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -958,16 +958,19 @@ public:
void SetMediaSuspend(SuspendTypes aSuspend);
bool GetAudioMuted() const;
void SetAudioMuted(bool aMuted);
float GetAudioVolume() const;
nsresult SetAudioVolume(float aVolume);
+ void NotifyCreatedNewMediaComponent();
+ void MaybeActiveMediaComponents();
+
void SetServiceWorkersTestingEnabled(bool aEnabled);
bool GetServiceWorkersTestingEnabled();
float GetDevicePixelRatio(mozilla::dom::CallerType aCallerType);
void SetLargeAllocStatus(mozilla::dom::LargeAllocStatus aStatus);
};