forked from mirrors/gecko-dev
		
	 05dc5e0d76
			
		
	
	
		05dc5e0d76
		
	
	
	
	
		
			
			Automatically generated rewrites of all ParamTraits and IPDLParamTraits
implementations in-tree to use IPC::Message{Reader,Writer}.
Differential Revision: https://phabricator.services.mozilla.com/D140004
		
	
			
		
			
				
	
	
		
			627 lines
		
	
	
	
		
			21 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			627 lines
		
	
	
	
		
			21 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #include "mozilla/dom/WindowContext.h"
 | |
| #include "mozilla/dom/WindowGlobalActorsBinding.h"
 | |
| #include "mozilla/dom/WindowGlobalChild.h"
 | |
| #include "mozilla/dom/WindowGlobalParent.h"
 | |
| #include "mozilla/dom/SyncedContextInlines.h"
 | |
| #include "mozilla/dom/BrowsingContext.h"
 | |
| #include "mozilla/dom/Document.h"
 | |
| #include "mozilla/dom/UserActivationIPCUtils.h"
 | |
| #include "mozilla/PermissionDelegateIPCUtils.h"
 | |
| #include "mozilla/StaticPrefs_dom.h"
 | |
| #include "mozilla/StaticPtr.h"
 | |
| #include "mozilla/ClearOnShutdown.h"
 | |
| #include "nsGlobalWindowInner.h"
 | |
| #include "nsIScriptError.h"
 | |
| #include "nsIXULRuntime.h"
 | |
| #include "nsRefPtrHashtable.h"
 | |
| #include "nsContentUtils.h"
 | |
| 
 | |
