Bug 1262053 - part1 : unblock window's media when the page was first visited.
MozReview-Commit-ID: sXhv0QJEYc
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1465,16 +1465,18 @@ nsDocument::nsDocument(const char* aCont
// void state used to differentiate an empty source from an unselected source
mPreloadPictureFoundSource.SetIsVoid(true);
if (!sProcessingStack) {
sProcessingStack.emplace();
// Add the base queue sentinel to the processing stack.
sProcessingStack->AppendElement((CustomElementData*) nullptr);
}
+
+ mEverInForeground = false;
}
void
nsDocument::ClearAllBoxObjects()
{
if (mBoxObjectTable) {
for (auto iter = mBoxObjectTable->Iter(); !iter.Done(); iter.Next()) {
nsPIBoxObject* boxObject = iter.UserData();
@@ -12562,16 +12564,20 @@ nsDocument::UpdateVisibilityState()
/* cancelable = */ false);
nsContentUtils::DispatchTrustedEvent(this, static_cast<nsIDocument*>(this),
NS_LITERAL_STRING("mozvisibilitychange"),
/* bubbles = */ true,
/* cancelable = */ false);
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
}
+
+ if (mVisibilityState == dom::VisibilityState::Visible) {
+ MaybeActiveMediaComponents();
+ }
}
VisibilityState
nsDocument::GetVisibilityState() const
{
// We have to check a few pieces of information here:
// 1) Are we in bfcache (!IsVisible())? If so, nothing else matters.
// 2) Do we have an outer window? If not, we're hidden. Note that we don't
@@ -12597,16 +12603,33 @@ nsDocument::GetVisibilityState() const
/* virtual */ void
nsDocument::PostVisibilityUpdateEvent()
{
nsCOMPtr<nsIRunnable> event =
NewRunnableMethod(this, &nsDocument::UpdateVisibilityState);
NS_DispatchToMainThread(event);
}
+void
+nsDocument::MaybeActiveMediaComponents()
+{
+ if (mEverInForeground) {
+ return;
+ }
+
+ if (!mWindow) {
+ return;
+ }
+
+ mEverInForeground = true;
+ if (GetWindow()->GetMediaSuspend() == nsISuspendedTypes::SUSPENDED_BLOCK) {
+ GetWindow()->SetMediaSuspend(nsISuspendedTypes::NONE_SUSPENDED);
+ }
+}
+
NS_IMETHODIMP
nsDocument::GetMozHidden(bool* aHidden)
{
*aHidden = MozHidden();
return NS_OK;
}
NS_IMETHODIMP
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -1204,16 +1204,20 @@ public:
mozilla::dom::Promise* GetOrientationPendingPromise() const override;
// This method may fire a DOM event; if it does so it will happen
// synchronously.
void UpdateVisibilityState();
// Posts an event to call UpdateVisibilityState
virtual void PostVisibilityUpdateEvent() override;
+ // Since we wouldn't automatically play media from non-visited page, we need
+ // to notify window when the page was first visited.
+ void MaybeActiveMediaComponents();
+
virtual void DocAddSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const override;
// DocAddSizeOfIncludingThis is inherited from nsIDocument.
virtual nsIDOMNode* AsDOMNode() override { return this; }
virtual void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
Element* aCustomElement,
mozilla::dom::LifecycleCallbackArgs* aArgs = nullptr,
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -613,17 +613,18 @@ nsPIDOMWindow<T>::nsPIDOMWindow(nsPIDOMW
mRunningTimeout(nullptr), mMutationBits(0), mIsDocumentLoaded(false),
mIsHandlingResizeEvent(false), mIsInnerWindow(aOuterWindow != nullptr),
mMayHavePaintEventListener(false), mMayHaveTouchEventListener(false),
mMayHaveMouseEnterLeaveEventListener(false),
mMayHavePointerEnterLeaveEventListener(false),
mInnerObjectsFreed(false),
mIsModalContentWindow(false),
mIsActive(false), mIsBackground(false),
- mMediaSuspend(nsISuspendedTypes::NONE_SUSPENDED),
+ mMediaSuspend(Preferences::GetBool("media.block-autoplay-until-in-foreground", true) ?
+ nsISuspendedTypes::SUSPENDED_BLOCK : nsISuspendedTypes::NONE_SUSPENDED),
mAudioMuted(false), mAudioVolume(1.0), mAudioCaptured(false),
mDesktopModeViewport(false), mInnerWindow(nullptr),
mOuterWindow(aOuterWindow),
// Make sure no actual window ends up with mWindowID == 0
mWindowID(NextWindowID()), mHasNotifiedGlobalCreated(false),
mMarkedCCGeneration(0), mServiceWorkersTestingEnabled(false)
{}
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -3064,16 +3064,19 @@ protected:
bool mFontFaceSetDirty : 1;
// Has GetUserFontSet() been called?
bool mGetUserFontSetCalled : 1;
// Do we currently have an event posted to call FlushUserFontSet?
bool mPostedFlushUserFontSet : 1;
+ // True is document has ever been in a foreground window.
+ bool mEverInForeground : 1;
+
enum Type {
eUnknown, // should never be used
eHTML,
eXHTML,
eGenericXML,
eSVG,
eXUL
};
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5498,16 +5498,17 @@ pref("media.seekToNextFrame.enabled", tr
pref("osfile.reset_worker_delay", 30000);
#endif
#if !defined(MOZ_WIDGET_GONK) && !defined(MOZ_WIDGET_ANDROID)
pref("dom.webkitBlink.dirPicker.enabled", true);
pref("dom.webkitBlink.filesystem.enabled", true);
#endif
+pref("media.block-autoplay-until-in-foreground", true);
#ifdef MOZ_STYLO
// Is the Servo-backed style system enabled?
pref("layout.css.servo.enabled", true);
#endif
#ifdef NIGHTLY_BUILD
pref("dom.html_fragment_serialisation.appendLF", true);
#else