Bug 1807268 - Fix verifyOpenAllInNewTabsOptionTest UI test r=ohorvath
[gecko.git] / docshell / base / WindowContext.h
blobfda403004506e1c3bf03ea9554fbfabfa5abcaa5
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 /* 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 \
68 * handler */ \
69 FIELD(HasBeforeUnload, bool) \
70 /* Controls whether the WindowContext is currently considered to be \
71 * activated by a gesture */ \
72 FIELD(UserActivationStateAndModifiers, \
73 UserActivation::StateAndModifiers::DataT) \
74 FIELD(EmbedderPolicy, nsILoadInfo::CrossOriginEmbedderPolicy) \
75 /* True if this document tree contained at least a HTMLMediaElement. \
76 * This should only be set on top level context. */ \
77 FIELD(DocTreeHadMedia, bool) \
78 FIELD(AutoplayPermission, uint32_t) \
79 FIELD(ShortcutsPermission, uint32_t) \
80 /* Store the Id of the browsing context where active media session \
81 * exists on the top level window context */ \
82 FIELD(ActiveMediaSessionContextId, Maybe<uint64_t>) \
83 /* ALLOW_ACTION if it is allowed to open popups for the sub-tree \
84 * starting and including the current WindowContext */ \
85 FIELD(PopupPermission, uint32_t) \
86 FIELD(DelegatedPermissions, \
87 PermissionDelegateHandler::DelegatedPermissionList) \
88 FIELD(DelegatedExactHostMatchPermissions, \
89 PermissionDelegateHandler::DelegatedPermissionList) \
90 FIELD(HasReportedShadowDOMUsage, bool) \
91 /* Whether the principal of this window is for a local \
92 * IP address */ \
93 FIELD(IsLocalIP, bool) \
94 /* Whether any of the windows in the subtree rooted at this window has \
95 * active peer connections or not (only set on the top window). */ \
96 FIELD(HasActivePeerConnections, bool) \
97 /* Whether we can execute scripts in this WindowContext. Has no effect \
98 * unless scripts are also allowed in the BrowsingContext. */ \
99 FIELD(AllowJavascript, bool) \
100 /* If this field is `true`, it means that this WindowContext's \
101 * WindowState was saved to be stored in the legacy (non-SHIP) BFCache \
102 * implementation. Always false for SHIP */ \
103 FIELD(WindowStateSaved, bool)
105 class WindowContext : public nsISupports, public nsWrapperCache {
106 MOZ_DECL_SYNCED_CONTEXT(WindowContext, MOZ_EACH_WC_FIELD)
108 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
109 NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(WindowContext)
111 public:
112 static already_AddRefed<WindowContext> GetById(uint64_t aInnerWindowId);
113 static LogModule* GetLog();
114 static LogModule* GetSyncLog();
116 BrowsingContext* GetBrowsingContext() const { return mBrowsingContext; }
117 BrowsingContextGroup* Group() const;
118 uint64_t Id() const { return InnerWindowId(); }
119 uint64_t InnerWindowId() const { return mInnerWindowId; }
120 uint64_t OuterWindowId() const { return mOuterWindowId; }
121 bool IsDiscarded() const { return mIsDiscarded; }
123 // Returns `true` if this WindowContext is the current WindowContext in its
124 // BrowsingContext.
125 bool IsCurrent() const;
127 // Returns `true` if this WindowContext is currently in the BFCache.
128 bool IsInBFCache();
130 bool IsInProcess() const { return mIsInProcess; }
132 bool HasBeforeUnload() const { return GetHasBeforeUnload(); }
134 bool IsLocalIP() const { return GetIsLocalIP(); }
136 bool ShouldResistFingerprinting() const {
137 return GetShouldResistFingerprinting();
140 Nullable<uint64_t> GetOverriddenFingerprintingSettingsWebIDL() const {
141 Maybe<RFPTarget> overriddenFingerprintingSettings =
142 GetOverriddenFingerprintingSettings();
144 return overriddenFingerprintingSettings.isSome()
145 ? Nullable<uint64_t>(
146 uint64_t(overriddenFingerprintingSettings.ref()))
147 : Nullable<uint64_t>();
150 nsGlobalWindowInner* GetInnerWindow() const;
151 Document* GetDocument() const;
152 Document* GetExtantDoc() const;
154 WindowGlobalChild* GetWindowGlobalChild() const;
156 // Get the parent WindowContext of this WindowContext, taking the BFCache into
157 // account. This will not cross chrome/content <browser> boundaries.
158 WindowContext* GetParentWindowContext();
159 WindowContext* TopWindowContext();
161 bool SameOriginWithTop() const;
163 bool IsTop() const;
165 Span<RefPtr<BrowsingContext>> Children() { return mChildren; }
167 // The filtered version of `Children()`, which contains no browsing contexts
168 // for synthetic documents as created by object loading content.
169 Span<RefPtr<BrowsingContext>> NonSyntheticChildren() {
170 return mNonSyntheticChildren;
173 // Cast this object to it's parent-process canonical form.
174 WindowGlobalParent* Canonical();
176 nsIGlobalObject* GetParentObject() const;
177 JSObject* WrapObject(JSContext* cx,
178 JS::Handle<JSObject*> aGivenProto) override;
180 void Discard();
182 struct IPCInitializer {
183 uint64_t mInnerWindowId;
184 uint64_t mOuterWindowId;
185 uint64_t mBrowsingContextId;
187 FieldValues mFields;
189 IPCInitializer GetIPCInitializer();
191 static void CreateFromIPC(IPCInitializer&& aInit);
193 // Add new security state flags.
194 // These should be some of the nsIWebProgressListener 'HTTPS_ONLY_MODE' or
195 // 'MIXED' state flags, and should only be called on the top window context.
196 void AddSecurityState(uint32_t aStateFlags);
198 UserActivation::State GetUserActivationState() const {
199 return UserActivation::StateAndModifiers(
200 GetUserActivationStateAndModifiers())
201 .GetState();
204 // This function would be called when its corresponding window is activated
205 // by user gesture.
206 void NotifyUserGestureActivation(
207 UserActivation::Modifiers aModifiers = UserActivation::Modifiers::None());
209 // This function would be called when we want to reset the user gesture
210 // activation flag.
211 void NotifyResetUserGestureActivation();
213 // Return true if its corresponding window has been activated by user
214 // gesture.
215 bool HasBeenUserGestureActivated();
217 // Return true if its corresponding window has transient user gesture
218 // activation and the transient user gesture activation haven't yet timed
219 // out.
220 bool HasValidTransientUserGestureActivation();
222 // See `mUserGestureStart`.
223 const TimeStamp& GetUserGestureStart() const;
225 // Return true if the corresponding window has valid transient user gesture
226 // activation and the transient user gesture activation had been consumed
227 // successfully.
228 bool ConsumeTransientUserGestureActivation();
230 bool GetTransientUserGestureActivationModifiers(
231 UserActivation::Modifiers* aModifiers);
233 bool CanShowPopup();
235 bool AllowJavascript() const { return GetAllowJavascript(); }
236 bool CanExecuteScripts() const { return mCanExecuteScripts; }
238 void TransientSetHasActivePeerConnections();
240 protected:
241 WindowContext(BrowsingContext* aBrowsingContext, uint64_t aInnerWindowId,
242 uint64_t aOuterWindowId, FieldValues&& aFields);
243 virtual ~WindowContext();
245 virtual void Init();
247 private:
248 friend class BrowsingContext;
249 friend class WindowGlobalChild;
250 friend class WindowGlobalActor;
252 void AppendChildBrowsingContext(BrowsingContext* aBrowsingContext);
253 void RemoveChildBrowsingContext(BrowsingContext* aBrowsingContext);
255 // Update non-synthetic children based on whether `aBrowsingContext`
256 // is synthetic or not. Regardless the synthetic of `aBrowsingContext`, it is
257 // kept in this WindowContext's all children list.
258 void UpdateChildSynthetic(BrowsingContext* aBrowsingContext,
259 bool aIsSynthetic);
261 // Send a given `BaseTransaction` object to the correct remote.
262 void SendCommitTransaction(ContentParent* aParent,
263 const BaseTransaction& aTxn, uint64_t aEpoch);
264 void SendCommitTransaction(ContentChild* aChild, const BaseTransaction& aTxn,
265 uint64_t aEpoch);
267 bool CheckOnlyOwningProcessCanSet(ContentParent* aSource);
269 // Overload `CanSet` to get notifications for a particular field being set.
270 bool CanSet(FieldIndex<IDX_IsSecure>, const bool& aIsSecure,
271 ContentParent* aSource);
272 bool CanSet(FieldIndex<IDX_AllowMixedContent>, const bool& aAllowMixedContent,
273 ContentParent* aSource);
275 bool CanSet(FieldIndex<IDX_HasBeforeUnload>, const bool& aHasBeforeUnload,
276 ContentParent* aSource);
278 bool CanSet(FieldIndex<IDX_CookieBehavior>, const Maybe<uint32_t>& aValue,
279 ContentParent* aSource);
281 bool CanSet(FieldIndex<IDX_IsOnContentBlockingAllowList>, const bool& aValue,
282 ContentParent* aSource);
284 bool CanSet(FieldIndex<IDX_EmbedderPolicy>, const bool& aValue,
285 ContentParent* aSource) {
286 return true;
289 bool CanSet(FieldIndex<IDX_IsThirdPartyWindow>,
290 const bool& IsThirdPartyWindow, ContentParent* aSource);
291 bool CanSet(FieldIndex<IDX_IsThirdPartyTrackingResourceWindow>,
292 const bool& aIsThirdPartyTrackingResourceWindow,
293 ContentParent* aSource);
294 bool CanSet(FieldIndex<IDX_UsingStorageAccess>,
295 const bool& aUsingStorageAccess, ContentParent* aSource);
296 bool CanSet(FieldIndex<IDX_ShouldResistFingerprinting>,
297 const bool& aShouldResistFingerprinting, ContentParent* aSource);
298 bool CanSet(FieldIndex<IDX_OverriddenFingerprintingSettings>,
299 const Maybe<RFPTarget>& aValue, ContentParent* aSource);
300 bool CanSet(FieldIndex<IDX_IsSecureContext>, const bool& aIsSecureContext,
301 ContentParent* aSource);
302 bool CanSet(FieldIndex<IDX_IsOriginalFrameSource>,
303 const bool& aIsOriginalFrameSource, ContentParent* aSource);
304 bool CanSet(FieldIndex<IDX_DocTreeHadMedia>, const bool& aValue,
305 ContentParent* aSource);
306 bool CanSet(FieldIndex<IDX_AutoplayPermission>, const uint32_t& aValue,
307 ContentParent* aSource);
308 bool CanSet(FieldIndex<IDX_ShortcutsPermission>, const uint32_t& aValue,
309 ContentParent* aSource);
310 bool CanSet(FieldIndex<IDX_ActiveMediaSessionContextId>,
311 const Maybe<uint64_t>& aValue, ContentParent* aSource);
312 bool CanSet(FieldIndex<IDX_PopupPermission>, const uint32_t&,
313 ContentParent* aSource);
314 bool CanSet(FieldIndex<IDX_SHEntryHasUserInteraction>,
315 const bool& aSHEntryHasUserInteraction, ContentParent* aSource) {
316 return true;
318 bool CanSet(FieldIndex<IDX_DelegatedPermissions>,
319 const PermissionDelegateHandler::DelegatedPermissionList& aValue,
320 ContentParent* aSource);
321 bool CanSet(FieldIndex<IDX_DelegatedExactHostMatchPermissions>,
322 const PermissionDelegateHandler::DelegatedPermissionList& aValue,
323 ContentParent* aSource);
324 bool CanSet(FieldIndex<IDX_UserActivationStateAndModifiers>,
325 const UserActivation::StateAndModifiers::DataT&
326 aUserActivationStateAndModifiers,
327 ContentParent* aSource) {
328 return true;
331 bool CanSet(FieldIndex<IDX_HasReportedShadowDOMUsage>, const bool& aValue,
332 ContentParent* aSource) {
333 return true;
336 bool CanSet(FieldIndex<IDX_IsLocalIP>, const bool& aValue,
337 ContentParent* aSource);
339 bool CanSet(FieldIndex<IDX_AllowJavascript>, bool aValue,
340 ContentParent* aSource);
341 void DidSet(FieldIndex<IDX_AllowJavascript>, bool aOldValue);
343 bool CanSet(FieldIndex<IDX_HasActivePeerConnections>, bool, ContentParent*);
345 void DidSet(FieldIndex<IDX_HasReportedShadowDOMUsage>, bool aOldValue);
347 void DidSet(FieldIndex<IDX_SHEntryHasUserInteraction>, bool aOldValue);
349 bool CanSet(FieldIndex<IDX_WindowStateSaved>, bool aValue,
350 ContentParent* aSource);
352 // Overload `DidSet` to get notifications for a particular field being set.
354 // You can also overload the variant that gets the old value if you need it.
355 template <size_t I>
356 void DidSet(FieldIndex<I>) {}
357 template <size_t I, typename T>
358 void DidSet(FieldIndex<I>, T&& aOldValue) {}
359 void DidSet(FieldIndex<IDX_UserActivationStateAndModifiers>);
361 // Recomputes whether we can execute scripts in this WindowContext based on
362 // the value of AllowJavascript() and whether scripts are allowed in the
363 // BrowsingContext.
364 void RecomputeCanExecuteScripts(bool aApplyChanges = true);
366 const uint64_t mInnerWindowId;
367 const uint64_t mOuterWindowId;
368 RefPtr<BrowsingContext> mBrowsingContext;
369 WeakPtr<WindowGlobalChild> mWindowGlobalChild;
371 // --- NEVER CHANGE `mChildren` DIRECTLY! ---
372 // Changes to this list need to be synchronized to the list within our
373 // `mBrowsingContext`, and should only be performed through the
374 // `AppendChildBrowsingContext` and `RemoveChildBrowsingContext` methods.
375 nsTArray<RefPtr<BrowsingContext>> mChildren;
377 // --- NEVER CHANGE `mNonSyntheticChildren` DIRECTLY! ---
378 // Same reason as for mChildren.
379 // mNonSyntheticChildren contains the same browsing contexts except browsing
380 // contexts created by the synthetic document for object loading contents
381 // loading images. This is used to discern browsing contexts created when
382 // loading images in <object> or <embed> elements, so that they can be hidden
383 // from named targeting, `Window.frames` etc.
384 nsTArray<RefPtr<BrowsingContext>> mNonSyntheticChildren;
386 bool mIsDiscarded = false;
387 bool mIsInProcess = false;
389 // Determines if we can execute scripts in this WindowContext. True if
390 // AllowJavascript() is true and script execution is allowed in the
391 // BrowsingContext.
392 bool mCanExecuteScripts = true;
394 // The start time of user gesture, this is only available if the window
395 // context is in process.
396 TimeStamp mUserGestureStart;
399 using WindowContextTransaction = WindowContext::BaseTransaction;
400 using WindowContextInitializer = WindowContext::IPCInitializer;
401 using MaybeDiscardedWindowContext = MaybeDiscarded<WindowContext>;
403 // Don't specialize the `Transaction` object for every translation unit it's
404 // used in. This should help keep code size down.
405 extern template class syncedcontext::Transaction<WindowContext>;
407 } // namespace dom
409 namespace ipc {
410 template <>
411 struct IPDLParamTraits<dom::MaybeDiscarded<dom::WindowContext>> {
412 static void Write(IPC::MessageWriter* aWriter, IProtocol* aActor,
413 const dom::MaybeDiscarded<dom::WindowContext>& aParam);
414 static bool Read(IPC::MessageReader* aReader, IProtocol* aActor,
415 dom::MaybeDiscarded<dom::WindowContext>* aResult);
418 template <>
419 struct IPDLParamTraits<dom::WindowContext::IPCInitializer> {
420 static void Write(IPC::MessageWriter* aWriter, IProtocol* aActor,
421 const dom::WindowContext::IPCInitializer& aInitializer);
423 static bool Read(IPC::MessageReader* aReader, IProtocol* aActor,
424 dom::WindowContext::IPCInitializer* aInitializer);
426 } // namespace ipc
427 } // namespace mozilla
429 #endif // !defined(mozilla_dom_WindowContext_h)