1 /* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
2 /* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
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/. */
6
7 #ifndef mozilla_dom_WindowGlobalParent_h
8 #define mozilla_dom_WindowGlobalParent_h
9
10 #include "mozilla/ContentBlockingLog.h"
11 #include "mozilla/ContentBlockingNotifier.h"
12 #include "mozilla/Maybe.h"
13 #include "mozilla/RefPtr.h"
14 #include "mozilla/UniquePtr.h"
15 #include "mozilla/dom/ClientInfo.h"
16 #include "mozilla/dom/ClientIPCTypes.h"
17 #include "mozilla/dom/DOMRect.h"
18 #include "mozilla/dom/PWindowGlobalParent.h"
19 #include "mozilla/dom/WindowContext.h"
20 #include "mozilla/dom/WindowGlobalActorsBinding.h"
21 #include "nsTHashMap.h"
22 #include "nsRefPtrHashtable.h"
23 #include "nsWrapperCache.h"
24 #include "nsISupports.h"
25 #include "nsIDOMProcessParent.h"
26 #include "mozilla/dom/WindowGlobalActor.h"
27 #include "mozilla/dom/CanonicalBrowsingContext.h"
28 #include "mozilla/net/CookieJarSettings.h"
29
30 class nsIPrincipal;
31 class nsIURI;
32 class nsFrameLoader;
33
34 namespace mozilla {
35
36 namespace gfx {
37 class CrossProcessPaint;
38 } // namespace gfx
39
40 namespace dom {
41
42 class BrowserParent;
43 class WindowGlobalChild;
44 class JSWindowActorParent;
45 class JSActorMessageMeta;
46 struct PageUseCounters;
47 class WindowSessionStoreState;
48 struct WindowSessionStoreUpdate;
49 class SSCacheQueryResult;
50
51 /**
52 * A handle in the parent process to a specific nsGlobalWindowInner object.
53 */
54 class WindowGlobalParent final : public WindowContext,
55 public WindowGlobalActor,
56 public PWindowGlobalParent {
57 friend class gfx::CrossProcessPaint;
58 friend class PWindowGlobalParent;
59
60 public:
61 NS_DECL_ISUPPORTS_INHERITED
62 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WindowGlobalParent,
63 WindowContext)
64
65 static already_AddRefed<WindowGlobalParent> GetByInnerWindowId(
66 uint64_t aInnerWindowId);
67
GetByInnerWindowId(const GlobalObject & aGlobal,uint64_t aInnerWindowId)68 static already_AddRefed<WindowGlobalParent> GetByInnerWindowId(
69 const GlobalObject& aGlobal, uint64_t aInnerWindowId) {
70 return GetByInnerWindowId(aInnerWindowId);
71 }
72
73 // The same as the corresponding methods on `WindowContext`, except that the
74 // return types are already cast to their parent-process type variants, such
75 // as `WindowGlobalParent` or `CanonicalBrowsingContext`.
GetParentWindowContext()76 WindowGlobalParent* GetParentWindowContext() {
77 return static_cast<WindowGlobalParent*>(
78 WindowContext::GetParentWindowContext());
79 }
TopWindowContext()80 WindowGlobalParent* TopWindowContext() {
81 return static_cast<WindowGlobalParent*>(WindowContext::TopWindowContext());
82 }
GetBrowsingContext()83 CanonicalBrowsingContext* GetBrowsingContext() {
84 return CanonicalBrowsingContext::Cast(WindowContext::GetBrowsingContext());
85 }
86
87 Element* GetRootOwnerElement();
88
89 // Has this actor been shut down
IsClosed()90 bool IsClosed() { return !CanSend(); }
91
92 // Get the other side of this actor if it is an in-process actor. Returns
93 // |nullptr| if the actor has been torn down, or is not in-process.
94 already_AddRefed<WindowGlobalChild> GetChildActor();
95
96 // Get a JS actor object by name.
97 already_AddRefed<JSWindowActorParent> GetActor(JSContext* aCx,
98 const nsACString& aName,
99 ErrorResult& aRv);
100 already_AddRefed<JSWindowActorParent> GetExistingActor(
101 const nsACString& aName);
102
103 // Get this actor's manager if it is not an in-process actor. Returns
104 // |nullptr| if the actor has been torn down, or is in-process.
105 BrowserParent* GetBrowserParent();
106
107 ContentParent* GetContentParent();
108
109 // The principal of this WindowGlobal. This value will not change over the
110 // lifetime of the WindowGlobal object, even to reflect changes in
111 // |document.domain|.
DocumentPrincipal()112 nsIPrincipal* DocumentPrincipal() { return mDocumentPrincipal; }
113
DocumentStoragePrincipal()114 nsIPrincipal* DocumentStoragePrincipal() { return mDocumentStoragePrincipal; }
115
116 // The BrowsingContext which this WindowGlobal has been loaded into.
117 // FIXME: It's quite awkward that this method has a slightly different name
118 // than the one on WindowContext.
BrowsingContext()119 CanonicalBrowsingContext* BrowsingContext() override {
120 return GetBrowsingContext();
121 }
122
123 // Get the root nsFrameLoader object for the tree of BrowsingContext nodes
124 // which this WindowGlobal is a part of. This will be the nsFrameLoader
125 // holding the BrowserParent for remote tabs, and the root content frameloader
126 // for non-remote tabs.
127 already_AddRefed<nsFrameLoader> GetRootFrameLoader();
128
129 // The current URI which loaded in the document.
GetDocumentURI()130 nsIURI* GetDocumentURI() override { return mDocumentURI; }
131
GetDocumentTitle(nsAString & aTitle)132 void GetDocumentTitle(nsAString& aTitle) const {
133 aTitle = mDocumentTitle.valueOr(nsString());
134 }
135
GetContentBlockingAllowListPrincipal()136 nsIPrincipal* GetContentBlockingAllowListPrincipal() const {
137 return mDocContentBlockingAllowListPrincipal;
138 }
139
GetClientInfo()140 Maybe<ClientInfo> GetClientInfo() { return mClientInfo; }
141
142 uint64_t ContentParentId();
143
144 int32_t OsPid();
145
146 bool IsCurrentGlobal();
147
148 bool IsProcessRoot();
149
150 uint32_t ContentBlockingEvents();
151
152 void GetContentBlockingLog(nsAString& aLog);
153
IsInitialDocument()154 bool IsInitialDocument() { return mIsInitialDocument; }
155
156 already_AddRefed<mozilla::dom::Promise> PermitUnload(
157 PermitUnloadAction aAction, uint32_t aTimeout, mozilla::ErrorResult& aRv);
158
159 void PermitUnload(std::function<void(bool)>&& aResolver);
160
161 already_AddRefed<mozilla::dom::Promise> DrawSnapshot(
162 const DOMRect* aRect, double aScale, const nsACString& aBackgroundColor,
163 mozilla::ErrorResult& aRv);
164
165 already_AddRefed<Promise> GetSecurityInfo(ErrorResult& aRv);
166
167 static already_AddRefed<WindowGlobalParent> CreateDisconnected(
168 const WindowGlobalInit& aInit);
169
170 // Initialize the mFrameLoader fields for a created WindowGlobalParent. Must
171 // be called after setting the Manager actor.
172 void Init() final;
173
174 nsIGlobalObject* GetParentObject();
175 JSObject* WrapObject(JSContext* aCx,
176 JS::Handle<JSObject*> aGivenProto) override;
177
178 void NotifyContentBlockingEvent(
179 uint32_t aEvent, nsIRequest* aRequest, bool aBlocked,
180 const nsACString& aTrackingOrigin,
181 const nsTArray<nsCString>& aTrackingFullHashes,
182 const Maybe<
183 ContentBlockingNotifier::StorageAccessPermissionGrantedReason>&
184 aReason = Nothing());
185
GetContentBlockingLog()186 ContentBlockingLog* GetContentBlockingLog() { return &mContentBlockingLog; }
187
188 nsIDOMProcessParent* GetDomProcess();
189
CookieJarSettings()190 nsICookieJarSettings* CookieJarSettings() { return mCookieJarSettings; }
191
GetCookieJarSettings()192 nsICookieJarSettings* GetCookieJarSettings() const {
193 return mCookieJarSettings;
194 }
195
DocumentHasLoaded()196 bool DocumentHasLoaded() { return mDocumentHasLoaded; }
197
DocumentHasUserInteracted()198 bool DocumentHasUserInteracted() { return mDocumentHasUserInteracted; }
199
SandboxFlags()200 uint32_t SandboxFlags() { return mSandboxFlags; }
201
GetDocumentBlockAllMixedContent()202 bool GetDocumentBlockAllMixedContent() { return mBlockAllMixedContent; }
203
GetDocumentUpgradeInsecureRequests()204 bool GetDocumentUpgradeInsecureRequests() { return mUpgradeInsecureRequests; }
205
206 void DidBecomeCurrentWindowGlobal(bool aCurrent);
207
HttpsOnlyStatus()208 uint32_t HttpsOnlyStatus() { return mHttpsOnlyStatus; }
209
210 void AddSecurityState(uint32_t aStateFlags);
GetSecurityFlags()211 uint32_t GetSecurityFlags() { return mSecurityState; }
212
GetSecurityInfo()213 nsITransportSecurityInfo* GetSecurityInfo() { return mSecurityInfo; }
214
215 const nsACString& GetRemoteType() override;
216
217 nsresult WriteFormDataAndScrollToSessionStore(
218 const Maybe<FormData>& aFormData, const Maybe<nsPoint>& aScrollPosition,
219 uint32_t aEpoch);
220
221 void NotifySessionStoreUpdatesComplete(Element* aEmbedder);
222
GetSingleChannelId()223 Maybe<uint64_t> GetSingleChannelId() { return mSingleChannelId; }
224
GetBFCacheStatus()225 uint16_t GetBFCacheStatus() { return mBFCacheStatus; }
226
227 protected:
228 already_AddRefed<JSActor> InitJSActor(JS::HandleObject aMaybeActor,
229 const nsACString& aName,
230 ErrorResult& aRv) override;
AsNativeActor()231 mozilla::ipc::IProtocol* AsNativeActor() override { return this; }
232
233 // IPC messages
234 mozilla::ipc::IPCResult RecvLoadURI(
235 const MaybeDiscarded<dom::BrowsingContext>& aTargetBC,
236 nsDocShellLoadState* aLoadState, bool aSetNavigating);
237 mozilla::ipc::IPCResult RecvInternalLoad(nsDocShellLoadState* aLoadState);
238 mozilla::ipc::IPCResult RecvUpdateDocumentURI(nsIURI* aURI);
239 mozilla::ipc::IPCResult RecvUpdateDocumentPrincipal(
240 nsIPrincipal* aNewDocumentPrincipal,
241 nsIPrincipal* aNewDocumentStoragePrincipal);
242 mozilla::ipc::IPCResult RecvUpdateDocumentHasLoaded(bool aDocumentHasLoaded);
243 mozilla::ipc::IPCResult RecvUpdateDocumentHasUserInteracted(
244 bool aDocumentHasUserInteracted);
245 mozilla::ipc::IPCResult RecvUpdateSandboxFlags(uint32_t aSandboxFlags);
246 mozilla::ipc::IPCResult RecvUpdateDocumentCspSettings(
247 bool aBlockAllMixedContent, bool aUpgradeInsecureRequests);
248 mozilla::ipc::IPCResult RecvUpdateDocumentTitle(const nsString& aTitle);
249 mozilla::ipc::IPCResult RecvUpdateHttpsOnlyStatus(uint32_t aHttpsOnlyStatus);
RecvSetIsInitialDocument(bool aIsInitialDocument)250 mozilla::ipc::IPCResult RecvSetIsInitialDocument(bool aIsInitialDocument) {
251 mIsInitialDocument = aIsInitialDocument;
252 return IPC_OK();
253 }
254 mozilla::ipc::IPCResult RecvUpdateDocumentSecurityInfo(
255 nsITransportSecurityInfo* aSecurityInfo);
256 mozilla::ipc::IPCResult RecvSetClientInfo(
257 const IPCClientInfo& aIPCClientInfo);
258 mozilla::ipc::IPCResult RecvDestroy();
259 mozilla::ipc::IPCResult RecvRawMessage(
260 const JSActorMessageMeta& aMeta, const Maybe<ClonedMessageData>& aData,
261 const Maybe<ClonedMessageData>& aStack);
262
263 mozilla::ipc::IPCResult RecvGetContentBlockingEvents(
264 GetContentBlockingEventsResolver&& aResolver);
265 mozilla::ipc::IPCResult RecvUpdateCookieJarSettings(
266 const CookieJarSettingsArgs& aCookieJarSettingsArgs);
267
268 void ActorDestroy(ActorDestroyReason aWhy) override;
269
270 void DrawSnapshotInternal(gfx::CrossProcessPaint* aPaint,
271 const Maybe<IntRect>& aRect, float aScale,
272 nscolor aBackgroundColor, uint32_t aFlags);
273
274 // WebShare API - try to share
275 mozilla::ipc::IPCResult RecvShare(IPCWebShareData&& aData,
276 ShareResolver&& aResolver);
277
278 mozilla::ipc::IPCResult RecvCheckPermitUnload(
279 bool aHasInProcessBlocker, XPCOMPermitUnloadAction aAction,
280 CheckPermitUnloadResolver&& aResolver);
281
282 mozilla::ipc::IPCResult RecvExpectPageUseCounters(
283 const MaybeDiscarded<dom::WindowContext>& aTop);
284 mozilla::ipc::IPCResult RecvAccumulatePageUseCounters(
285 const UseCounters& aUseCounters);
286
287 mozilla::ipc::IPCResult RecvRequestRestoreTabContent();
288
289 mozilla::ipc::IPCResult RecvUpdateSessionStore(
290 const Maybe<FormData>& aFormData, const Maybe<nsPoint>& aScrollPosition,
291 uint32_t aEpoch);
292
293 mozilla::ipc::IPCResult RecvResetSessionStore(uint32_t aEpoch);
294
295 mozilla::ipc::IPCResult RecvUpdateBFCacheStatus(const uint16_t& aOnFlags,
296 const uint16_t& aOffFlags);
297
298 public:
299 mozilla::ipc::IPCResult RecvSetSingleChannelId(
300 const Maybe<uint64_t>& aSingleChannelId);
301
302 mozilla::ipc::IPCResult RecvSetDocumentDomain(nsIURI* aDomain);
303
304 private:
305 WindowGlobalParent(CanonicalBrowsingContext* aBrowsingContext,
306 uint64_t aInnerWindowId, uint64_t aOuterWindowId,
307 FieldValues&& aInit);
308
309 ~WindowGlobalParent();
310
311 bool ShouldTrackSiteOriginTelemetry();
312 void FinishAccumulatingPageUseCounters();
313
314 nsresult ResetSessionStore(uint32_t aEpoch);
315
316 // Returns failure if the new storage principal cannot be validated
317 // against the current document principle.
318 nsresult SetDocumentStoragePrincipal(
319 nsIPrincipal* aNewDocumentStoragePrincipal);
320
321 // NOTE: Neither this document principal nor the document storage
322 // principal doesn't reflect possible |document.domain| mutations
323 // which may have been made in the actual document.
324 nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
325 nsCOMPtr<nsIPrincipal> mDocumentStoragePrincipal;
326
327 // The principal to use for the content blocking allow list.
328 nsCOMPtr<nsIPrincipal> mDocContentBlockingAllowListPrincipal;
329
330 nsCOMPtr<nsIURI> mDocumentURI;
331 Maybe<nsString> mDocumentTitle;
332
333 bool mIsInitialDocument;
334
335 // True if this window has a "beforeunload" event listener.
336 bool mHasBeforeUnload;
337
338 // The log of all content blocking actions taken on the document related to
339 // this WindowGlobalParent. This is only stored on top-level documents and
340 // includes the activity log for all of the nested subdocuments as well.
341 ContentBlockingLog mContentBlockingLog;
342
343 uint32_t mSecurityState = 0;
344
345 Maybe<ClientInfo> mClientInfo;
346 // Fields being mirrored from the corresponding document
347 nsCOMPtr<nsICookieJarSettings> mCookieJarSettings;
348 nsCOMPtr<nsITransportSecurityInfo> mSecurityInfo;
349
350 uint32_t mSandboxFlags;
351
352 struct OriginCounter {
353 void UpdateSiteOriginsFrom(WindowGlobalParent* aParent, bool aIncrease);
354 void Accumulate();
355
356 nsTHashMap<nsCStringHashKey, int32_t> mOriginMap;
357 uint32_t mMaxOrigins = 0;
358 };
359
360 // Used to collect unique site origin telemetry.
361 //
362 // Is only Some() on top-level content windows.
363 Maybe<OriginCounter> mOriginCounter;
364
365 bool mDocumentHasLoaded;
366 bool mDocumentHasUserInteracted;
367 bool mDocumentTreeWouldPreloadResources = false;
368 bool mBlockAllMixedContent;
369 bool mUpgradeInsecureRequests;
370
371 // HTTPS-Only Mode flags
372 uint32_t mHttpsOnlyStatus;
373
374 // The window of the document whose page use counters our document's use
375 // counters will contribute to. (If we are a top-level document, this
376 // will point to ourselves.)
377 RefPtr<WindowGlobalParent> mPageUseCountersWindow;
378
379 // Our page use counters, if we are a top-level document.
380 UniquePtr<PageUseCounters> mPageUseCounters;
381
382 // Whether we have sent our page use counters, and so should ignore any
383 // subsequent ExpectPageUseCounters calls.
384 bool mSentPageUseCounters = false;
385
386 uint16_t mBFCacheStatus = 0;
387
388 // mSingleChannelId records whether the loadgroup contains a single request
389 // with an id. If there is one channel in the loadgroup and it has an id then
390 // mSingleChannelId is set to Some(id) (ids are non-zero). If there is one
391 // request in the loadgroup and it's not a channel or it doesn't have an id,
392 // or there are multiple requests in the loadgroup, then mSingleChannelId is
393 // set to Some(0). If there are no requests in the loadgroup then
394 // mSingleChannelId is set to Nothing().
395 // Note: We ignore favicon loads when considering the requests in the
396 // loadgroup.
397 Maybe<uint64_t> mSingleChannelId;
398 };
399
400 } // namespace dom
401 } // namespace mozilla
402
ToSupports(mozilla::dom::WindowGlobalParent * aWindowGlobal)403 inline nsISupports* ToSupports(
404 mozilla::dom::WindowGlobalParent* aWindowGlobal) {
405 return static_cast<mozilla::dom::WindowContext*>(aWindowGlobal);
406 }
407
408 #endif // !defined(mozilla_dom_WindowGlobalParent_h)
409