Backed out 3 changesets (bug 1648887, bug 1611961) for assertion failures on WindowContext.cpp. CLOSED TREE

Backed out changeset 3719f7db339d (bug 1648887)
Backed out changeset b7c7fcb5df37 (bug 1648887)
Backed out changeset ab82a9c613f8 (bug 1611961)
This commit is contained in:
Csoregi Natalia 2020-08-06 17:43:51 +03:00
parent f914e7976e
commit 8fa5e9e957
16 changed files with 133 additions and 206 deletions

View File

@ -1068,9 +1068,7 @@ bool BrowsingContext::IsSandboxedFrom(BrowsingContext* aTarget) {
// If SANDBOXED_TOPLEVEL_NAVIGATION_USER_ACTIVATION flag is not on, we are not // If SANDBOXED_TOPLEVEL_NAVIGATION_USER_ACTIVATION flag is not on, we are not
// sandboxed from our top if we have user interaction. // sandboxed from our top if we have user interaction.
if (!(sandboxFlags & SANDBOXED_TOPLEVEL_NAVIGATION_USER_ACTIVATION) && if (!(sandboxFlags & SANDBOXED_TOPLEVEL_NAVIGATION_USER_ACTIVATION) &&
mCurrentWindowContext && HasValidTransientUserGestureActivation() && aTarget == Top()) {
mCurrentWindowContext->HasValidTransientUserGestureActivation() &&
aTarget == Top()) {
return false; return false;
} }
@ -1161,6 +1159,60 @@ JSObject* BrowsingContext::ReadStructuredClone(JSContext* aCx,
return val.toObjectOrNull(); return val.toObjectOrNull();
} }
void BrowsingContext::NotifyUserGestureActivation() {
// Return value of setting synced field should be checked. See bug 1656492.
Unused << SetUserActivationState(UserActivation::State::FullActivated);
}
void BrowsingContext::NotifyResetUserGestureActivation() {
// Return value of setting synced field should be checked. See bug 1656492.
Unused << SetUserActivationState(UserActivation::State::None);
}
bool BrowsingContext::HasBeenUserGestureActivated() {
return GetUserActivationState() != UserActivation::State::None;
}
bool BrowsingContext::HasValidTransientUserGestureActivation() {
MOZ_ASSERT(mIsInProcess);
if (GetUserActivationState() != UserActivation::State::FullActivated) {
MOZ_ASSERT(mUserGestureStart.IsNull(),
"mUserGestureStart should be null if the document hasn't ever "
"been activated by user gesture");
return false;
}
MOZ_ASSERT(!mUserGestureStart.IsNull(),
"mUserGestureStart shouldn't be null if the document has ever "
"been activated by user gesture");
TimeDuration timeout = TimeDuration::FromMilliseconds(
StaticPrefs::dom_user_activation_transient_timeout());
return timeout <= TimeDuration() ||
(TimeStamp::Now() - mUserGestureStart) <= timeout;
}
bool BrowsingContext::ConsumeTransientUserGestureActivation() {
MOZ_ASSERT(mIsInProcess);
if (!HasValidTransientUserGestureActivation()) {
return false;
}
BrowsingContext* top = Top();
top->PreOrderWalk([&](BrowsingContext* aContext) {
if (aContext->GetUserActivationState() ==
UserActivation::State::FullActivated) {
// Updating user activation state on a discarded context has no effect.
Unused << aContext->SetUserActivationState(
UserActivation::State::HasBeenActivated);
}
});
return true;
}
bool BrowsingContext::CanSetOriginAttributes() { bool BrowsingContext::CanSetOriginAttributes() {
// A discarded BrowsingContext has already been destroyed, and cannot modify // A discarded BrowsingContext has already been destroyed, and cannot modify
// its OriginAttributes. // its OriginAttributes.
@ -1998,6 +2050,23 @@ void BrowsingContext::DidSet(FieldIndex<IDX_GVInaudibleAutoplayRequestStatus>) {
"browsing context"); "browsing context");
} }
void BrowsingContext::DidSet(FieldIndex<IDX_UserActivationState>) {
MOZ_ASSERT_IF(!mIsInProcess, mUserGestureStart.IsNull());
USER_ACTIVATION_LOG("Set user gesture activation %" PRIu8
" for %s browsing context 0x%08" PRIx64,
static_cast<uint8_t>(GetUserActivationState()),
XRE_IsParentProcess() ? "Parent" : "Child", Id());
if (mIsInProcess) {
USER_ACTIVATION_LOG(
"Set user gesture start time for %s browsing context 0x%08" PRIx64,
XRE_IsParentProcess() ? "Parent" : "Child", Id());
mUserGestureStart =
(GetUserActivationState() == UserActivation::State::FullActivated)
? TimeStamp::Now()
: TimeStamp();
}
}
void BrowsingContext::DidSet(FieldIndex<IDX_IsActive>, bool aOldValue) { void BrowsingContext::DidSet(FieldIndex<IDX_IsActive>, bool aOldValue) {
if (!IsTop() || aOldValue == GetIsActive() || if (!IsTop() || aOldValue == GetIsActive() ||
!StaticPrefs::dom_suspend_inactive_enabled()) { !StaticPrefs::dom_suspend_inactive_enabled()) {

View File

@ -495,6 +495,29 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
JSObject* WrapObject(JSContext* aCx, JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override; JS::Handle<JSObject*> aGivenProto) override;
// This function would be called when its corresponding document is activated
// by user gesture, and we would set the flag in the top level browsing
// context.
void NotifyUserGestureActivation();
// This function would be called when we want to reset the user gesture
// activation flag of the top level browsing context.
void NotifyResetUserGestureActivation();
// Return true if its corresponding document has been activated by user
// gesture.
bool HasBeenUserGestureActivated();
// Return true if its corresponding document has transient user gesture
// activation and the transient user gesture activation haven't yet timed
// out.
bool HasValidTransientUserGestureActivation();
// Return true if the corresponding document has valid transient user gesture
// activation and the transient user gesture activation had been consumed
// successfully.
bool ConsumeTransientUserGestureActivation();
// Return the window proxy object that corresponds to this browsing context. // Return the window proxy object that corresponds to this browsing context.
inline JSObject* GetWindowProxy() const { return mWindowProxy; } inline JSObject* GetWindowProxy() const { return mWindowProxy; }
inline JSObject* GetUnbarrieredWindowProxy() const { inline JSObject* GetUnbarrieredWindowProxy() const {
@ -704,6 +727,7 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
return true; return true;
} }
void DidSet(FieldIndex<IDX_UserActivationState>);
void DidSet(FieldIndex<IDX_IsActive>, bool aOldValue); void DidSet(FieldIndex<IDX_IsActive>, bool aOldValue);
// Ensure that we only set the flag on the top level browsingContext. // Ensure that we only set the flag on the top level browsingContext.

View File

@ -395,15 +395,14 @@ void CanonicalBrowsingContext::CanonicalDiscard() {
} }
void CanonicalBrowsingContext::NotifyStartDelayedAutoplayMedia() { void CanonicalBrowsingContext::NotifyStartDelayedAutoplayMedia() {
WindowContext* windowContext = GetCurrentWindowContext(); if (!GetCurrentWindowGlobal()) {
if (!windowContext) {
return; return;
} }
// As this function would only be called when user click the play icon on the // As this function would only be called when user click the play icon on the
// tab bar. That's clear user intent to play, so gesture activate the window // tab bar. That's clear user intent to play, so gesture activate the browsing
// context so that the block-autoplay logic allows the media to autoplay. // context so that the block-autoplay logic allows the media to autoplay.
windowContext->NotifyUserGestureActivation(); NotifyUserGestureActivation();
AUTOPLAY_LOG("NotifyStartDelayedAutoplayMedia for chrome bc 0x%08" PRIx64, AUTOPLAY_LOG("NotifyStartDelayedAutoplayMedia for chrome bc 0x%08" PRIx64,
Id()); Id());
StartDelayedAutoplayMediaComponents(); StartDelayedAutoplayMediaComponents();

View File

@ -10,7 +10,6 @@
#include "mozilla/dom/WindowGlobalParent.h" #include "mozilla/dom/WindowGlobalParent.h"
#include "mozilla/dom/SyncedContextInlines.h" #include "mozilla/dom/SyncedContextInlines.h"
#include "mozilla/dom/BrowsingContext.h" #include "mozilla/dom/BrowsingContext.h"
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/StaticPtr.h" #include "mozilla/StaticPtr.h"
#include "mozilla/ClearOnShutdown.h" #include "mozilla/ClearOnShutdown.h"
#include "nsIScriptError.h" #include "nsIScriptError.h"
@ -26,11 +25,6 @@ template class syncedcontext::Transaction<WindowContext>;
static LazyLogModule gWindowContextLog("WindowContext"); static LazyLogModule gWindowContextLog("WindowContext");
extern mozilla::LazyLogModule gUserInteractionPRLog;
#define USER_ACTIVATION_LOG(msg, ...) \
MOZ_LOG(gUserInteractionPRLog, LogLevel::Debug, (msg, ##__VA_ARGS__))
using WindowContextByIdMap = nsDataHashtable<nsUint64HashKey, WindowContext*>; using WindowContextByIdMap = nsDataHashtable<nsUint64HashKey, WindowContext*>;
static StaticAutoPtr<WindowContextByIdMap> gWindowContexts; static StaticAutoPtr<WindowContextByIdMap> gWindowContexts;
@ -197,23 +191,6 @@ bool WindowContext::CanSet(
return CheckOnlyOwningProcessCanSet(aSource); return CheckOnlyOwningProcessCanSet(aSource);
} }
void WindowContext::DidSet(FieldIndex<IDX_UserActivationState>) {
MOZ_ASSERT_IF(!mInProcess, mUserGestureStart.IsNull());
USER_ACTIVATION_LOG("Set user gesture activation %" PRIu8
" for %s browsing context 0x%08" PRIx64,
static_cast<uint8_t>(GetUserActivationState()),
XRE_IsParentProcess() ? "Parent" : "Child", Id());
if (mInProcess) {
USER_ACTIVATION_LOG(
"Set user gesture start time for %s browsing context 0x%08" PRIx64,
XRE_IsParentProcess() ? "Parent" : "Child", Id());
mUserGestureStart =
(GetUserActivationState() == UserActivation::State::FullActivated)
? TimeStamp::Now()
: TimeStamp();
}
}
void WindowContext::DidSet(FieldIndex<IDX_HasReportedShadowDOMUsage>, void WindowContext::DidSet(FieldIndex<IDX_HasReportedShadowDOMUsage>,
bool aOldValue) { bool aOldValue) {
if (!aOldValue && GetHasReportedShadowDOMUsage() && IsInProcess()) { if (!aOldValue && GetHasReportedShadowDOMUsage() && IsInProcess()) {
@ -305,59 +282,6 @@ void WindowContext::AddMixedContentSecurityState(uint32_t aStateFlags) {
} }
} }
void WindowContext::NotifyUserGestureActivation() {
Unused << SetUserActivationState(UserActivation::State::FullActivated);
}
void WindowContext::NotifyResetUserGestureActivation() {
Unused << SetUserActivationState(UserActivation::State::None);
}
bool WindowContext::HasBeenUserGestureActivated() {
return GetUserActivationState() != UserActivation::State::None;
}
bool WindowContext::HasValidTransientUserGestureActivation() {
MOZ_ASSERT(mInProcess);
if (GetUserActivationState() != UserActivation::State::FullActivated) {
MOZ_ASSERT(mUserGestureStart.IsNull(),
"mUserGestureStart should be null if the document hasn't ever "
"been activated by user gesture");
return false;
}
MOZ_ASSERT(!mUserGestureStart.IsNull(),
"mUserGestureStart shouldn't be null if the document has ever "
"been activated by user gesture");
TimeDuration timeout = TimeDuration::FromMilliseconds(
StaticPrefs::dom_user_activation_transient_timeout());
return timeout <= TimeDuration() ||
(TimeStamp::Now() - mUserGestureStart) <= timeout;
}
bool WindowContext::ConsumeTransientUserGestureActivation() {
MOZ_ASSERT(mInProcess);
MOZ_ASSERT(!IsCached());
if (!HasValidTransientUserGestureActivation()) {
return false;
}
BrowsingContext* top = mBrowsingContext->Top();
top->PreOrderWalk([&](BrowsingContext* aBrowsingContext) {
WindowContext* windowContext = aBrowsingContext->GetCurrentWindowContext();
if (windowContext && windowContext->GetUserActivationState() ==
UserActivation::State::FullActivated) {
Unused << windowContext->SetUserActivationState(
UserActivation::State::HasBeenActivated);
}
});
return true;
}
WindowContext::IPCInitializer WindowContext::GetIPCInitializer() { WindowContext::IPCInitializer WindowContext::GetIPCInitializer() {
IPCInitializer init; IPCInitializer init;
init.mInnerWindowId = mInnerWindowId; init.mInnerWindowId = mInnerWindowId;

View File

@ -11,7 +11,6 @@
#include "mozilla/Span.h" #include "mozilla/Span.h"
#include "mozilla/dom/MaybeDiscarded.h" #include "mozilla/dom/MaybeDiscarded.h"
#include "mozilla/dom/SyncedContext.h" #include "mozilla/dom/SyncedContext.h"
#include "mozilla/dom/UserActivation.h"
#include "nsILoadInfo.h" #include "nsILoadInfo.h"
#include "nsWrapperCache.h" #include "nsWrapperCache.h"
@ -52,9 +51,6 @@ class BrowsingContextGroup;
/* Whether the user has overriden the mixed content blocker to allow \ /* Whether the user has overriden the mixed content blocker to allow \
* mixed content loads to happen */ \ * mixed content loads to happen */ \
FIELD(AllowMixedContent, bool) \ FIELD(AllowMixedContent, bool) \
/* Controls whether the WindowContext is currently considered to be \
* activated by a gesture */ \
FIELD(UserActivationState, UserActivation::State) \
FIELD(EmbedderPolicy, nsILoadInfo::CrossOriginEmbedderPolicy) \ FIELD(EmbedderPolicy, nsILoadInfo::CrossOriginEmbedderPolicy) \
/* True if this document tree contained an HTMLMediaElement that \ /* True if this document tree contained an HTMLMediaElement that \
* played audibly. This should only be set on top level context. */ \ * played audibly. This should only be set on top level context. */ \
@ -121,28 +117,6 @@ class WindowContext : public nsISupports, public nsWrapperCache {
// top window context. // top window context.
void AddMixedContentSecurityState(uint32_t aStateFlags); void AddMixedContentSecurityState(uint32_t aStateFlags);
// This function would be called when its corresponding window is activated
// by user gesture.
void NotifyUserGestureActivation();
// This function would be called when we want to reset the user gesture
// activation flag.
void NotifyResetUserGestureActivation();
// Return true if its corresponding window has been activated by user
// gesture.
bool HasBeenUserGestureActivated();
// Return true if its corresponding window has transient user gesture
// activation and the transient user gesture activation haven't yet timed
// out.
bool HasValidTransientUserGestureActivation();
// Return true if the corresponding window has valid transient user gesture
// activation and the transient user gesture activation had been consumed
// successfully.
bool ConsumeTransientUserGestureActivation();
protected: protected:
WindowContext(BrowsingContext* aBrowsingContext, uint64_t aInnerWindowId, WindowContext(BrowsingContext* aBrowsingContext, uint64_t aInnerWindowId,
uint64_t aOuterWindowId, bool aInProcess, uint64_t aOuterWindowId, bool aInProcess,
@ -207,11 +181,6 @@ class WindowContext : public nsISupports, public nsWrapperCache {
bool CanSet(FieldIndex<IDX_DelegatedExactHostMatchPermissions>, bool CanSet(FieldIndex<IDX_DelegatedExactHostMatchPermissions>,
const PermissionDelegateHandler::DelegatedPermissionList& aValue, const PermissionDelegateHandler::DelegatedPermissionList& aValue,
ContentParent* aSource); ContentParent* aSource);
bool CanSet(FieldIndex<IDX_UserActivationState>,
const UserActivation::State& aUserActivationState,
ContentParent* aSource) {
return true;
}
bool CanSet(FieldIndex<IDX_HasReportedShadowDOMUsage>, const bool& aValue, bool CanSet(FieldIndex<IDX_HasReportedShadowDOMUsage>, const bool& aValue,
ContentParent* aSource) { ContentParent* aSource) {
@ -226,7 +195,6 @@ class WindowContext : public nsISupports, public nsWrapperCache {
void DidSet(FieldIndex<I>) {} void DidSet(FieldIndex<I>) {}
template <size_t I, typename T> template <size_t I, typename T>
void DidSet(FieldIndex<I>, T&& aOldValue) {} void DidSet(FieldIndex<I>, T&& aOldValue) {}
void DidSet(FieldIndex<IDX_UserActivationState>);
uint64_t mInnerWindowId; uint64_t mInnerWindowId;
uint64_t mOuterWindowId; uint64_t mOuterWindowId;
@ -240,10 +208,6 @@ class WindowContext : public nsISupports, public nsWrapperCache {
bool mIsDiscarded = false; bool mIsDiscarded = false;
bool mInProcess = false; bool mInProcess = false;
// The start time of user gesture, this is only available if the window
// context is in process.
TimeStamp mUserGestureStart;
}; };
using WindowContextTransaction = WindowContext::BaseTransaction; using WindowContextTransaction = WindowContext::BaseTransaction;

View File

@ -3795,7 +3795,6 @@ nsresult nsDocShell::LoadErrorPage(nsIURI* aErrorURI, nsIURI* aFailedURI,
mLSHE->AbandonBFCacheEntry(); mLSHE->AbandonBFCacheEntry();
} }
RefPtr<WindowContext> context = mBrowsingContext->GetCurrentWindowContext();
RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(aErrorURI); RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(aErrorURI);
loadState->SetTriggeringPrincipal(nsContentUtils::GetSystemPrincipal()); loadState->SetTriggeringPrincipal(nsContentUtils::GetSystemPrincipal());
if (mBrowsingContext) { if (mBrowsingContext) {
@ -3805,7 +3804,8 @@ nsresult nsDocShell::LoadErrorPage(nsIURI* aErrorURI, nsIURI* aFailedURI,
loadState->SetFirstParty(true); loadState->SetFirstParty(true);
loadState->SetSourceBrowsingContext(mBrowsingContext); loadState->SetSourceBrowsingContext(mBrowsingContext);
loadState->SetHasValidUserGestureActivation( loadState->SetHasValidUserGestureActivation(
context && context->HasValidTransientUserGestureActivation()); mBrowsingContext &&
mBrowsingContext->HasValidTransientUserGestureActivation());
return InternalLoad(loadState); return InternalLoad(loadState);
} }
@ -3939,7 +3939,6 @@ nsresult nsDocShell::ReloadDocument(nsDocShell* aDocShell, Document* aDocument,
Maybe<nsCOMPtr<nsIURI>> emplacedResultPrincipalURI; Maybe<nsCOMPtr<nsIURI>> emplacedResultPrincipalURI;
emplacedResultPrincipalURI.emplace(std::move(resultPrincipalURI)); emplacedResultPrincipalURI.emplace(std::move(resultPrincipalURI));
RefPtr<WindowContext> context = aBrowsingContext->GetCurrentWindowContext();
RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(currentURI); RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(currentURI);
loadState->SetReferrerInfo(aReferrerInfo); loadState->SetReferrerInfo(aReferrerInfo);
loadState->SetOriginalURI(originalURI); loadState->SetOriginalURI(originalURI);
@ -3957,7 +3956,8 @@ nsresult nsDocShell::ReloadDocument(nsDocShell* aDocShell, Document* aDocument,
loadState->SetSourceBrowsingContext(aBrowsingContext); loadState->SetSourceBrowsingContext(aBrowsingContext);
loadState->SetBaseURI(baseURI); loadState->SetBaseURI(baseURI);
loadState->SetHasValidUserGestureActivation( loadState->SetHasValidUserGestureActivation(
context && context->HasValidTransientUserGestureActivation()); aBrowsingContext &&
aBrowsingContext->HasValidTransientUserGestureActivation());
return aDocShell->InternalLoad(loadState); return aDocShell->InternalLoad(loadState);
} }
@ -9688,12 +9688,11 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
Maybe<mozilla::dom::ClientInfo>(), Maybe<mozilla::dom::ClientInfo>(),
Maybe<mozilla::dom::ServiceWorkerDescriptor>(), Maybe<mozilla::dom::ServiceWorkerDescriptor>(),
sandboxFlags); sandboxFlags);
RefPtr<WindowContext> context = mBrowsingContext->GetCurrentWindowContext();
// in case this docshell load was triggered by a valid transient user gesture, // in case this docshell load was triggered by a valid transient user gesture,
// or also the load originates from external, then we pass that information on // or also the load originates from external, then we pass that information on
// to the loadinfo, which allows e.g. setting Sec-Fetch-User request headers. // to the loadinfo, which allows e.g. setting Sec-Fetch-User request headers.
if ((context && context->HasValidTransientUserGestureActivation()) || if (mBrowsingContext->HasValidTransientUserGestureActivation() ||
aLoadState->HasValidUserGestureActivation() || aLoadState->HasValidUserGestureActivation() ||
aLoadState->HasLoadFlags(LOAD_FLAGS_FROM_EXTERNAL)) { aLoadState->HasLoadFlags(LOAD_FLAGS_FROM_EXTERNAL)) {
loadInfo->SetHasValidUserGestureActivation(true); loadInfo->SetHasValidUserGestureActivation(true);
@ -12099,7 +12098,6 @@ nsresult nsDocShell::OnLinkClickSync(nsIContent* aContent,
nsCOMPtr<nsIReferrerInfo> referrerInfo = nsCOMPtr<nsIReferrerInfo> referrerInfo =
isElementAnchorOrArea ? new ReferrerInfo(*aContent->AsElement()) isElementAnchorOrArea ? new ReferrerInfo(*aContent->AsElement())
: new ReferrerInfo(*referrerDoc); : new ReferrerInfo(*referrerDoc);
RefPtr<WindowContext> context = mBrowsingContext->GetCurrentWindowContext();
aLoadState->SetTriggeringSandboxFlags(triggeringSandboxFlags); aLoadState->SetTriggeringSandboxFlags(triggeringSandboxFlags);
aLoadState->SetReferrerInfo(referrerInfo); aLoadState->SetReferrerInfo(referrerInfo);
@ -12108,7 +12106,8 @@ nsresult nsDocShell::OnLinkClickSync(nsIContent* aContent,
aLoadState->SetLoadType(loadType); aLoadState->SetLoadType(loadType);
aLoadState->SetSourceBrowsingContext(mBrowsingContext); aLoadState->SetSourceBrowsingContext(mBrowsingContext);
aLoadState->SetHasValidUserGestureActivation( aLoadState->SetHasValidUserGestureActivation(
context && context->HasValidTransientUserGestureActivation()); mBrowsingContext &&
mBrowsingContext->HasValidTransientUserGestureActivation());
nsresult rv = InternalLoad(aLoadState); nsresult rv = InternalLoad(aLoadState);

View File

@ -124,6 +124,7 @@ support-files =
file_history_length_during_pageload_2.html file_history_length_during_pageload_2.html
[test_pushState_after_document_open.html] [test_pushState_after_document_open.html]
[test_navigate_after_pagehide.html] [test_navigate_after_pagehide.html]
skip-if = debug # Bug 1648887
[test_windowedhistoryframes.html] [test_windowedhistoryframes.html]
skip-if = !debug && os == 'android' # Bug 1573892 skip-if = !debug && os == 'android' # Bug 1573892
[test_triggeringprincipal_location_seturi.html] [test_triggeringprincipal_location_seturi.html]

View File

@ -15268,13 +15268,8 @@ BrowsingContext* Document::GetBrowsingContext() const {
void Document::NotifyUserGestureActivation() { void Document::NotifyUserGestureActivation() {
if (RefPtr<BrowsingContext> bc = GetBrowsingContext()) { if (RefPtr<BrowsingContext> bc = GetBrowsingContext()) {
bc->PreOrderWalk([&](BrowsingContext* aBC) { bc->PreOrderWalk([&](BrowsingContext* aContext) {
WindowContext* windowContext = aBC->GetCurrentWindowContext(); nsIDocShell* docShell = aContext->GetDocShell();
if (!windowContext) {
return;
}
nsIDocShell* docShell = aBC->GetDocShell();
if (!docShell) { if (!docShell) {
return; return;
} }
@ -15287,42 +15282,38 @@ void Document::NotifyUserGestureActivation() {
// XXXedgar we probably could just check `IsInProcess()` after fission // XXXedgar we probably could just check `IsInProcess()` after fission
// enable. // enable.
if (NodePrincipal()->Equals(document->NodePrincipal())) { if (NodePrincipal()->Equals(document->NodePrincipal())) {
windowContext->NotifyUserGestureActivation(); aContext->NotifyUserGestureActivation();
} }
}); });
for (bc = bc->GetParent(); bc; bc = bc->GetParent()) { for (bc = bc->GetParent(); bc; bc = bc->GetParent()) {
if (WindowContext* windowContext = bc->GetCurrentWindowContext()) { bc->NotifyUserGestureActivation();
windowContext->NotifyUserGestureActivation();
}
} }
} }
} }
bool Document::HasBeenUserGestureActivated() { bool Document::HasBeenUserGestureActivated() {
RefPtr<WindowContext> wc = GetWindowContext(); RefPtr<BrowsingContext> bc = GetBrowsingContext();
return wc && wc->HasBeenUserGestureActivated(); return bc && bc->HasBeenUserGestureActivated();
} }
void Document::ClearUserGestureActivation() { void Document::ClearUserGestureActivation() {
if (RefPtr<BrowsingContext> bc = GetBrowsingContext()) { if (RefPtr<BrowsingContext> bc = GetBrowsingContext()) {
bc = bc->Top(); bc = bc->Top();
bc->PreOrderWalk([&](BrowsingContext* aBC) { bc->PreOrderWalk([&](BrowsingContext* aContext) {
if (WindowContext* windowContext = aBC->GetCurrentWindowContext()) { aContext->NotifyResetUserGestureActivation();
windowContext->NotifyResetUserGestureActivation();
}
}); });
} }
} }
bool Document::HasValidTransientUserGestureActivation() { bool Document::HasValidTransientUserGestureActivation() {
RefPtr<WindowContext> wc = GetWindowContext(); RefPtr<BrowsingContext> bc = GetBrowsingContext();
return wc && wc->HasValidTransientUserGestureActivation(); return bc && bc->HasValidTransientUserGestureActivation();
} }
bool Document::ConsumeTransientUserGestureActivation() { bool Document::ConsumeTransientUserGestureActivation() {
RefPtr<WindowContext> wc = GetWindowContext(); RefPtr<BrowsingContext> bc = GetBrowsingContext();
return wc && wc->ConsumeTransientUserGestureActivation(); return bc && bc->ConsumeTransientUserGestureActivation();
} }
void Document::SetDocTreeHadAudibleMedia() { void Document::SetDocTreeHadAudibleMedia() {

View File

@ -16,7 +16,6 @@
#include "nsGlobalWindow.h" #include "nsGlobalWindow.h"
#include "mozilla/NullPrincipal.h" #include "mozilla/NullPrincipal.h"
#include "mozilla/dom/Document.h" #include "mozilla/dom/Document.h"
#include "mozilla/dom/WindowContext.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@ -134,10 +133,10 @@ void LocationBase::SetURI(nsIURI* aURI, nsIPrincipal& aSubjectPrincipal,
nsCOMPtr<nsPIDOMWindowInner> sourceWindow = nsCOMPtr<nsPIDOMWindowInner> sourceWindow =
nsContentUtils::CallerInnerWindow(); nsContentUtils::CallerInnerWindow();
if (sourceWindow) { if (sourceWindow) {
WindowContext* context = sourceWindow->GetWindowContext(); RefPtr<BrowsingContext> sourceBC = sourceWindow->GetBrowsingContext();
loadState->SetSourceBrowsingContext(sourceWindow->GetBrowsingContext()); loadState->SetSourceBrowsingContext(sourceBC);
loadState->SetHasValidUserGestureActivation( loadState->SetHasValidUserGestureActivation(
context && context->HasValidTransientUserGestureActivation()); sourceBC && sourceBC->HasValidTransientUserGestureActivation());
} }
loadState->SetLoadFlags(nsIWebNavigation::LOAD_FLAGS_NONE); loadState->SetLoadFlags(nsIWebNavigation::LOAD_FLAGS_NONE);

View File

@ -1612,9 +1612,6 @@ void nsGlobalWindowInner::InitDocumentDependentState(JSContext* aCx) {
if (!mWindowGlobalChild) { if (!mWindowGlobalChild) {
mWindowGlobalChild = WindowGlobalChild::Create(this); mWindowGlobalChild = WindowGlobalChild::Create(this);
} }
MOZ_ASSERT(!GetWindowContext()->HasBeenUserGestureActivated(),
"WindowContext should always not have user gesture activation at "
"this point.");
UpdateAutoplayPermission(); UpdateAutoplayPermission();
UpdateShortcutsPermission(); UpdateShortcutsPermission();
@ -1626,6 +1623,10 @@ void nsGlobalWindowInner::InitDocumentDependentState(JSContext* aCx) {
permDelegateHandler->PopulateAllDelegatedPermissions(); permDelegateHandler->PopulateAllDelegatedPermissions();
} }
if (mWindowGlobalChild && GetBrowsingContext()) {
GetBrowsingContext()->NotifyResetUserGestureActivation();
}
#if defined(MOZ_WIDGET_ANDROID) #if defined(MOZ_WIDGET_ANDROID)
// When we insert the new document to the window in the top-level browsing // When we insert the new document to the window in the top-level browsing
// context, we should reset the status of the request which is used for the // context, we should reset the status of the request which is used for the

View File

@ -637,7 +637,6 @@ support-files = file_bug1100912.html
[test_bug1499169.html] [test_bug1499169.html]
skip-if = toolkit == 'android' # Timeouts on android due to page closing issues with embedded pdf skip-if = toolkit == 'android' # Timeouts on android due to page closing issues with embedded pdf
[test_bug1576154.html] [test_bug1576154.html]
[test_bug1648887.html]
[test_caretPositionFromPoint.html] [test_caretPositionFromPoint.html]
[test_change_policy.html] [test_change_policy.html]
[test_clearTimeoutIntervalNoArg.html] [test_clearTimeoutIntervalNoArg.html]

View File

@ -1,34 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1648887
-->
<head>
<title>Test for Bug 1648887</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1648887">Mozilla Bug 1648887</a>
<p id="display"></p>
<iframe srcdoc="<a id='a' href='http://w'>"></iframe>
<script class="testbody" type="text/javascript">
/** Test for Bug 1648887 **/
add_task(async function test() {
await SpecialPowers.pushPrefEnv({
set: [
["dom.disable_open_during_load", false],
],
});
let iframe = document.querySelector("iframe");
iframe.contentDocument.getElementById('a').click();
iframe.contentWindow.open(document.createElement('r').outerHTML,'','h').close();
ok(true, "Should not crash");
});
</script>
</pre>
</body>
</html>

View File

@ -78,9 +78,8 @@ static bool IsWindowAllowedToPlay(nsPIDOMWindowInner* aWindow) {
return true; return true;
} }
WindowContext* topContext = RefPtr<BrowsingContext> topLevelBC = aWindow->GetBrowsingContext()->Top();
aWindow->GetBrowsingContext()->GetTopWindowContext(); if (topLevelBC->HasBeenUserGestureActivated()) {
if (topContext && topContext->HasBeenUserGestureActivated()) {
AUTOPLAY_LOG( AUTOPLAY_LOG(
"Allow autoplay as top-level context has been activated by user " "Allow autoplay as top-level context has been activated by user "
"gesture."); "gesture.");

View File

@ -103,11 +103,8 @@ DocumentChannelChild::AsyncOpen(nsIStreamListener* aListener) {
args.timing() = Some(mTiming); args.timing() = Some(mTiming);
} }
RefPtr<WindowContext> loadingWindowContext =
loadingContext->GetCurrentWindowContext();
args.hasValidTransientUserAction() = args.hasValidTransientUserAction() =
loadingWindowContext && loadingContext->HasValidTransientUserGestureActivation();
loadingWindowContext->HasValidTransientUserGestureActivation();
switch (mLoadInfo->GetExternalContentPolicyType()) { switch (mLoadInfo->GetExternalContentPolicyType()) {
case nsIContentPolicy::TYPE_DOCUMENT: case nsIContentPolicy::TYPE_DOCUMENT:

View File

@ -159,10 +159,8 @@ NS_IMETHODIMP ParentProcessDocumentChannel::AsyncOpen(
nsresult rv = NS_OK; nsresult rv = NS_OK;
Maybe<dom::ClientInfo> initialClientInfo = mInitialClientInfo; Maybe<dom::ClientInfo> initialClientInfo = mInitialClientInfo;
RefPtr<WindowContext> context =
GetDocShell()->GetBrowsingContext()->GetCurrentWindowContext();
const bool hasValidTransientUserGestureActivation = const bool hasValidTransientUserGestureActivation =
context && context->HasValidTransientUserGestureActivation(); docShell->GetBrowsingContext()->HasValidTransientUserGestureActivation();
RefPtr<DocumentLoadListener::OpenPromise> promise; RefPtr<DocumentLoadListener::OpenPromise> promise;
if (isDocumentLoad) { if (isDocumentLoad) {

View File

@ -1138,22 +1138,17 @@ nsresult nsWindowWatcher::OpenWindowInternal(
newBC->UseRemoteSubframes() == newBC->UseRemoteSubframes() ==
!!(chromeFlags & nsIWebBrowserChrome::CHROME_FISSION_WINDOW)); !!(chromeFlags & nsIWebBrowserChrome::CHROME_FISSION_WINDOW));
nsCOMPtr<nsPIDOMWindowInner> pInnerWin =
parentWindow ? parentWindow->GetCurrentInnerWindow() : nullptr;
;
RefPtr<nsDocShellLoadState> loadState = aLoadState; RefPtr<nsDocShellLoadState> loadState = aLoadState;
if (uriToLoad && loadState) { if (uriToLoad && loadState) {
// If a URI was passed to this function, open that, not what was passed in // If a URI was passed to this function, open that, not what was passed in
// the original LoadState. See Bug 1515433. // the original LoadState. See Bug 1515433.
loadState->SetURI(uriToLoad); loadState->SetURI(uriToLoad);
} else if (uriToLoad && aNavigate && !loadState) { } else if (uriToLoad && aNavigate && !loadState) {
RefPtr<WindowContext> context =
pInnerWin ? pInnerWin->GetWindowContext() : nullptr;
loadState = new nsDocShellLoadState(uriToLoad); loadState = new nsDocShellLoadState(uriToLoad);
loadState->SetSourceBrowsingContext(parentBC); loadState->SetSourceBrowsingContext(parentBC);
loadState->SetHasValidUserGestureActivation( loadState->SetHasValidUserGestureActivation(
context && context->HasValidTransientUserGestureActivation()); parentBC && parentBC->HasValidTransientUserGestureActivation());
if (parentBC) { if (parentBC) {
loadState->SetTriggeringSandboxFlags(parentBC->GetSandboxFlags()); loadState->SetTriggeringSandboxFlags(parentBC->GetSandboxFlags());
} }
@ -1254,6 +1249,8 @@ nsresult nsWindowWatcher::OpenWindowInternal(
if (parentStorageManager && newStorageManager) { if (parentStorageManager && newStorageManager) {
RefPtr<Storage> storage; RefPtr<Storage> storage;
nsCOMPtr<nsPIDOMWindowInner> pInnerWin =
parentWindow->GetCurrentInnerWindow();
parentStorageManager->GetStorage( parentStorageManager->GetStorage(
pInnerWin, subjectPrincipal, subjectPrincipal, pInnerWin, subjectPrincipal, subjectPrincipal,
newBC->UsePrivateBrowsing(), getter_AddRefs(storage)); newBC->UsePrivateBrowsing(), getter_AddRefs(storage));