зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1625615 - part0 : create and set the flag `suspendMediaWhenInactive` on docShell. r=baku,farre
Implemecurnt a flag `suspendMediaWhenInactive` on the docShell that indicates media in that shell should be suspended when the shell is inactive. Currently, only GeckoView is using this flag. --- The reason of implementing this flag is because in bug1577890 we remove the old way to suspend/resume the media, and I thought setting docshell to inactive is enough to suspend the media because we already have a mechanism which would suspend/resume media when document becomes inactive/active [1]. However, the active state of document is actually different from what I thought it was. Setting docshell to inactive won't change the document's active state, because that indicates if the document is the current active document for the docshell [2] (docshell can have multiple documents), instead of indicating if the docshell is active or not. Therefore, we have to add another flag to indicate if the docshell wants to suspend its media when it's inactive, in order to use current mechanism to suspend/resume media. [1] https://searchfox.org/mozilla-central/rev/4d2a9d5dc8f0e65807ee66e2b04c64596c643b7a/dom/html/HTMLMediaElement.cpp#6453 [2] https://searchfox.org/mozilla-central/rev/4d2a9d5dc8f0e65807ee66e2b04c64596c643b7a/dom/base/Document.h#2627-2633 Differential Revision: https://phabricator.services.mozilla.com/D69669
This commit is contained in:
Родитель
e8e2885864
Коммит
f6f59cedd1
|
@ -398,7 +398,8 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
|
|||
mTitleValidForCurrentURI(false),
|
||||
mWillChangeProcess(false),
|
||||
mWatchedByDevtools(false),
|
||||
mIsNavigating(false) {
|
||||
mIsNavigating(false),
|
||||
mSuspendMediaWhenInactive(false) {
|
||||
// If no outer window ID was provided, generate a new one.
|
||||
if (aContentWindowID == 0) {
|
||||
mContentWindowID = nsContentUtils::GenerateWindowId();
|
||||
|
@ -4640,6 +4641,18 @@ nsDocShell::GetIsOffScreenBrowser(bool* aIsOffScreen) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetSuspendMediaWhenInactive(bool aSuspendMediaWhenInactive) {
|
||||
mSuspendMediaWhenInactive = aSuspendMediaWhenInactive;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetSuspendMediaWhenInactive(bool* aSuspendMediaWhenInactive) {
|
||||
*aSuspendMediaWhenInactive = mSuspendMediaWhenInactive;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetIsActive(bool aIsActive) {
|
||||
// Keep track ourselves.
|
||||
|
|
|
@ -1325,6 +1325,10 @@ class nsDocShell final : public nsDocLoader,
|
|||
// This flag indicates whether or not the DocShell is currently executing an
|
||||
// nsIWebNavigation navigation method.
|
||||
bool mIsNavigating : 1;
|
||||
|
||||
// This flag indicates whether the media in this docshell should be suspended
|
||||
// when the docshell is inactive.
|
||||
bool mSuspendMediaWhenInactive : 1;
|
||||
};
|
||||
|
||||
#endif /* nsDocShell_h__ */
|
||||
|
|
|
@ -558,6 +558,13 @@ interface nsIDocShell : nsIDocShellTreeItem
|
|||
*/
|
||||
[infallible] attribute boolean isActive;
|
||||
|
||||
/**
|
||||
* Set if the media element in this docShell should be suspended when the
|
||||
* docShell is inactive.
|
||||
*/
|
||||
[infallible] attribute boolean suspendMediaWhenInactive;
|
||||
|
||||
|
||||
/**
|
||||
* The ID of the docshell in the session history.
|
||||
*/
|
||||
|
|
|
@ -20,6 +20,13 @@ interface nsIRemoteTab : nsISupports
|
|||
*/
|
||||
attribute boolean docShellIsActive;
|
||||
|
||||
/**
|
||||
* Manages the flag of the remote docshell, which is used to determine if the
|
||||
* media element in that remote docshell should be suspended when the docshell
|
||||
* is inactive.
|
||||
*/
|
||||
attribute boolean suspendMediaWhenInactive;
|
||||
|
||||
/**
|
||||
* When set to true, this tells the child to paint and upload layers to
|
||||
* the compositor. When set to false, previous layers are cleared from
|
||||
|
|
|
@ -365,6 +365,7 @@ BrowserChild::BrowserChild(ContentChild* aManager, const TabId& aTabId,
|
|||
mShouldSendWebProgressEventsToParent(false),
|
||||
mRenderLayers(true),
|
||||
mPendingDocShellIsActive(false),
|
||||
mPendingSuspendMediaWhenInactive(false),
|
||||
mPendingDocShellReceivedMessage(false),
|
||||
mPendingRenderLayers(false),
|
||||
mPendingRenderLayersReceivedMessage(false),
|
||||
|
@ -2394,6 +2395,10 @@ void BrowserChild::RemovePendingDocShellBlocker() {
|
|||
mPendingDocShellReceivedMessage = false;
|
||||
InternalSetDocShellIsActive(mPendingDocShellIsActive);
|
||||
}
|
||||
if (!mPendingDocShellBlockers && mPendingSuspendMediaWhenInactive) {
|
||||
mPendingSuspendMediaWhenInactive = false;
|
||||
InternalSetSuspendMediaWhenInactive(mPendingSuspendMediaWhenInactive);
|
||||
}
|
||||
if (!mPendingDocShellBlockers && mPendingRenderLayersReceivedMessage) {
|
||||
mPendingRenderLayersReceivedMessage = false;
|
||||
RecvRenderLayers(mPendingRenderLayers, mPendingLayersObserverEpoch);
|
||||
|
@ -2421,6 +2426,25 @@ mozilla::ipc::IPCResult BrowserChild::RecvSetDocShellIsActive(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
void BrowserChild::InternalSetSuspendMediaWhenInactive(
|
||||
bool aSuspendMediaWhenInactive) {
|
||||
if (nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation())) {
|
||||
docShell->SetSuspendMediaWhenInactive(aSuspendMediaWhenInactive);
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserChild::RecvSetSuspendMediaWhenInactive(
|
||||
const bool& aSuspendMediaWhenInactive) {
|
||||
if (mPendingDocShellBlockers > 0) {
|
||||
mPendingDocShellReceivedMessage = true;
|
||||
mPendingSuspendMediaWhenInactive = aSuspendMediaWhenInactive;
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
InternalSetSuspendMediaWhenInactive(aSuspendMediaWhenInactive);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserChild::RecvRenderLayers(
|
||||
const bool& aEnabled, const layers::LayersObserverEpoch& aEpoch) {
|
||||
if (mPendingDocShellBlockers > 0) {
|
||||
|
|
|
@ -717,6 +717,9 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||
|
||||
mozilla::ipc::IPCResult RecvSetDocShellIsActive(const bool& aIsActive);
|
||||
|
||||
mozilla::ipc::IPCResult RecvSetSuspendMediaWhenInactive(
|
||||
const bool& aSuspendMediaWhenInactive);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
mozilla::ipc::IPCResult RecvRenderLayers(
|
||||
const bool& aEnabled, const layers::LayersObserverEpoch& aEpoch);
|
||||
|
@ -812,6 +815,8 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||
|
||||
void InternalSetDocShellIsActive(bool aIsActive);
|
||||
|
||||
void InternalSetSuspendMediaWhenInactive(bool aSuspendMediaWhenInactive);
|
||||
|
||||
bool CreateRemoteLayerManager(
|
||||
mozilla::layers::PCompositorBridgeChild* aCompositorChild);
|
||||
|
||||
|
@ -931,6 +936,7 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||
// states temporarily as "pending", and only apply them once the DocShell
|
||||
// is no longer blocked.
|
||||
bool mPendingDocShellIsActive;
|
||||
bool mPendingSuspendMediaWhenInactive;
|
||||
bool mPendingDocShellReceivedMessage;
|
||||
bool mPendingRenderLayers;
|
||||
bool mPendingRenderLayersReceivedMessage;
|
||||
|
|
|
@ -97,6 +97,28 @@ void BrowserHost::UpdateEffects(EffectsInfo aEffects) {
|
|||
Unused << mRoot->SendUpdateEffects(mEffectsInfo);
|
||||
}
|
||||
|
||||
/* attribute boolean suspendMediaWhenInactive; */
|
||||
NS_IMETHODIMP
|
||||
BrowserHost::GetSuspendMediaWhenInactive(bool* aSuspendMediaWhenInactive) {
|
||||
if (!mRoot) {
|
||||
*aSuspendMediaWhenInactive = false;
|
||||
return NS_OK;
|
||||
}
|
||||
*aSuspendMediaWhenInactive = mRoot->GetSuspendMediaWhenInactive();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BrowserHost::SetSuspendMediaWhenInactive(bool aSuspendMediaWhenInactive) {
|
||||
if (!mRoot) {
|
||||
return NS_OK;
|
||||
}
|
||||
VisitAll([&](BrowserParent* aBrowserParent) {
|
||||
aBrowserParent->SetSuspendMediaWhenInactive(aSuspendMediaWhenInactive);
|
||||
});
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute boolean docShellIsActive; */
|
||||
NS_IMETHODIMP
|
||||
BrowserHost::GetDocShellIsActive(bool* aDocShellIsActive) {
|
||||
|
|
|
@ -221,7 +221,8 @@ BrowserParent::BrowserParent(ContentParent* aManager, const TabId& aTabId,
|
|||
mHasPresented(false),
|
||||
mIsReadyToHandleInputEvents(false),
|
||||
mIsMouseEnterIntoWidgetEventSuppressed(false),
|
||||
mSuspendedProgressEvents(false) {
|
||||
mSuspendedProgressEvents(false),
|
||||
mSuspendMediaWhenInactive(false) {
|
||||
MOZ_ASSERT(aManager);
|
||||
// When the input event queue is disabled, we don't need to handle the case
|
||||
// that some input events are dispatched before PBrowserConstructor.
|
||||
|
@ -3404,6 +3405,16 @@ void BrowserParent::SetDocShellIsActive(bool isActive) {
|
|||
#endif
|
||||
}
|
||||
|
||||
bool BrowserParent::GetSuspendMediaWhenInactive() const {
|
||||
return mSuspendMediaWhenInactive;
|
||||
}
|
||||
|
||||
void BrowserParent::SetSuspendMediaWhenInactive(
|
||||
bool aSuspendMediaWhenInactive) {
|
||||
mSuspendMediaWhenInactive = aSuspendMediaWhenInactive;
|
||||
Unused << SendSetSuspendMediaWhenInactive(aSuspendMediaWhenInactive);
|
||||
}
|
||||
|
||||
bool BrowserParent::GetHasPresented() { return mHasPresented; }
|
||||
|
||||
bool BrowserParent::GetHasLayers() { return mHasLayers; }
|
||||
|
|
|
@ -709,6 +709,9 @@ class BrowserParent final : public PBrowserParent,
|
|||
bool GetDocShellIsActive();
|
||||
void SetDocShellIsActive(bool aDocShellIsActive);
|
||||
|
||||
bool GetSuspendMediaWhenInactive() const;
|
||||
void SetSuspendMediaWhenInactive(bool aSuspendMediaWhenInactive);
|
||||
|
||||
bool GetHasPresented();
|
||||
bool GetHasLayers();
|
||||
bool GetRenderLayers();
|
||||
|
@ -995,6 +998,10 @@ class BrowserParent final : public PBrowserParent,
|
|||
// (for something that isn't the initial about:blank) and then start
|
||||
// allowing future events.
|
||||
bool mSuspendedProgressEvents : 1;
|
||||
|
||||
// True if the media in the remote docshell should be suspended when the
|
||||
// remote docshell is inactive.
|
||||
bool mSuspendMediaWhenInactive : 1;
|
||||
};
|
||||
|
||||
struct MOZ_STACK_CLASS BrowserParent::AutoUseNewTab final {
|
||||
|
|
|
@ -868,6 +868,15 @@ child:
|
|||
*/
|
||||
async SetDocShellIsActive(bool aIsActive);
|
||||
|
||||
/**
|
||||
* Update docshell's flag which is used to determine if the media in that
|
||||
* docshell should be suspended when the docshell is inactive.
|
||||
*
|
||||
* @param aSuspendMediaWhenInactive
|
||||
* If the media should be suspended when docshell is inactive.
|
||||
*/
|
||||
async SetSuspendMediaWhenInactive(bool aSuspendMediaWhenInactive);
|
||||
|
||||
/**
|
||||
* If aEnabled is true, tells the child to paint and upload layers to
|
||||
* the compositor. If aEnabled is false, the child stops painting and
|
||||
|
|
|
@ -513,6 +513,28 @@
|
|||
return popupAnchor;
|
||||
}
|
||||
|
||||
set suspendMediaWhenInactive(val) {
|
||||
if (this.isRemoteBrowser) {
|
||||
let { frameLoader } = this;
|
||||
if (frameLoader && frameLoader.remoteTab) {
|
||||
frameLoader.remoteTab.suspendMediaWhenInactive = val;
|
||||
}
|
||||
} else if (this.docShell) {
|
||||
this.docShell.suspendMediaWhenInactive = val;
|
||||
}
|
||||
}
|
||||
|
||||
get suspendMediaWhenInactive() {
|
||||
if (this.isRemoteBrowser) {
|
||||
let { frameLoader } = this;
|
||||
if (frameLoader && frameLoader.remoteTab) {
|
||||
return frameLoader.remoteTab.suspendMediaWhenInactive;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return this.docShell && this.docShell.suspendMediaWhenInactive;
|
||||
}
|
||||
|
||||
set docShellIsActive(val) {
|
||||
if (this.isRemoteBrowser) {
|
||||
let { frameLoader } = this;
|
||||
|
|
Загрузка…
Ссылка в новой задаче