| namespace mozilla {
 | |
| namespace dom {
 | |
| 
 | |
| // Explicit specialization of the `Transaction` type. Required by the `extern
 | |
| // template class` declaration in the header.
 | |
| template class syncedcontext::Transaction<WindowContext>;
 | |
| 
 | |
| static LazyLogModule gWindowContextLog("WindowContext");
 | |
| static LazyLogModule gWindowContextSyncLog("WindowContextSync");
 | |
| 
 | |
| extern mozilla::LazyLogModule gUserInteractionPRLog;
 | |
| 
 | |
| #define USER_ACTIVATION_LOG(msg, ...) \
 | |
|   MOZ_LOG(gUserInteractionPRLog, LogLevel::Debug, (msg, ##__VA_ARGS__))
 | |
| 
 | |
| using WindowContextByIdMap = nsTHashMap<nsUint64HashKey, WindowContext*>;
 | |
| static StaticAutoPtr<WindowContextByIdMap> gWindowContexts;
 | |
| 
 | |
| /* static */
 | |
| LogModule* WindowContext::GetLog() { return gWindowContextLog; }
 | |
| 
 | |
| /* static */
 | |
| LogModule* WindowContext::GetSyncLog() { return gWindowContextSyncLog; }
 | |
| 
 | |
| /* static */
 | |
| already_AddRefed<WindowContext> WindowContext::GetById(
 | |
|     uint64_t aInnerWindowId) {
 | |
|   if (!gWindowContexts) {
 | |
|     return nullptr;
 | |
|   }
 | |
|   return do_AddRef(gWindowContexts->Get(aInnerWindowId));
 | |
| }
 | |
| 
 | |
| BrowsingContextGroup* WindowContext::Group() const {
 | |
|   return mBrowsingContext->Group();
 | |
| }
 | |
| 
 | |
| WindowGlobalParent* WindowContext::Canonical() {
 | |
|   MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
 | |
|   return static_cast<WindowGlobalParent*>(this);
 | |
| }
 | |
| 
 | |
| bool WindowContext::IsCurrent() const {
 | |
|   return mBrowsingContext->mCurrentWindowContext == this;
 | |
| }
 | |
| 
 | |
| bool WindowContext::IsInBFCache() {
 | |
|   if (mozilla::SessionHistoryInParent()) {
 | |
|     return mBrowsingContext->IsInBFCache();
 | |
|   }
 | |
|   return TopWindowContext()->GetWindowStateSaved();
 | |
| }
 | |
| 
 | |
| nsGlobalWindowInner* WindowContext::GetInnerWindow() const {
 | |
|   return mWindowGlobalChild ? mWindowGlobalChild->GetWindowGlobal() : nullptr;
 | |
| }
 | |
| 
 | |
| Document* WindowContext::GetDocument() const {
 | |
|   nsGlobalWindowInner* innerWindow = GetInnerWindow();
 | |
|   return innerWindow ? innerWindow->GetDocument() : nullptr;
 | |
| }
 | |
| 
 | |
| Document* WindowContext::GetExtantDoc() const {
 | |
|   nsGlobalWindowInner* innerWindow = GetInnerWindow();
 | |
|   return innerWindow ? innerWindow->GetExtantDoc() : nullptr;
 | |
| }
 | |
| 
 | |
| WindowGlobalChild* WindowContext::GetWindowGlobalChild() const {
 | |
|   return mWindowGlobalChild;
 | |
| }
 | |
| 
 | |
| WindowContext* WindowContext::GetParentWindowContext() {
 | |
|   return mBrowsingContext->GetParentWindowContext();
 | |
| }
 | |
| 
 | |
| WindowContext* WindowContext::TopWindowContext() {
 | |
|   WindowContext* current = this;
 | |
|   while (current->GetParentWindowContext()) {
 | |
|     current = current->GetParentWindowContext();
 | |
|   }
 | |
|   return current;
 | |
| }
 | |
| 
 | |
| bool WindowContext::IsTop() const { return mBrowsingContext->IsTop(); }
 | |
| 
 | |
| bool WindowContext::SameOriginWithTop() const {
 | |
|   return mBrowsingContext->SameOriginWithTop();
 | |
| }
 | |
| 
 | |
| nsIGlobalObject* WindowContext::GetParentObject() const {
 | |
|   return xpc::NativeGlobal(xpc::PrivilegedJunkScope());
 | |
| }
 | |
| 
 | |
| void WindowContext::AppendChildBrowsingContext(
 | |
|     BrowsingContext* aBrowsingContext) {
 | |
|   MOZ_DIAGNOSTIC_ASSERT(Group() == aBrowsingContext->Group(),
 | |
|                         "Mismatched groups?");
 | |
|   MOZ_DIAGNOSTIC_ASSERT(!mChildren.Contains(aBrowsingContext));
 | |
| 
 | |
|   mChildren.AppendElement(aBrowsingContext);
 | |
| 
 | |
|   // If we're the current WindowContext in our BrowsingContext, make sure to
 | |
|   // clear any cached `children` value.
 | |
|   if (IsCurrent()) {
 | |
|     BrowsingContext_Binding::ClearCachedChildrenValue(mBrowsingContext);
 | |
|   }
 | |
| }
 | |
| 
 | |
| void WindowContext::RemoveChildBrowsingContext(
 | |
|     BrowsingContext* aBrowsingContext) {
 | |
|   MOZ_DIAGNOSTIC_ASSERT(Group() == aBrowsingContext->Group(),
 | |
|                         "Mismatched groups?");
 | |
| 
 | |
|   mChildren.RemoveElement(aBrowsingContext);
 | |
| 
 | |
|   // If we're the current WindowContext in our BrowsingContext, make sure to
 | |
|   // clear any cached `children` value.
 | |
|   if (IsCurrent()) {
 | |
|     BrowsingContext_Binding::ClearCachedChildrenValue(mBrowsingContext);
 | |
|   }
 | |
| }
 | |
| 
 | |
| void WindowContext::SendCommitTransaction(ContentParent* aParent,
 | |
|                                           const BaseTransaction& aTxn,
 | |
|                                           uint64_t aEpoch) {
 | |
|   Unused << aParent->SendCommitWindowContextTransaction(this, aTxn, aEpoch);
 | |
| }
 | |
| 
 | |
| void WindowContext::SendCommitTransaction(ContentChild* aChild,
 | |
|                                           const BaseTransaction& aTxn,
 | |
|                                           uint64_t aEpoch) {
 | |
|   aChild->SendCommitWindowContextTransaction(this, aTxn, aEpoch);
 | |
| }
 | |
| 
 | |
| bool WindowContext::CheckOnlyOwningProcessCanSet(ContentParent* aSource) {
 | |
|   if (IsInProcess()) {
 | |
|     return true;
 | |
|   }
 | |
| 
 | |
|   if (XRE_IsParentProcess() && aSource) {
 | |
|     return Canonical()->GetContentParent() == aSource;
 | |
|   }
 | |
| 
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_IsSecure>, const bool& aIsSecure,
 | |
|                            ContentParent* aSource) {
 | |
|   return CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_AllowMixedContent>,
 | |
|                            const bool& aAllowMixedContent,
 | |
|                            ContentParent* aSource) {
 | |
|   return CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_HasBeforeUnload>,
 | |
|                            const bool& aHasBeforeUnload,
 | |
|                            ContentParent* aSource) {
 | |
|   return CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_CookieBehavior>,
 | |
|                            const Maybe<uint32_t>& aValue,
 | |
|                            ContentParent* aSource) {
 | |
|   return CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_IsOnContentBlockingAllowList>,
 | |
|                            const bool& aValue, ContentParent* aSource) {
 | |
|   return CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_IsThirdPartyWindow>,
 | |
|                            const bool& IsThirdPartyWindow,
 | |
|                            ContentParent* aSource) {
 | |
|   return CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_IsThirdPartyTrackingResourceWindow>,
 | |
|                            const bool& aIsThirdPartyTrackingResourceWindow,
 | |
|                            ContentParent* aSource) {
 | |
|   return CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_IsSecureContext>,
 | |
|                            const bool& aIsSecureContext,
 | |
|                            ContentParent* aSource) {
 | |
|   return CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_IsOriginalFrameSource>,
 | |
|                            const bool& aIsOriginalFrameSource,
 | |
|                            ContentParent* aSource) {
 | |
|   return CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_DocTreeHadMedia>, const bool& aValue,
 | |
|                            ContentParent* aSource) {
 | |
|   return IsTop();
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_AutoplayPermission>,
 | |
|                            const uint32_t& aValue, ContentParent* aSource) {
 | |
|   return CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_ShortcutsPermission>,
 | |
|                            const uint32_t& aValue, ContentParent* aSource) {
 | |
|   return IsTop() && CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_ActiveMediaSessionContextId>,
 | |
|                            const Maybe<uint64_t>& aValue,
 | |
|                            ContentParent* aSource) {
 | |
|   return IsTop();
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_PopupPermission>, const uint32_t&,
 | |
|                            ContentParent* aSource) {
 | |
|   return CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(
 | |
|     FieldIndex<IDX_DelegatedPermissions>,
 | |
|     const PermissionDelegateHandler::DelegatedPermissionList& aValue,
 | |
|     ContentParent* aSource) {
 | |
|   return CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(
 | |
|     FieldIndex<IDX_DelegatedExactHostMatchPermissions>,
 | |
|     const PermissionDelegateHandler::DelegatedPermissionList& aValue,
 | |
|     ContentParent* aSource) {
 | |
|   return CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_IsLocalIP>, const bool& aValue,
 | |
|                            ContentParent* aSource) {
 | |
|   return CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_HadLazyLoadImage>, const bool& aValue,
 | |
|                            ContentParent* aSource) {
 | |
|   return IsTop();
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_AllowJavascript>, bool aValue,
 | |
|                            ContentParent* aSource) {
 | |
|   return (XRE_IsParentProcess() && !aSource) ||
 | |
|          CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| void WindowContext::DidSet(FieldIndex<IDX_AllowJavascript>, bool aOldValue) {
 | |
|   RecomputeCanExecuteScripts();
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_HasActivePeerConnections>, bool,
 | |
|                            ContentParent*) {
 | |
|   return XRE_IsParentProcess() && IsTop();
 | |
| }
 | |
| 
 | |
| void WindowContext::RecomputeCanExecuteScripts(bool aApplyChanges) {
 | |
|   const bool old = mCanExecuteScripts;
 | |
|   if (!AllowJavascript()) {
 | |
|     // Scripting has been explicitly disabled on our WindowContext.
 | |
|     mCanExecuteScripts = false;
 | |
|   } else {
 | |
|     // Otherwise, inherit.
 | |
|     mCanExecuteScripts = mBrowsingContext->CanExecuteScripts();
 | |
|   }
 | |
| 
 | |
|   if (aApplyChanges && old != mCanExecuteScripts) {
 | |
|     // Inform our active DOM window.
 | |
|     if (nsGlobalWindowInner* window = GetInnerWindow()) {
 | |
|       // Only update scriptability if the window is current. Windows will have
 | |
|       // scriptability disabled when entering the bfcache and updated when
 | |
|       // coming out.
 | |
|       if (window->IsCurrentInnerWindow()) {
 | |
|         auto& scriptability =
 | |
|             xpc::Scriptability::Get(window->GetGlobalJSObject());
 | |
|         scriptability.SetWindowAllowsScript(mCanExecuteScripts);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     for (const RefPtr<BrowsingContext>& child : Children()) {
 | |
|       child->RecomputeCanExecuteScripts();
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| void WindowContext::DidSet(FieldIndex<IDX_SHEntryHasUserInteraction>,
 | |
|                            bool aOldValue) {
 | |
|   MOZ_ASSERT(
 | |
|       TopWindowContext() == this,
 | |
|       "SHEntryHasUserInteraction can only be set on the top window context");
 | |
|   // This field is set when the child notifies us of new user interaction, so we
 | |
|   // also set the currently active shentry in the parent as having interaction.
 | |
|   if (XRE_IsParentProcess() && mBrowsingContext) {
 | |
|     SessionHistoryEntry* activeEntry =
 | |
|         mBrowsingContext->Canonical()->GetActiveSessionHistoryEntry();
 | |
|     if (activeEntry && GetSHEntryHasUserInteraction()) {
 | |
|       activeEntry->SetHasUserInteraction(true);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| void WindowContext::DidSet(FieldIndex<IDX_UserActivationState>) {
 | |
|   MOZ_ASSERT_IF(!IsInProcess(), 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 (IsInProcess()) {
 | |
|     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>,
 | |
|                            bool aOldValue) {
 | |
|   if (!aOldValue && GetHasReportedShadowDOMUsage() && IsInProcess()) {
 | |
|     MOZ_ASSERT(TopWindowContext() == this);
 | |
|     if (mBrowsingContext) {
 | |
|       Document* topLevelDoc = mBrowsingContext->GetDocument();
 | |
|       if (topLevelDoc) {
 | |
|         nsAutoString uri;
 | |
|         Unused << topLevelDoc->GetDocumentURI(uri);
 | |
|         if (!uri.IsEmpty()) {
 | |
|           nsAutoString msg = u"Shadow DOM used in ["_ns + uri +
 | |
|                              u"] or in some of its subdocuments."_ns;
 | |
|           nsContentUtils::ReportToConsoleNonLocalized(
 | |
|               msg, nsIScriptError::infoFlag, "DOM"_ns, topLevelDoc);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanSet(FieldIndex<IDX_WindowStateSaved>, bool aValue,
 | |
|                            ContentParent* aSource) {
 | |
|   return !mozilla::SessionHistoryInParent() && IsTop() &&
 | |
|          CheckOnlyOwningProcessCanSet(aSource);
 | |
| }
 | |
| 
 | |
| void WindowContext::CreateFromIPC(IPCInitializer&& aInit) {
 | |
|   MOZ_RELEASE_ASSERT(XRE_IsContentProcess(),
 | |
|                      "Should be a WindowGlobalParent in the parent");
 | |
| 
 | |
|   RefPtr<BrowsingContext> bc = BrowsingContext::Get(aInit.mBrowsingContextId);
 | |
|   MOZ_RELEASE_ASSERT(bc);
 | |
| 
 | |
|   if (bc->IsDiscarded()) {
 | |
|     // If we have already closed our browsing context, the
 | |
|     // WindowGlobalChild actor is bound to be destroyed soon and it's
 | |
|     // safe to ignore creating the WindowContext.
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   RefPtr<WindowContext> context = new WindowContext(
 | |
|       bc, aInit.mInnerWindowId, aInit.mOuterWindowId, std::move(aInit.mFields));
 | |
|   context->Init();
 | |
| }
 | |
| 
 | |
| void WindowContext::Init() {
 | |
|   MOZ_LOG(GetLog(), LogLevel::Debug,
 | |
|           ("Registering 0x%" PRIx64 " (bc=0x%" PRIx64 ")", mInnerWindowId,
 | |
|            mBrowsingContext->Id()));
 | |
| 
 | |
|   // Register the WindowContext in the `WindowContextByIdMap`.
 | |
|   if (!gWindowContexts) {
 | |
|     gWindowContexts = new WindowContextByIdMap();
 | |
|     ClearOnShutdown(&gWindowContexts);
 | |
|   }
 | |
|   auto& entry = gWindowContexts->LookupOrInsert(mInnerWindowId);
 | |
|   MOZ_RELEASE_ASSERT(!entry, "Duplicate WindowContext for ID!");
 | |
|   entry = this;
 | |
| 
 | |
|   // Register this to the browsing context.
 | |
|   mBrowsingContext->RegisterWindowContext(this);
 | |
|   Group()->Register(this);
 | |
| }
 | |
| 
 | |
| void WindowContext::Discard() {
 | |
|   MOZ_LOG(GetLog(), LogLevel::Debug,
 | |
|           ("Discarding 0x%" PRIx64 " (bc=0x%" PRIx64 ")", mInnerWindowId,
 | |
|            mBrowsingContext->Id()));
 | |
|   if (mIsDiscarded) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   mIsDiscarded = true;
 | |
|   if (gWindowContexts) {
 | |
|     gWindowContexts->Remove(InnerWindowId());
 | |
|   }
 | |
|   mBrowsingContext->UnregisterWindowContext(this);
 | |
|   Group()->Unregister(this);
 | |
| }
 | |
| 
 | |
| void WindowContext::AddSecurityState(uint32_t aStateFlags) {
 | |
|   MOZ_ASSERT(TopWindowContext() == this);
 | |
|   MOZ_ASSERT((aStateFlags &
 | |
|               (nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT |
 | |
|                nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT |
 | |
|                nsIWebProgressListener::STATE_BLOCKED_MIXED_DISPLAY_CONTENT |
 | |
|                nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT |
 | |
|                nsIWebProgressListener::STATE_HTTPS_ONLY_MODE_UPGRADED |
 | |
|                nsIWebProgressListener::STATE_HTTPS_ONLY_MODE_UPGRADE_FAILED)) ==
 | |
|                  aStateFlags,
 | |
|              "Invalid flags specified!");
 | |
| 
 | |
|   if (XRE_IsParentProcess()) {
 | |
|     Canonical()->AddSecurityState(aStateFlags);
 | |
|   } else {
 | |
|     ContentChild* child = ContentChild::GetSingleton();
 | |
|     child->SendAddSecurityState(this, 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(IsInProcess());
 | |
| 
 | |
|   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(IsInProcess());
 | |
|   MOZ_ASSERT(IsCurrent());
 | |
| 
 | |
|   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;
 | |
| }
 | |
| 
 | |
| bool WindowContext::CanShowPopup() {
 | |
|   uint32_t permit = GetPopupPermission();
 | |
|   if (permit == nsIPermissionManager::ALLOW_ACTION) {
 | |
|     return true;
 | |
|   }
 | |
|   if (permit == nsIPermissionManager::DENY_ACTION) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   return !StaticPrefs::dom_disable_open_during_load();
 | |
| }
 | |
| 
 | |
| WindowContext::IPCInitializer WindowContext::GetIPCInitializer() {
 | |
|   IPCInitializer init;
 | |
|   init.mInnerWindowId = mInnerWindowId;
 | |
|   init.mOuterWindowId = mOuterWindowId;
 | |
|   init.mBrowsingContextId = mBrowsingContext->Id();
 | |
|   init.mFields = mFields.RawValues();
 | |
|   return init;
 | |
| }
 | |
| 
 | |
| WindowContext::WindowContext(BrowsingContext* aBrowsingContext,
 | |
|                              uint64_t aInnerWindowId, uint64_t aOuterWindowId,
 | |
|                              FieldValues&& aInit)
 | |
|     : mFields(std::move(aInit)),
 | |
|       mInnerWindowId(aInnerWindowId),
 | |
|       mOuterWindowId(aOuterWindowId),
 | |
|       mBrowsingContext(aBrowsingContext) {
 | |
|   MOZ_ASSERT(mBrowsingContext);
 | |
|   MOZ_ASSERT(mInnerWindowId);
 | |
|   MOZ_ASSERT(mOuterWindowId);
 | |
|   RecomputeCanExecuteScripts(/* aApplyChanges */ false);
 | |
| }
 | |
| 
 | |
| WindowContext::~WindowContext() {
 | |
|   if (gWindowContexts) {
 | |
|     gWindowContexts->Remove(InnerWindowId());
 | |
|   }
 | |
| }
 | |
| 
 | |
| JSObject* WindowContext::WrapObject(JSContext* cx,
 | |
|                                     JS::Handle<JSObject*> aGivenProto) {
 | |
|   return WindowContext_Binding::Wrap(cx, this, aGivenProto);
 | |
| }
 | |
| 
 | |
| NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WindowContext)
 | |
|   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
 | |
|   NS_INTERFACE_MAP_ENTRY(nsISupports)
 | |
| NS_INTERFACE_MAP_END
 | |
| 
 | |
| NS_IMPL_CYCLE_COLLECTING_ADDREF(WindowContext)
 | |
| NS_IMPL_CYCLE_COLLECTING_RELEASE(WindowContext)
 | |
| 
 | |
| NS_IMPL_CYCLE_COLLECTION_CLASS(WindowContext)
 | |
| 
 | |
| NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WindowContext)
 | |
|   if (gWindowContexts) {
 | |
|     gWindowContexts->Remove(tmp->InnerWindowId());
 | |
|   }
 | |
| 
 | |
|   NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowsingContext)
 | |
|   NS_IMPL_CYCLE_COLLECTION_UNLINK(mChildren)
 | |
|   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 | |
| NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 | |
| 
 | |
| NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WindowContext)
 | |
|   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowsingContext)
 | |
|   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildren)
 | |
| NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 | |
| 
 | |
| NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(WindowContext)
 | |
| 
 | |
| }  // namespace dom
 | |
| 
 | |
| namespace ipc {
 | |
| 
 | |
| void IPDLParamTraits<dom::MaybeDiscarded<dom::WindowContext>>::Write(
 | |
|     IPC::MessageWriter* aWriter, IProtocol* aActor,
 | |
|     const dom::MaybeDiscarded<dom::WindowContext>& aParam) {
 | |
|   uint64_t id = aParam.ContextId();
 | |
|   WriteIPDLParam(aWriter, aActor, id);
 | |
| }
 | |
| 
 | |
| bool IPDLParamTraits<dom::MaybeDiscarded<dom::WindowContext>>::Read(
 | |
|     IPC::MessageReader* aReader, IProtocol* aActor,
 | |
|     dom::MaybeDiscarded<dom::WindowContext>* aResult) {
 | |
|   uint64_t id = 0;
 | |
|   if (!ReadIPDLParam(aReader, aActor, &id)) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   if (id == 0) {
 | |
|     *aResult = nullptr;
 | |
|   } else if (RefPtr<dom::WindowContext> wc = dom::WindowContext::GetById(id)) {
 | |
|     *aResult = std::move(wc);
 | |
|   } else {
 | |
|     aResult->SetDiscarded(id);
 | |
|   }
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| void IPDLParamTraits<dom::WindowContext::IPCInitializer>::Write(
 | |
|     IPC::MessageWriter* aWriter, IProtocol* aActor,
 | |
|     const dom::WindowContext::IPCInitializer& aInit) {
 | |
|   // Write actor ID parameters.
 | |
|   WriteIPDLParam(aWriter, aActor, aInit.mInnerWindowId);
 | |
|   WriteIPDLParam(aWriter, aActor, aInit.mOuterWindowId);
 | |
|   WriteIPDLParam(aWriter, aActor, aInit.mBrowsingContextId);
 | |
|   WriteIPDLParam(aWriter, aActor, aInit.mFields);
 | |
| }
 | |
| 
 | |
| bool IPDLParamTraits<dom::WindowContext::IPCInitializer>::Read(
 | |
|     IPC::MessageReader* aReader, IProtocol* aActor,
 | |
|     dom::WindowContext::IPCInitializer* aInit) {
 | |
|   // Read actor ID parameters.
 | |
|   return ReadIPDLParam(aReader, aActor, &aInit->mInnerWindowId) &&
 | |
|          ReadIPDLParam(aReader, aActor, &aInit->mOuterWindowId) &&
 | |
|          ReadIPDLParam(aReader, aActor, &aInit->mBrowsingContextId) &&
 | |
|          ReadIPDLParam(aReader, aActor, &aInit->mFields);
 | |
| }
 | |
| 
 | |
| template struct IPDLParamTraits<dom::WindowContext::BaseTransaction>;
 | |
| 
 | |
| }  // namespace ipc
 | |
| }  // namespace mozilla
 |