Bug 1696158 - Move CanSavePresentation to the parent process. Keep track of various flags for deciding whether to put a page in BFCache. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D110231
This commit is contained in:
Peter Van der Beken
2021-04-19 14:50:54 +00:00
parent 4687b22fef
commit 2ed1ecb468
13 changed files with 224 additions and 20 deletions

View File

@@ -6783,6 +6783,17 @@ void Document::DeletePresShell() {
mDesignModeSheetAdded = false; mDesignModeSheetAdded = false;
} }
void Document::DisallowBFCaching() {
NS_ASSERTION(!mBFCacheEntry, "We're already in the bfcache!");
if (!mBFCacheDisallowed) {
WindowGlobalChild* wgc = GetWindowGlobalChild();
if (wgc) {
wgc->BlockBFCacheFor(BFCacheStatus::NOT_ALLOWED);
}
}
mBFCacheDisallowed = true;
}
void Document::SetBFCacheEntry(nsIBFCacheEntry* aEntry) { void Document::SetBFCacheEntry(nsIBFCacheEntry* aEntry) {
MOZ_ASSERT(IsBFCachingAllowed() || !aEntry, "You should have checked!"); MOZ_ASSERT(IsBFCachingAllowed() || !aEntry, "You should have checked!");
@@ -11857,6 +11868,12 @@ void Document::GetReadyState(nsAString& aReadyState) const {
void Document::SuppressEventHandling(uint32_t aIncrease) { void Document::SuppressEventHandling(uint32_t aIncrease) {
mEventsSuppressed += aIncrease; mEventsSuppressed += aIncrease;
if (mEventsSuppressed == aIncrease) {
WindowGlobalChild* wgc = GetWindowGlobalChild();
if (wgc) {
wgc->BlockBFCacheFor(BFCacheStatus::EVENT_HANDLING_SUPPRESSED);
}
}
UpdateFrameRequestCallbackSchedulingState(); UpdateFrameRequestCallbackSchedulingState();
for (uint32_t i = 0; i < aIncrease; ++i) { for (uint32_t i = 0; i < aIncrease; ++i) {
ScriptLoader()->AddExecuteBlocker(); ScriptLoader()->AddExecuteBlocker();
@@ -12255,6 +12272,11 @@ void Document::UnsuppressEventHandlingAndFireEvents(bool aFireEvents) {
} }
if (!EventHandlingSuppressed()) { if (!EventHandlingSuppressed()) {
WindowGlobalChild* wgc = GetWindowGlobalChild();
if (wgc) {
wgc->UnblockBFCacheFor(BFCacheStatus::EVENT_HANDLING_SUPPRESSED);
}
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
nsTArray<RefPtr<net::ChannelEventQueue>> queues = nsTArray<RefPtr<net::ChannelEventQueue>> queues =
std::move(mSuspendedQueues); std::move(mSuspendedQueues);
@@ -17231,4 +17253,23 @@ void Document::DisableChildElementInPictureInPictureMode() {
MOZ_ASSERT(mPictureInPictureChildElementCount >= 0); MOZ_ASSERT(mPictureInPictureChildElementCount >= 0);
} }
void Document::AddMediaElementWithMSE() {
if (mMediaElementWithMSECount++ == 0) {
WindowGlobalChild* wgc = GetWindowGlobalChild();
if (wgc) {
wgc->BlockBFCacheFor(BFCacheStatus::CONTAINS_MSE_CONTENT);
}
}
}
void Document::RemoveMediaElementWithMSE() {
MOZ_ASSERT(mMediaElementWithMSECount > 0);
if (--mMediaElementWithMSECount == 0) {
WindowGlobalChild* wgc = GetWindowGlobalChild();
if (wgc) {
wgc->UnblockBFCacheFor(BFCacheStatus::CONTAINS_MSE_CONTENT);
}
}
}
} // namespace mozilla::dom } // namespace mozilla::dom

View File

@@ -1201,10 +1201,7 @@ class Document : public nsINode,
// Instead using this method, what you probably want is // Instead using this method, what you probably want is
// RemoveFromBFCacheSync() as we do in MessagePort and BroadcastChannel. // RemoveFromBFCacheSync() as we do in MessagePort and BroadcastChannel.
void DisallowBFCaching() { void DisallowBFCaching();
NS_ASSERTION(!mBFCacheEntry, "We're already in the bfcache!");
mBFCacheDisallowed = true;
}
bool IsBFCachingAllowed() const { return !mBFCacheDisallowed; } bool IsBFCachingAllowed() const { return !mBFCacheDisallowed; }
@@ -1520,6 +1517,9 @@ class Document : public nsINode,
bool ShouldIncludeInTelemetry(bool aAllowExtensionURIs); bool ShouldIncludeInTelemetry(bool aAllowExtensionURIs);
void AddMediaElementWithMSE();
void RemoveMediaElementWithMSE();
protected: protected:
friend class nsUnblockOnloadEvent; friend class nsUnblockOnloadEvent;
@@ -5233,6 +5233,8 @@ class Document : public nsINode,
int32_t mNextFormNumber; int32_t mNextFormNumber;
int32_t mNextControlNumber; int32_t mNextControlNumber;
uint32_t mMediaElementWithMSECount = 0;
// Scope preloads per document. This is used by speculative loading as well. // Scope preloads per document. This is used by speculative loading as well.
PreloadService mPreloadService; PreloadService mPreloadService;

View File

@@ -939,8 +939,7 @@ nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow,
mAreDialogsEnabled(true), mAreDialogsEnabled(true),
mObservingRefresh(false), mObservingRefresh(false),
mIteratingDocumentFlushedResolvers(false), mIteratingDocumentFlushedResolvers(false),
mCanSkipCCGeneration(0), mCanSkipCCGeneration(0) {
mBeforeUnloadListenerCount(0) {
mIsInnerWindow = true; mIsInnerWindow = true;
AssertIsOnMainThread(); AssertIsOnMainThread();
@@ -2635,11 +2634,17 @@ bool nsPIDOMWindowInner::HasActivePeerConnections() {
void nsPIDOMWindowInner::AddMediaKeysInstance(MediaKeys* aMediaKeys) { void nsPIDOMWindowInner::AddMediaKeysInstance(MediaKeys* aMediaKeys) {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
mMediaKeysInstances.AppendElement(aMediaKeys); mMediaKeysInstances.AppendElement(aMediaKeys);
if (mWindowGlobalChild && mMediaKeysInstances.Length() == 1) {
mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::CONTAINS_EME_CONTENT);
}
} }
void nsPIDOMWindowInner::RemoveMediaKeysInstance(MediaKeys* aMediaKeys) { void nsPIDOMWindowInner::RemoveMediaKeysInstance(MediaKeys* aMediaKeys) {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
mMediaKeysInstances.RemoveElement(aMediaKeys); mMediaKeysInstances.RemoveElement(aMediaKeys);
if (mWindowGlobalChild && mMediaKeysInstances.IsEmpty()) {
mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::CONTAINS_EME_CONTENT);
}
} }
bool nsPIDOMWindowInner::HasActiveMediaKeysInstance() { bool nsPIDOMWindowInner::HasActiveMediaKeysInstance() {
@@ -5460,6 +5465,10 @@ void nsGlobalWindowInner::Suspend(bool aIncludeSubWindows) {
return; return;
} }
if (mWindowGlobalChild) {
mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::SUSPENDED);
}
nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID); nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID);
if (ac) { if (ac) {
for (uint32_t i = 0; i < mEnabledSensors.Length(); i++) for (uint32_t i = 0; i < mEnabledSensors.Length(); i++)
@@ -5546,6 +5555,10 @@ void nsGlobalWindowInner::Resume(bool aIncludeSubWindows) {
mSharedWorkers.ForwardRange()) { mSharedWorkers.ForwardRange()) {
pinnedWorker->Resume(); pinnedWorker->Resume();
} }
if (mWindowGlobalChild) {
mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::SUSPENDED);
}
} }
bool nsGlobalWindowInner::IsSuspended() const { bool nsGlobalWindowInner::IsSuspended() const {
@@ -6462,10 +6475,16 @@ void nsGlobalWindowInner::EventListenerAdded(nsAtom* aType) {
mHasVRDisplayActivateEvents = true; mHasVRDisplayActivateEvents = true;
} }
if (aType == nsGkAtoms::onbeforeunload && mWindowGlobalChild && if ((aType == nsGkAtoms::onunload || aType == nsGkAtoms::onbeforeunload) &&
(!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS))) { mWindowGlobalChild) {
mWindowGlobalChild->BeforeUnloadAdded(); if (++mUnloadOrBeforeUnloadListenerCount == 1) {
MOZ_ASSERT(mWindowGlobalChild->BeforeUnloadListeners() > 0); mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::UNLOAD_LISTENER);
}
if (aType == nsGkAtoms::onbeforeunload &&
(!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS))) {
mWindowGlobalChild->BeforeUnloadAdded();
MOZ_ASSERT(mWindowGlobalChild->BeforeUnloadListeners() > 0);
}
} }
// We need to initialize localStorage in order to receive notifications. // We need to initialize localStorage in order to receive notifications.
@@ -6484,10 +6503,17 @@ void nsGlobalWindowInner::EventListenerAdded(nsAtom* aType) {
} }
void nsGlobalWindowInner::EventListenerRemoved(nsAtom* aType) { void nsGlobalWindowInner::EventListenerRemoved(nsAtom* aType) {
if (aType == nsGkAtoms::onbeforeunload && mWindowGlobalChild && if ((aType == nsGkAtoms::onunload || aType == nsGkAtoms::onbeforeunload) &&
(!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS))) { mWindowGlobalChild) {
mWindowGlobalChild->BeforeUnloadRemoved(); MOZ_ASSERT(mUnloadOrBeforeUnloadListenerCount > 0);
MOZ_ASSERT(mWindowGlobalChild->BeforeUnloadListeners() >= 0); if (--mUnloadOrBeforeUnloadListenerCount == 0) {
mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::UNLOAD_LISTENER);
}
if (aType == nsGkAtoms::onbeforeunload &&
(!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS))) {
mWindowGlobalChild->BeforeUnloadRemoved();
MOZ_ASSERT(mWindowGlobalChild->BeforeUnloadListeners() >= 0);
}
} }
if (aType == nsGkAtoms::onstorage) { if (aType == nsGkAtoms::onstorage) {
@@ -6511,6 +6537,9 @@ void nsGlobalWindowInner::NotifyHasXRSession() {
// has been called, including mVREventObserver. // has been called, including mVREventObserver.
return; return;
} }
if (mWindowGlobalChild && !mHasXRSession) {
mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::HAS_USED_VR);
}
mHasXRSession = true; mHasXRSession = true;
EnableVRUpdates(); EnableVRUpdates();
} }

