Bug 1773793 [wpt PR 34381] - [FedCM] Move most tests to fedcm-network-requests, a...
[gecko.git] / docshell / base / WindowContext.h
blob984ae3d1672a30b778332e936cff2224c2f0258d
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;
24 namespace mozilla {
25 class LogModule;
27 namespace dom {
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 \
43 * user interaction. \
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 FIELD(IsSecureContext, bool) \
55 FIELD(IsOriginalFrameSource, bool) \
56 /* Mixed-Content: If the corresponding documentURI is https, \
57 * then this flag is true. */ \
58 FIELD(IsSecure, bool) \
59 /* Whether the user has overriden the mixed content blocker to allow \
60 * mixed content loads to happen */ \
61 FIELD(AllowMixedContent, bool) \
62 /* Whether this window has registered a "beforeunload" event \
63 * handler */ \
64 FIELD(HasBeforeUnload, bool) \
65 /* Controls whether the WindowContext is currently considered to be \
66 * activated by a gesture */ \
67 FIELD(UserActivationState, UserActivation::State) \
68 FIELD(EmbedderPolicy, nsILoadInfo::CrossOriginEmbedderPolicy) \
69 /* True if this document tree contained at least a HTMLMediaElement. \
70 * This should only be set on top level context. */ \
71 FIELD(DocTreeHadMedia, bool) \
72 FIELD(AutoplayPermission, uint32_t) \
73 FIELD(ShortcutsPermission, uint32_t) \
74 /* Store the Id of the browsing context where active media session \
75 * exists on the top level window context */ \
76 FIELD(ActiveMediaSessionContextId, Maybe<uint64_t>) \
77 /* ALLOW_ACTION if it is allowed to open popups for the sub-tree \
78 * starting and including the current WindowContext */ \
79 FIELD(PopupPermission, uint32_t) \
80 FIELD(DelegatedPermissions, \
81 PermissionDelegateHandler::DelegatedPermissionList) \
82 FIELD(DelegatedExactHostMatchPermissions, \
83 PermissionDelegateHandler::DelegatedPermissionList) \
84 FIELD(HasReportedShadowDOMUsage, bool) \
85 /* Whether the principal of this window is for a local \
86 * IP address */ \
87 FIELD(IsLocalIP, bool) \
88 /* Whether the corresponding document has `loading='lazy'` \
89 * images; It won't become false if the image becomes non-lazy */ \
90 FIELD(HadLazyLoadImage, bool) \
91 /* Whether any of the windows in the subtree rooted at this window has \
92 * active peer connections or not (only set on the top window). */ \
93 FIELD(HasActivePeerConnections, bool) \
94 /* Whether we can execute scripts in this WindowContext. Has no effect \
95 * unless scripts are also allowed in the BrowsingContext. */ \
96 FIELD(AllowJavascript, bool) \
97 /* If this field is `true`, it means that this WindowContext's \
98 * WindowState was saved to be stored in the legacy (non-SHIP) BFCache \
99 * implementation. Always false for SHIP */ \
100 FIELD(WindowStateSaved, bool)
102 class WindowContext : public nsISupports, public nsWrapperCache {
103 MOZ_DECL_SYNCED_CONTEXT(WindowContext, MOZ_EACH_WC_FIELD)
105 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
106 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WindowContext)
108 public:
109 static already_AddRefed<WindowContext> GetById(uint64_t aInnerWindowId);
110 static LogModule* GetLog();
111 static LogModule* GetSyncLog();
113 BrowsingContext* GetBrowsingContext() const { return mBrowsingContext; }
114 BrowsingContextGroup* Group() const;
115 uint64_t Id() const { return InnerWindowId(); }
116 uint64_t InnerWindowId() const { return mInnerWindowId; }
117 uint64_t OuterWindowId() const { return mOuterWindowId; }
118 bool IsDiscarded() const { return mIsDiscarded; }
120 // Returns `true` if this WindowContext is the current WindowContext in its
121 // BrowsingContext.
122 bool IsCurrent() const;
124 // Returns `true` if this WindowContext is currently in the BFCache.
125 bool IsInBFCache();
127 bool IsInProcess() const { return mIsInProcess; }
129 bool HasBeforeUnload() const { return GetHasBeforeUnload(); }
131 bool IsLocalIP() const { return GetIsLocalIP(); }
133 nsGlobalWindowInner* GetInnerWindow() const;
134 Document* GetDocument() const;
135 Document* GetExtantDoc() const;
137 WindowGlobalChild* GetWindowGlobalChild() const;
139 // Get the parent WindowContext of this WindowContext, taking the BFCache into
140 // account. This will not cross chrome/content <browser> boundaries.
141 WindowContext* GetParentWindowContext();
142 WindowContext* TopWindowContext();
144 bool SameOriginWithTop() const;
146 bool IsTop() const;
148 Span<RefPtr<BrowsingContext>> Children() { return mChildren; }
150 // Cast this object to it's parent-process canonical form.
151 WindowGlobalParent* Canonical();
153 nsIGlobalObject* GetParentObject() const;
154 JSObject* WrapObject(JSContext* cx,
155 JS::Handle<JSObject*> aGivenProto) override;
157 void Discard();
159 struct IPCInitializer {
160 uint64_t mInnerWindowId;
161 uint64_t mOuterWindowId;
162 uint64_t mBrowsingContextId;
164 FieldValues mFields;
166 IPCInitializer GetIPCInitializer();
168 static void CreateFromIPC(IPCInitializer&& aInit);
170 // Add new security state flags.
171 // These should be some of the nsIWebProgressListener 'HTTPS_ONLY_MODE' or
172 // 'MIXED' state flags, and should only be called on the top window context.
173 void AddSecurityState(uint32_t aStateFlags);
175 // This function would be called when its corresponding window is activated
176 // by user gesture.
177 void NotifyUserGestureActivation();
179 // This function would be called when we want to reset the user gesture
180 // activation flag.
181 void NotifyResetUserGestureActivation();
183 // Return true if its corresponding window has been activated by user
184 // gesture.
185 bool HasBeenUserGestureActivated();
187 // Return true if its corresponding window has transient user gesture
188 // activation and the transient user gesture activation haven't yet timed
189 // out.
190 bool HasValidTransientUserGestureActivation();
192 // See `mUserGestureStart`.
193 const TimeStamp& GetUserGestureStart() const;
195 // Return true if the corresponding window has valid transient user gesture
196 // activation and the transient user gesture activation had been consumed
197 // successfully.
198 bool ConsumeTransientUserGestureActivation();
200 bool CanShowPopup();
202 bool HadLazyLoadImage() const { return GetHadLazyLoadImage(); }
204 bool AllowJavascript() const { return GetAllowJavascript(); }
205 bool CanExecuteScripts() const { return mCanExecuteScripts; }
207 protected:
208 WindowContext(BrowsingContext* aBrowsingContext, uint64_t aInnerWindowId,
209 uint64_t aOuterWindowId, FieldValues&& aFields);
210 virtual ~WindowContext();
212 virtual void Init();
214 private:
215 friend class BrowsingContext;
216 friend class WindowGlobalChild;
217 friend class WindowGlobalActor;
219 void AppendChildBrowsingContext(BrowsingContext* aBrowsingContext);
220 void RemoveChildBrowsingContext(BrowsingContext* aBrowsingContext);
222 // Send a given `BaseTransaction` object to the correct remote.
223 void SendCommitTransaction(ContentParent* aParent,
224 const BaseTransaction& aTxn, uint64_t aEpoch);
225 void SendCommitTransaction(ContentChild* aChild, const BaseTransaction& aTxn,
226 uint64_t aEpoch);
228 bool CheckOnlyOwningProcessCanSet(ContentParent* aSource);
230 // Overload `CanSet` to get notifications for a particular field being set.
231 bool CanSet(FieldIndex<IDX_IsSecure>, const bool& aIsSecure,
232 ContentParent* aSource);
233 bool CanSet(FieldIndex<IDX_AllowMixedContent>, const bool& aAllowMixedContent,
234 ContentParent* aSource);
236 bool CanSet(FieldIndex<IDX_HasBeforeUnload>, const bool& aHasBeforeUnload,
237 ContentParent* aSource);
239 bool CanSet(FieldIndex<IDX_CookieBehavior>, const Maybe<uint32_t>& aValue,
240 ContentParent* aSource);
242 bool CanSet(FieldIndex<IDX_IsOnContentBlockingAllowList>, const bool& aValue,
243 ContentParent* aSource);
245 bool CanSet(FieldIndex<IDX_EmbedderPolicy>, const bool& aValue,
246 ContentParent* aSource) {
247 return true;
250 bool CanSet(FieldIndex<IDX_IsThirdPartyWindow>,
251 const bool& IsThirdPartyWindow, ContentParent* aSource);
252 bool CanSet(FieldIndex<IDX_IsThirdPartyTrackingResourceWindow>,
253 const bool& aIsThirdPartyTrackingResourceWindow,
254 ContentParent* aSource);
255 bool CanSet(FieldIndex<IDX_IsSecureContext>, const bool& aIsSecureContext,
256 ContentParent* aSource);
257 bool CanSet(FieldIndex<IDX_IsOriginalFrameSource>,
258 const bool& aIsOriginalFrameSource, ContentParent* aSource);
259 bool CanSet(FieldIndex<IDX_DocTreeHadMedia>, const bool& aValue,
260 ContentParent* aSource);
261 bool CanSet(FieldIndex<IDX_AutoplayPermission>, const uint32_t& aValue,
262 ContentParent* aSource);
263 bool CanSet(FieldIndex<IDX_ShortcutsPermission>, const uint32_t& aValue,
264 ContentParent* aSource);
265 bool CanSet(FieldIndex<IDX_ActiveMediaSessionContextId>,
266 const Maybe<uint64_t>& aValue, ContentParent* aSource);
267 bool CanSet(FieldIndex<IDX_PopupPermission>, const uint32_t&,
268 ContentParent* aSource);
269 bool CanSet(FieldIndex<IDX_SHEntryHasUserInteraction>,
270 const bool& aSHEntryHasUserInteraction, ContentParent* aSource) {
271 return true;
273 bool CanSet(FieldIndex<IDX_DelegatedPermissions>,
274 const PermissionDelegateHandler::DelegatedPermissionList& aValue,
275 ContentParent* aSource);
276 bool CanSet(FieldIndex<IDX_DelegatedExactHostMatchPermissions>,
277 const PermissionDelegateHandler::DelegatedPermissionList& aValue,
278 ContentParent* aSource);
279 bool CanSet(FieldIndex<IDX_UserActivationState>,
280 const UserActivation::State& aUserActivationState,
281 ContentParent* aSource) {
282 return true;
285 bool CanSet(FieldIndex<IDX_HasReportedShadowDOMUsage>, const bool& aValue,
286 ContentParent* aSource) {
287 return true;
290 bool CanSet(FieldIndex<IDX_IsLocalIP>, const bool& aValue,
291 ContentParent* aSource);
293 bool CanSet(FieldIndex<IDX_HadLazyLoadImage>, const bool& aValue,
294 ContentParent* aSource);
296 bool CanSet(FieldIndex<IDX_AllowJavascript>, bool aValue,
297 ContentParent* aSource);
298 void DidSet(FieldIndex<IDX_AllowJavascript>, bool aOldValue);
300 bool CanSet(FieldIndex<IDX_HasActivePeerConnections>, bool, ContentParent*);
302 void DidSet(FieldIndex<IDX_HasReportedShadowDOMUsage>, bool aOldValue);
304 void DidSet(FieldIndex<IDX_SHEntryHasUserInteraction>, bool aOldValue);
306 bool CanSet(FieldIndex<IDX_WindowStateSaved>, bool aValue,
307 ContentParent* aSource);
309 // Overload `DidSet` to get notifications for a particular field being set.
311 // You can also overload the variant that gets the old value if you need it.
312 template <size_t I>
313 void DidSet(FieldIndex<I>) {}
314 template <size_t I, typename T>
315 void DidSet(FieldIndex<I>, T&& aOldValue) {}
316 void DidSet(FieldIndex<IDX_UserActivationState>);
318 // Recomputes whether we can execute scripts in this WindowContext based on
319 // the value of AllowJavascript() and whether scripts are allowed in the
320 // BrowsingContext.
321 void RecomputeCanExecuteScripts(bool aApplyChanges = true);
323 const uint64_t mInnerWindowId;
324 const uint64_t mOuterWindowId;
325 RefPtr<BrowsingContext> mBrowsingContext;
326 WeakPtr<WindowGlobalChild> mWindowGlobalChild;
328 // --- NEVER CHANGE `mChildren` DIRECTLY! ---
329 // Changes to this list need to be synchronized to the list within our
330 // `mBrowsingContext`, and should only be performed through the
331 // `AppendChildBrowsingContext` and `RemoveChildBrowsingContext` methods.
332 nsTArray<RefPtr<BrowsingContext>> mChildren;
334 bool mIsDiscarded = false;
335 bool mIsInProcess = false;
337 // Determines if we can execute scripts in this WindowContext. True if
338 // AllowJavascript() is true and script execution is allowed in the
339 // BrowsingContext.
340 bool mCanExecuteScripts = true;
342 // The start time of user gesture, this is only available if the window
343 // context is in process.
344 TimeStamp mUserGestureStart;
347 using WindowContextTransaction = WindowContext::BaseTransaction;
348 using WindowContextInitializer = WindowContext::IPCInitializer;
349 using MaybeDiscardedWindowContext = MaybeDiscarded<WindowContext>;
351 // Don't specialize the `Transaction` object for every translation unit it's
352 // used in. This should help keep code size down.
353 extern template class syncedcontext::Transaction<WindowContext>;
355 } // namespace dom
357 namespace ipc {
358 template <>
359 struct IPDLParamTraits<dom::MaybeDiscarded<dom::WindowContext>> {
360 static void Write(IPC::MessageWriter* aWriter, IProtocol* aActor,
361 const dom::MaybeDiscarded<dom::WindowContext>& aParam);
362 static bool Read(IPC::MessageReader* aReader, IProtocol* aActor,
363 dom::MaybeDiscarded<dom::WindowContext>* aResult);
366 template <>
367 struct IPDLParamTraits<dom::WindowContext::IPCInitializer> {
368 static void Write(IPC::MessageWriter* aWriter, IProtocol* aActor,
369 const dom::WindowContext::IPCInitializer& aInitializer);
371 static bool Read(IPC::MessageReader* aReader, IProtocol* aActor,
372 dom::WindowContext::IPCInitializer* aInitializer);
374 } // namespace ipc
375 } // namespace mozilla
377 #endif // !defined(mozilla_dom_WindowContext_h)