1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_WindowContext_h
8 #define mozilla_dom_WindowContext_h
10 #include "mozilla/PermissionDelegateHandler.h"
11 #include "mozilla/WeakPtr.h"
12 #include "mozilla/Span.h"
13 #include "mozilla/dom/MaybeDiscarded.h"
14 #include "mozilla/dom/SyncedContext.h"
15 #include "mozilla/dom/UserActivation.h"
16 #include "nsDOMNavigationTiming.h"
17 #include "nsILoadInfo.h"
18 #include "nsWrapperCache.h"
20 class nsIGlobalObject
;
22 class nsGlobalWindowInner
;
29 class WindowGlobalChild
;
30 class WindowGlobalParent
;
31 class WindowGlobalInit
;
32 class BrowsingContext
;
33 class BrowsingContextGroup
;
35 #define MOZ_EACH_WC_FIELD(FIELD) \
36 /* Whether the SHEntry associated with the current top-level \
37 * window has already seen user interaction. \
38 * As such, this will be reset to false when a new SHEntry is \
39 * created without changing the WC (e.g. when using pushState or \
40 * sub-frame navigation) \
41 * This flag is set for optimization purposes, to avoid \
42 * having to get the top SHEntry and update it on every \
44 * This is only meaningful on the top-level WC. */ \
45 FIELD(SHEntryHasUserInteraction, bool) \
46 FIELD(CookieBehavior, Maybe<uint32_t>) \
47 FIELD(IsOnContentBlockingAllowList, bool) \
48 /* Whether the given window hierarchy is third party. See \
49 * ThirdPartyUtil::IsThirdPartyWindow for details */ \
50 FIELD(IsThirdPartyWindow, bool) \
51 /* Whether this window's channel has been marked as a third-party \
52 * tracking resource */ \
53 FIELD(IsThirdPartyTrackingResourceWindow, bool) \
54 /* Whether this window is using its unpartitioned cookies due to \
55 * the Storage Access API */ \
56 FIELD(UsingStorageAccess, bool) \
57 FIELD(ShouldResistFingerprinting, bool) \
58 FIELD(OverriddenFingerprintingSettings, Maybe<RFPTarget>) \
59 FIELD(IsSecureContext, bool) \
60 FIELD(IsOriginalFrameSource, bool) \
61 /* Mixed-Content: If the corresponding documentURI is https, \
62 * then this flag is true. */ \
63 FIELD(IsSecure, bool) \
64 /* Whether the user has overriden the mixed content blocker to allow \
65 * mixed content loads to happen */ \
66 FIELD(AllowMixedContent, bool) \
67 /* Whether this window has registered a "beforeunload" event \
69 FIELD(HasBeforeUnload, bool) \
70 /* Controls whether the WindowContext is currently considered to be \
71 * activated by a gesture */ \
72 FIELD(UserActivationState, UserActivation::State) \
73 FIELD(EmbedderPolicy, nsILoadInfo::CrossOriginEmbedderPolicy) \
74 /* True if this document tree contained at least a HTMLMediaElement. \
75 * This should only be set on top level context. */ \
76 FIELD(DocTreeHadMedia, bool) \
77 FIELD(AutoplayPermission, uint32_t) \
78 FIELD(ShortcutsPermission, uint32_t) \
79 /* Store the Id of the browsing context where active media session \
80 * exists on the top level window context */ \
81 FIELD(ActiveMediaSessionContextId, Maybe<uint64_t>) \
82 /* ALLOW_ACTION if it is allowed to open popups for the sub-tree \
83 * starting and including the current WindowContext */ \
84 FIELD(PopupPermission, uint32_t) \
85 FIELD(DelegatedPermissions, \
86 PermissionDelegateHandler::DelegatedPermissionList) \
87 FIELD(DelegatedExactHostMatchPermissions, \
88 PermissionDelegateHandler::DelegatedPermissionList) \
89 FIELD(HasReportedShadowDOMUsage, bool) \
90 /* Whether the principal of this window is for a local \
92 FIELD(IsLocalIP, bool) \
93 /* Whether any of the windows in the subtree rooted at this window has \
94 * active peer connections or not (only set on the top window). */ \
95 FIELD(HasActivePeerConnections, bool) \
96 /* Whether we can execute scripts in this WindowContext. Has no effect \
97 * unless scripts are also allowed in the BrowsingContext. */ \
98 FIELD(AllowJavascript, bool) \
99 /* If this field is `true`, it means that this WindowContext's \
100 * WindowState was saved to be stored in the legacy (non-SHIP) BFCache \
101 * implementation. Always false for SHIP */ \
102 FIELD(WindowStateSaved, bool)
104 class WindowContext
: public nsISupports
, public nsWrapperCache
{
105 MOZ_DECL_SYNCED_CONTEXT(WindowContext
, MOZ_EACH_WC_FIELD
)
107 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
108 NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(WindowContext
)
111 static already_AddRefed
<WindowContext
> GetById(uint64_t aInnerWindowId
);
112 static LogModule
* GetLog();
113 static LogModule
* GetSyncLog();
115 BrowsingContext
* GetBrowsingContext() const { return mBrowsingContext
; }
116 BrowsingContextGroup
* Group() const;
117 uint64_t Id() const { return InnerWindowId(); }
118 uint64_t InnerWindowId() const { return mInnerWindowId
; }
119 uint64_t OuterWindowId() const { return mOuterWindowId
; }
120 bool IsDiscarded() const { return mIsDiscarded
; }
122 // Returns `true` if this WindowContext is the current WindowContext in its
124 bool IsCurrent() const;
126 // Returns `true` if this WindowContext is currently in the BFCache.
129 bool IsInProcess() const { return mIsInProcess
; }
131 bool HasBeforeUnload() const { return GetHasBeforeUnload(); }
133 bool IsLocalIP() const { return GetIsLocalIP(); }
135 bool ShouldResistFingerprinting() const {
136 return GetShouldResistFingerprinting();
139 Nullable
<uint64_t> GetOverriddenFingerprintingSettingsWebIDL() const {
140 Maybe
<RFPTarget
> overriddenFingerprintingSettings
=
141 GetOverriddenFingerprintingSettings();
143 return overriddenFingerprintingSettings
.isSome()
144 ? Nullable
<uint64_t>(
145 uint64_t(overriddenFingerprintingSettings
.ref()))
146 : Nullable
<uint64_t>();
149 nsGlobalWindowInner
* GetInnerWindow() const;
150 Document
* GetDocument() const;
151 Document
* GetExtantDoc() const;
153 WindowGlobalChild
* GetWindowGlobalChild() const;
155 // Get the parent WindowContext of this WindowContext, taking the BFCache into
156 // account. This will not cross chrome/content <browser> boundaries.
157 WindowContext
* GetParentWindowContext();
158 WindowContext
* TopWindowContext();
160 bool SameOriginWithTop() const;
164 Span
<RefPtr
<BrowsingContext
>> Children() { return mChildren
; }
166 // The filtered version of `Children()`, which contains no browsing contexts
167 // for synthetic documents as created by object loading content.
168 Span
<RefPtr
<BrowsingContext
>> NonSyntheticChildren() {
169 return mNonSyntheticChildren
;
172 // Cast this object to it's parent-process canonical form.
173 WindowGlobalParent
* Canonical();
175 nsIGlobalObject
* GetParentObject() const;
176 JSObject
* WrapObject(JSContext
* cx
,
177 JS::Handle
<JSObject
*> aGivenProto
) override
;
181 struct IPCInitializer
{
182 uint64_t mInnerWindowId
;
183 uint64_t mOuterWindowId
;
184 uint64_t mBrowsingContextId
;
188 IPCInitializer
GetIPCInitializer();
190 static void CreateFromIPC(IPCInitializer
&& aInit
);
192 // Add new security state flags.
193 // These should be some of the nsIWebProgressListener 'HTTPS_ONLY_MODE' or
194 // 'MIXED' state flags, and should only be called on the top window context.
195 void AddSecurityState(uint32_t aStateFlags
);
197 // This function would be called when its corresponding window is activated
199 void NotifyUserGestureActivation();
201 // This function would be called when we want to reset the user gesture
203 void NotifyResetUserGestureActivation();
205 // Return true if its corresponding window has been activated by user
207 bool HasBeenUserGestureActivated();
209 // Return true if its corresponding window has transient user gesture
210 // activation and the transient user gesture activation haven't yet timed
212 bool HasValidTransientUserGestureActivation();
214 // See `mUserGestureStart`.
215 const TimeStamp
& GetUserGestureStart() const;
217 // Return true if the corresponding window has valid transient user gesture
218 // activation and the transient user gesture activation had been consumed
220 bool ConsumeTransientUserGestureActivation();
224 bool AllowJavascript() const { return GetAllowJavascript(); }
225 bool CanExecuteScripts() const { return mCanExecuteScripts
; }
227 void TransientSetHasActivePeerConnections();
230 WindowContext(BrowsingContext
* aBrowsingContext
, uint64_t aInnerWindowId
,
231 uint64_t aOuterWindowId
, FieldValues
&& aFields
);
232 virtual ~WindowContext();
237 friend class BrowsingContext
;
238 friend class WindowGlobalChild
;
239 friend class WindowGlobalActor
;
241 void AppendChildBrowsingContext(BrowsingContext
* aBrowsingContext
);
242 void RemoveChildBrowsingContext(BrowsingContext
* aBrowsingContext
);
244 // Update non-synthetic children based on whether `aBrowsingContext`
245 // is synthetic or not. Regardless the synthetic of `aBrowsingContext`, it is
246 // kept in this WindowContext's all children list.
247 void UpdateChildSynthetic(BrowsingContext
* aBrowsingContext
,
250 // Send a given `BaseTransaction` object to the correct remote.
251 void SendCommitTransaction(ContentParent
* aParent
,
252 const BaseTransaction
& aTxn
, uint64_t aEpoch
);
253 void SendCommitTransaction(ContentChild
* aChild
, const BaseTransaction
& aTxn
,
256 bool CheckOnlyOwningProcessCanSet(ContentParent
* aSource
);
258 // Overload `CanSet` to get notifications for a particular field being set.
259 bool CanSet(FieldIndex
<IDX_IsSecure
>, const bool& aIsSecure
,
260 ContentParent
* aSource
);
261 bool CanSet(FieldIndex
<IDX_AllowMixedContent
>, const bool& aAllowMixedContent
,
262 ContentParent
* aSource
);
264 bool CanSet(FieldIndex
<IDX_HasBeforeUnload
>, const bool& aHasBeforeUnload
,
265 ContentParent
* aSource
);
267 bool CanSet(FieldIndex
<IDX_CookieBehavior
>, const Maybe
<uint32_t>& aValue
,
268 ContentParent
* aSource
);
270 bool CanSet(FieldIndex
<IDX_IsOnContentBlockingAllowList
>, const bool& aValue
,
271 ContentParent
* aSource
);
273 bool CanSet(FieldIndex
<IDX_EmbedderPolicy
>, const bool& aValue
,
274 ContentParent
* aSource
) {
278 bool CanSet(FieldIndex
<IDX_IsThirdPartyWindow
>,
279 const bool& IsThirdPartyWindow
, ContentParent
* aSource
);
280 bool CanSet(FieldIndex
<IDX_IsThirdPartyTrackingResourceWindow
>,
281 const bool& aIsThirdPartyTrackingResourceWindow
,
282 ContentParent
* aSource
);
283 bool CanSet(FieldIndex
<IDX_UsingStorageAccess
>,
284 const bool& aUsingStorageAccess
, ContentParent
* aSource
);
285 bool CanSet(FieldIndex
<IDX_ShouldResistFingerprinting
>,
286 const bool& aShouldResistFingerprinting
, ContentParent
* aSource
);
287 bool CanSet(FieldIndex
<IDX_OverriddenFingerprintingSettings
>,
288 const Maybe
<RFPTarget
>& aValue
, ContentParent
* aSource
);
289 bool CanSet(FieldIndex
<IDX_IsSecureContext
>, const bool& aIsSecureContext
,
290 ContentParent
* aSource
);
291 bool CanSet(FieldIndex
<IDX_IsOriginalFrameSource
>,
292 const bool& aIsOriginalFrameSource
, ContentParent
* aSource
);
293 bool CanSet(FieldIndex
<IDX_DocTreeHadMedia
>, const bool& aValue
,
294 ContentParent
* aSource
);
295 bool CanSet(FieldIndex
<IDX_AutoplayPermission
>, const uint32_t& aValue
,
296 ContentParent
* aSource
);
297 bool CanSet(FieldIndex
<IDX_ShortcutsPermission
>, const uint32_t& aValue
,
298 ContentParent
* aSource
);
299 bool CanSet(FieldIndex
<IDX_ActiveMediaSessionContextId
>,
300 const Maybe
<uint64_t>& aValue
, ContentParent
* aSource
);
301 bool CanSet(FieldIndex
<IDX_PopupPermission
>, const uint32_t&,
302 ContentParent
* aSource
);
303 bool CanSet(FieldIndex
<IDX_SHEntryHasUserInteraction
>,
304 const bool& aSHEntryHasUserInteraction
, ContentParent
* aSource
) {
307 bool CanSet(FieldIndex
<IDX_DelegatedPermissions
>,
308 const PermissionDelegateHandler::DelegatedPermissionList
& aValue
,
309 ContentParent
* aSource
);
310 bool CanSet(FieldIndex
<IDX_DelegatedExactHostMatchPermissions
>,
311 const PermissionDelegateHandler::DelegatedPermissionList
& aValue
,
312 ContentParent
* aSource
);
313 bool CanSet(FieldIndex
<IDX_UserActivationState
>,
314 const UserActivation::State
& aUserActivationState
,
315 ContentParent
* aSource
) {
319 bool CanSet(FieldIndex
<IDX_HasReportedShadowDOMUsage
>, const bool& aValue
,
320 ContentParent
* aSource
) {
324 bool CanSet(FieldIndex
<IDX_IsLocalIP
>, const bool& aValue
,
325 ContentParent
* aSource
);
327 bool CanSet(FieldIndex
<IDX_AllowJavascript
>, bool aValue
,
328 ContentParent
* aSource
);
329 void DidSet(FieldIndex
<IDX_AllowJavascript
>, bool aOldValue
);
331 bool CanSet(FieldIndex
<IDX_HasActivePeerConnections
>, bool, ContentParent
*);
333 void DidSet(FieldIndex
<IDX_HasReportedShadowDOMUsage
>, bool aOldValue
);
335 void DidSet(FieldIndex
<IDX_SHEntryHasUserInteraction
>, bool aOldValue
);
337 bool CanSet(FieldIndex
<IDX_WindowStateSaved
>, bool aValue
,
338 ContentParent
* aSource
);
340 // Overload `DidSet` to get notifications for a particular field being set.
342 // You can also overload the variant that gets the old value if you need it.
344 void DidSet(FieldIndex
<I
>) {}
345 template <size_t I
, typename T
>
346 void DidSet(FieldIndex
<I
>, T
&& aOldValue
) {}
347 void DidSet(FieldIndex
<IDX_UserActivationState
>);
349 // Recomputes whether we can execute scripts in this WindowContext based on
350 // the value of AllowJavascript() and whether scripts are allowed in the
352 void RecomputeCanExecuteScripts(bool aApplyChanges
= true);
354 const uint64_t mInnerWindowId
;
355 const uint64_t mOuterWindowId
;
356 RefPtr
<BrowsingContext
> mBrowsingContext
;
357 WeakPtr
<WindowGlobalChild
> mWindowGlobalChild
;
359 // --- NEVER CHANGE `mChildren` DIRECTLY! ---
360 // Changes to this list need to be synchronized to the list within our
361 // `mBrowsingContext`, and should only be performed through the
362 // `AppendChildBrowsingContext` and `RemoveChildBrowsingContext` methods.
363 nsTArray
<RefPtr
<BrowsingContext
>> mChildren
;
365 // --- NEVER CHANGE `mNonSyntheticChildren` DIRECTLY! ---
366 // Same reason as for mChildren.
367 // mNonSyntheticChildren contains the same browsing contexts except browsing
368 // contexts created by the synthetic document for object loading contents
369 // loading images. This is used to discern browsing contexts created when
370 // loading images in <object> or <embed> elements, so that they can be hidden
371 // from named targeting, `Window.frames` etc.
372 nsTArray
<RefPtr
<BrowsingContext
>> mNonSyntheticChildren
;
374 bool mIsDiscarded
= false;
375 bool mIsInProcess
= false;
377 // Determines if we can execute scripts in this WindowContext. True if
378 // AllowJavascript() is true and script execution is allowed in the
380 bool mCanExecuteScripts
= true;
382 // The start time of user gesture, this is only available if the window
383 // context is in process.
384 TimeStamp mUserGestureStart
;
387 using WindowContextTransaction
= WindowContext::BaseTransaction
;
388 using WindowContextInitializer
= WindowContext::IPCInitializer
;
389 using MaybeDiscardedWindowContext
= MaybeDiscarded
<WindowContext
>;
391 // Don't specialize the `Transaction` object for every translation unit it's
392 // used in. This should help keep code size down.
393 extern template class syncedcontext::Transaction
<WindowContext
>;
399 struct IPDLParamTraits
<dom::MaybeDiscarded
<dom::WindowContext
>> {
400 static void Write(IPC::MessageWriter
* aWriter
, IProtocol
* aActor
,
401 const dom::MaybeDiscarded
<dom::WindowContext
>& aParam
);
402 static bool Read(IPC::MessageReader
* aReader
, IProtocol
* aActor
,
403 dom::MaybeDiscarded
<dom::WindowContext
>* aResult
);
407 struct IPDLParamTraits
<dom::WindowContext::IPCInitializer
> {
408 static void Write(IPC::MessageWriter
* aWriter
, IProtocol
* aActor
,
409 const dom::WindowContext::IPCInitializer
& aInitializer
);
411 static bool Read(IPC::MessageReader
* aReader
, IProtocol
* aActor
,
412 dom::WindowContext::IPCInitializer
* aInitializer
);
415 } // namespace mozilla
417 #endif // !defined(mozilla_dom_WindowContext_h)