View File

@@ -1473,7 +1473,9 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
RefPtr<mozilla::dom::VREventObserver> mVREventObserver; RefPtr<mozilla::dom::VREventObserver> mVREventObserver;
int64_t mBeforeUnloadListenerCount; // The number of unload and beforeunload even listeners registered on this
// window.
uint64_t mUnloadOrBeforeUnloadListenerCount = 0;
RefPtr<mozilla::dom::IntlUtils> mIntlUtils; RefPtr<mozilla::dom::IntlUtils> mIntlUtils;

View File

@@ -86,6 +86,7 @@
#include "mozilla/dom/VideoTrack.h" #include "mozilla/dom/VideoTrack.h"
#include "mozilla/dom/VideoTrackList.h" #include "mozilla/dom/VideoTrackList.h"
#include "mozilla/dom/WakeLock.h" #include "mozilla/dom/WakeLock.h"
#include "mozilla/dom/WindowGlobalChild.h"
#include "mozilla/dom/power/PowerManagerService.h" #include "mozilla/dom/power/PowerManagerService.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h" #include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "nsAttrValueInlines.h" #include "nsAttrValueInlines.h"
@@ -2239,6 +2240,10 @@ void HTMLMediaElement::AbortExistingLoads() {
EndSrcMediaStreamPlayback(); EndSrcMediaStreamPlayback();
} }
if (mMediaSource) {
OwnerDoc()->RemoveMediaElementWithMSE();
}
RemoveMediaElementFromURITable(); RemoveMediaElementFromURITable();
mLoadingSrcTriggeringPrincipal = nullptr; mLoadingSrcTriggeringPrincipal = nullptr;
DDLOG(DDLogCategory::Property, "loading_src", ""); DDLOG(DDLogCategory::Property, "loading_src", "");
@@ -2549,6 +2554,10 @@ void HTMLMediaElement::SelectResource() {
!mIsLoadingFromSourceChildren, !mIsLoadingFromSourceChildren,
"Should think we're not loading from source children by default"); "Should think we're not loading from source children by default");
if (!mMediaSource) {
OwnerDoc()->AddMediaElementWithMSE();
}
RemoveMediaElementFromURITable(); RemoveMediaElementFromURITable();
if (!mSrcMediaSource) { if (!mSrcMediaSource) {
mLoadingSrc = uri; mLoadingSrc = uri;
@@ -2812,6 +2821,10 @@ void HTMLMediaElement::LoadFromSourceChildren() {
return; return;
} }
if (!mMediaSource) {
OwnerDoc()->AddMediaElementWithMSE();
}
RemoveMediaElementFromURITable(); RemoveMediaElementFromURITable();
mLoadingSrc = uri; mLoadingSrc = uri;
mLoadingSrcTriggeringPrincipal = childSrc->GetSrcTriggeringPrincipal(); mLoadingSrcTriggeringPrincipal = childSrc->GetSrcTriggeringPrincipal();
@@ -7652,6 +7665,15 @@ bool HTMLMediaElement::IsBeingUsedInPictureInPictureMode() const {
return static_cast<const HTMLVideoElement*>(this)->IsCloningElementVisually(); return static_cast<const HTMLVideoElement*>(this)->IsCloningElementVisually();
} }
void HTMLMediaElement::NodeInfoChanged(Document* aOldDoc) {
if (mMediaSource) {
OwnerDoc()->AddMediaElementWithMSE();
aOldDoc->RemoveMediaElementWithMSE();
}
nsGenericHTMLElement::NodeInfoChanged(aOldDoc);
}
} // namespace mozilla::dom } // namespace mozilla::dom
#undef LOG #undef LOG

View File

@@ -192,6 +192,8 @@ class HTMLMediaElement : public nsGenericHTMLElement,
// EventTarget // EventTarget
void GetEventTargetParent(EventChainPreVisitor& aVisitor) override; void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
void NodeInfoChanged(Document* aOldDoc) override;
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute, virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
const nsAString& aValue, const nsAString& aValue,
nsIPrincipal* aMaybeScriptedPrincipal, nsIPrincipal* aMaybeScriptedPrincipal,

View File

@@ -181,6 +181,11 @@ parent:
async ResetSessionStore(uint32_t aEpoch); async ResetSessionStore(uint32_t aEpoch);
// Add the flags in aOnFlags to the current BFCache status and remove the
// flags in aOffFlags from the current BFCache status. See the BFCacheStatus
// enum for the valid flags.
async UpdateBFCacheStatus(uint16_t aOnFlags, uint16_t aOffFlags);
async Destroy(); async Destroy();
}; };

View File

@@ -671,6 +671,14 @@ bool WindowGlobalChild::SameOriginWithTop() {
return IsSameOriginWith(WindowContext()->TopWindowContext()); return IsSameOriginWith(WindowContext()->TopWindowContext());
} }
void WindowGlobalChild::UnblockBFCacheFor(BFCacheStatus aStatus) {
SendUpdateBFCacheStatus(0, aStatus);
}
void WindowGlobalChild::BlockBFCacheFor(BFCacheStatus aStatus) {
SendUpdateBFCacheStatus(aStatus, 0);
}
WindowGlobalChild::~WindowGlobalChild() = default; WindowGlobalChild::~WindowGlobalChild() = default;
JSObject* WindowGlobalChild::WrapObject(JSContext* aCx, JSObject* WindowGlobalChild::WrapObject(JSContext* aCx,

View File

@@ -12,6 +12,7 @@
#include "mozilla/dom/PWindowGlobalChild.h" #include "mozilla/dom/PWindowGlobalChild.h"
#include "nsRefPtrHashtable.h" #include "nsRefPtrHashtable.h"
#include "nsWrapperCache.h" #include "nsWrapperCache.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/WindowGlobalActor.h" #include "mozilla/dom/WindowGlobalActor.h"
class nsGlobalWindowInner; class nsGlobalWindowInner;
@@ -132,6 +133,9 @@ class WindowGlobalChild final : public WindowGlobalActor,
void SetSessionStoreDataCollector(SessionStoreDataCollector* aCollector); void SetSessionStoreDataCollector(SessionStoreDataCollector* aCollector);
SessionStoreDataCollector* GetSessionStoreDataCollector() const; SessionStoreDataCollector* GetSessionStoreDataCollector() const;
void UnblockBFCacheFor(BFCacheStatus aStatus);
void BlockBFCacheFor(BFCacheStatus aStatus);
protected: protected:
const nsACString& GetRemoteType() override; const nsACString& GetRemoteType() override;

View File

@@ -70,6 +70,7 @@
using namespace mozilla::ipc; using namespace mozilla::ipc;
using namespace mozilla::dom::ipc; using namespace mozilla::dom::ipc;
extern mozilla::LazyLogModule gSHIPBFCacheLog;
extern mozilla::LazyLogModule gUseCountersLog; extern mozilla::LazyLogModule gUseCountersLog;
namespace mozilla::dom { namespace mozilla::dom {
@@ -1315,6 +1316,59 @@ mozilla::ipc::IPCResult WindowGlobalParent::RecvRequestRestoreTabContent() {
return IPC_OK(); return IPC_OK();
} }
nsCString BFCacheStatusToString(uint16_t aFlags) {
if (aFlags == 0) {
return "0"_ns;
}
nsCString flags;
#define ADD_BFCACHESTATUS_TO_STRING(_flag) \
if (aFlags & BFCacheStatus::_flag) { \
if (!flags.IsEmpty()) { \
flags.Append('|'); \
} \
flags.AppendLiteral(#_flag); \
aFlags &= ~BFCacheStatus::_flag; \
}
ADD_BFCACHESTATUS_TO_STRING(NOT_ALLOWED);
ADD_BFCACHESTATUS_TO_STRING(EVENT_HANDLING_SUPPRESSED);
ADD_BFCACHESTATUS_TO_STRING(SUSPENDED);
ADD_BFCACHESTATUS_TO_STRING(UNLOAD_LISTENER);
ADD_BFCACHESTATUS_TO_STRING(REQUEST);
ADD_BFCACHESTATUS_TO_STRING(ACTIVE_GET_USER_MEDIA);
ADD_BFCACHESTATUS_TO_STRING(ACTIVE_PEER_CONNECTION);
ADD_BFCACHESTATUS_TO_STRING(CONTAINS_EME_CONTENT);
ADD_BFCACHESTATUS_TO_STRING(CONTAINS_MSE_CONTENT);
ADD_BFCACHESTATUS_TO_STRING(HAS_ACTIVE_SPEECH_SYNTHESIS);
ADD_BFCACHESTATUS_TO_STRING(HAS_USED_VR);
ADD_BFCACHESTATUS_TO_STRING(CONTAINS_REMOTE_SUBFRAMES);
ADD_BFCACHESTATUS_TO_STRING(NOT_ONLY_TOPLEVEL_IN_BCG);
#undef ADD_BFCACHESTATUS_TO_STRING
MOZ_ASSERT(aFlags == 0,
"Missing stringification for enum value in BFCacheStatus.");
return flags;
}
mozilla::ipc::IPCResult WindowGlobalParent::RecvUpdateBFCacheStatus(
const uint16_t& aOnFlags, const uint16_t& aOffFlags) {
if (MOZ_UNLIKELY(MOZ_LOG_TEST(gSHIPBFCacheLog, LogLevel::Debug))) {
nsAutoCString uri("[no uri]");
if (mDocumentURI) {
uri = mDocumentURI->GetSpecOrDefault();
}
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("Setting BFCache flags for %s +(%s) -(%s)", uri.get(),
BFCacheStatusToString(aOnFlags).get(),
BFCacheStatusToString(aOffFlags).get()));
}
mBFCacheStatus |= aOnFlags;
mBFCacheStatus &= ~aOffFlags;
return IPC_OK();
}
void WindowGlobalParent::ActorDestroy(ActorDestroyReason aWhy) { void WindowGlobalParent::ActorDestroy(ActorDestroyReason aWhy) {
if (mPageUseCountersWindow) { if (mPageUseCountersWindow) {
mPageUseCountersWindow->FinishAccumulatingPageUseCounters(); mPageUseCountersWindow->FinishAccumulatingPageUseCounters();

View File

@@ -280,6 +280,9 @@ class WindowGlobalParent final : public WindowContext,
mozilla::ipc::IPCResult RecvResetSessionStore(uint32_t aEpoch); mozilla::ipc::IPCResult RecvResetSessionStore(uint32_t aEpoch);
mozilla::ipc::IPCResult RecvUpdateBFCacheStatus(const uint16_t& aOnFlags,
const uint16_t& aOffFlags);
private: private:
WindowGlobalParent(CanonicalBrowsingContext* aBrowsingContext, WindowGlobalParent(CanonicalBrowsingContext* aBrowsingContext,
uint64_t aInnerWindowId, uint64_t aOuterWindowId, uint64_t aInnerWindowId, uint64_t aOuterWindowId,
@@ -352,6 +355,8 @@ class WindowGlobalParent final : public WindowContext,
// Whether we have sent our page use counters, and so should ignore any // Whether we have sent our page use counters, and so should ignore any
// subsequent ExpectPageUseCounters calls. // subsequent ExpectPageUseCounters calls.
bool mSentPageUseCounters = false; bool mSentPageUseCounters = false;
uint16_t mBFCacheStatus = 0;
}; };
} // namespace dom } // namespace dom

View File

@@ -38,6 +38,7 @@
#include "mozilla/dom/Promise.h" #include "mozilla/dom/Promise.h"
#include "mozilla/dom/UserActivation.h" #include "mozilla/dom/UserActivation.h"
#include "mozilla/dom/WindowContext.h" #include "mozilla/dom/WindowContext.h"
#include "mozilla/dom/WindowGlobalChild.h"
#include "mozilla/ipc/BackgroundChild.h" #include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/media/MediaChild.h" #include "mozilla/media/MediaChild.h"
#include "mozilla/media/MediaTaskUtils.h" #include "mozilla/media/MediaTaskUtils.h"
@@ -164,6 +165,7 @@ class GetUserMediaStreamTask;
class LocalTrackSource; class LocalTrackSource;
class SelectAudioOutputTask; class SelectAudioOutputTask;
using dom::BFCacheStatus;
using dom::CallerType; using dom::CallerType;
using dom::ConstrainDOMStringParameters; using dom::ConstrainDOMStringParameters;
using dom::ConstrainDoubleRange; using dom::ConstrainDoubleRange;
@@ -191,6 +193,7 @@ using dom::OwningStringOrStringSequenceOrConstrainDOMStringParameters;
using dom::Promise; using dom::Promise;
using dom::Sequence; using dom::Sequence;
using dom::UserActivation; using dom::UserActivation;
using dom::WindowGlobalChild;
using media::NewRunnableFrom; using media::NewRunnableFrom;
using media::NewTaskFrom; using media::NewTaskFrom;
using media::Refcountable; using media::Refcountable;
@@ -3411,9 +3414,21 @@ void MediaManager::AddWindowID(uint64_t aWindowId,
aListener->MuteOrUnmuteCameras(mCamerasMuted); aListener->MuteOrUnmuteCameras(mCamerasMuted);
aListener->MuteOrUnmuteMicrophones(mMicrophonesMuted); aListener->MuteOrUnmuteMicrophones(mMicrophonesMuted);
GetActiveWindows()->InsertOrUpdate(aWindowId, std::move(aListener)); GetActiveWindows()->InsertOrUpdate(aWindowId, std::move(aListener));
RefPtr<WindowGlobalChild> wgc =
WindowGlobalChild::GetByInnerWindowId(aWindowId);
if (wgc) {
wgc->BlockBFCacheFor(BFCacheStatus::ACTIVE_GET_USER_MEDIA);
}
} }
void MediaManager::RemoveWindowID(uint64_t aWindowId) { void MediaManager::RemoveWindowID(uint64_t aWindowId) {
RefPtr<WindowGlobalChild> wgc =
WindowGlobalChild::GetByInnerWindowId(aWindowId);
if (wgc) {
wgc->UnblockBFCacheFor(BFCacheStatus::ACTIVE_GET_USER_MEDIA);
}
mActiveWindows.Remove(aWindowId); mActiveWindows.Remove(aWindowId);
// get outer windowID // get outer windowID

View File

@@ -11,6 +11,7 @@
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
#include "mozilla/dom/SpeechSynthesisBinding.h" #include "mozilla/dom/SpeechSynthesisBinding.h"
#include "mozilla/dom/WindowGlobalChild.h"
#include "SpeechSynthesis.h" #include "SpeechSynthesis.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsSynthVoiceRegistry.h" #include "nsSynthVoiceRegistry.h"
@@ -118,11 +119,18 @@ void SpeechSynthesis::Speak(SpeechSynthesisUtterance& aUtterance) {
mSpeechQueue.AppendElement(&aUtterance); mSpeechQueue.AppendElement(&aUtterance);
// If we only have one item in the queue, we aren't pre-paused, and if (mSpeechQueue.Length() == 1) {
// we have voices available, speak it. RefPtr<WindowGlobalChild> wgc =
if (mSpeechQueue.Length() == 1 && !mCurrentTask && !mHoldQueue && WindowGlobalChild::GetByInnerWindowId(mInnerID);
HasVoices()) { if (wgc) {
AdvanceQueue(); wgc->BlockBFCacheFor(BFCacheStatus::HAS_ACTIVE_SPEECH_SYNTHESIS);
}
// If we only have one item in the queue, we aren't pre-paused, and
// we have voices available, speak it.
if (!mCurrentTask && !mHoldQueue && HasVoices()) {
AdvanceQueue();
}
} }
} }
@@ -201,6 +209,13 @@ void SpeechSynthesis::OnEnd(const nsSpeechTask* aTask) {
if (!mSpeechQueue.IsEmpty()) { if (!mSpeechQueue.IsEmpty()) {
mSpeechQueue.RemoveElementAt(0); mSpeechQueue.RemoveElementAt(0);
if (mSpeechQueue.IsEmpty()) {
RefPtr<WindowGlobalChild> wgc =
WindowGlobalChild::GetByInnerWindowId(mInnerID);
if (wgc) {
wgc->UnblockBFCacheFor(BFCacheStatus::HAS_ACTIVE_SPEECH_SYNTHESIS);
}
}
} }
mCurrentTask = nullptr; mCurrentTask = nullptr;