WindowGlobalParent.h (17477B)
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/CanonicalBrowsingContext.h" 16 #include "mozilla/dom/ClientIPCTypes.h" 17 #include "mozilla/dom/ClientInfo.h" 18 #include "mozilla/dom/DOMRect.h" 19 #include "mozilla/dom/PWindowGlobalParent.h" 20 #include "mozilla/dom/WindowContext.h" 21 #include "mozilla/dom/WindowGlobalActor.h" 22 #include "mozilla/dom/WindowGlobalActorsBinding.h" 23 #include "mozilla/net/CookieJarSettings.h" 24 #include "nsIDOMProcessParent.h" 25 #include "nsISupports.h" 26 #include "nsRefPtrHashtable.h" 27 #include "nsTHashMap.h" 28 #include "nsWrapperCache.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 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`. 76 WindowGlobalParent* GetParentWindowContext() { 77 return static_cast<WindowGlobalParent*>( 78 WindowContext::GetParentWindowContext()); 79 } 80 WindowGlobalParent* TopWindowContext() { 81 return static_cast<WindowGlobalParent*>(WindowContext::TopWindowContext()); 82 } 83 CanonicalBrowsingContext* GetBrowsingContext() const { 84 return CanonicalBrowsingContext::Cast(WindowContext::GetBrowsingContext()); 85 } 86 87 Element* GetRootOwnerElement(); 88 89 // Has this actor been shut down 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() const; 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|. 112 nsIPrincipal* DocumentPrincipal() { return mDocumentPrincipal; } 113 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. 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. 130 nsIURI* GetDocumentURI() override { return mDocumentURI; } 131 132 void GetDocumentTitle(nsAString& aTitle) const { 133 aTitle = mDocumentTitle.valueOr(nsString()); 134 } 135 136 nsIPrincipal* GetContentBlockingAllowListPrincipal() const { 137 return mDocContentBlockingAllowListPrincipal; 138 } 139 140 Maybe<ClientInfo> GetClientInfo() { return mClientInfo; } 141 142 uint64_t ContentParentId(); 143 144 int32_t OsPid(); 145 146 bool IsCurrentGlobal(); 147 148 bool IsActiveInTab(); 149 150 bool IsProcessRoot(); 151 152 uint32_t ContentBlockingEvents(); 153 154 void GetContentBlockingLog(nsAString& aLog); 155 156 bool IsInitialDocument() { 157 return mIsInitialDocument.isSome() && mIsInitialDocument.value(); 158 } 159 160 bool IsUncommittedInitialDocument() { return mIsUncommittedInitialDocument; } 161 162 already_AddRefed<mozilla::dom::Promise> PermitUnload( 163 PermitUnloadAction aAction, uint32_t aTimeout, mozilla::ErrorResult& aRv); 164 165 void PermitUnload( 166 std::function<void(nsIDocumentViewer::PermitUnloadResult)>&& aResolver); 167 168 void PermitUnloadTraversable( 169 const SessionHistoryInfo& aInfo, 170 nsIDocumentViewer::PermitUnloadAction aAction, 171 std::function<void(nsIDocumentViewer::PermitUnloadResult)>&& aResolver); 172 173 void PermitUnloadChildNavigables( 174 nsIDocumentViewer::PermitUnloadAction aAction, 175 std::function<void(nsIDocumentViewer::PermitUnloadResult)>&& aResolver); 176 177 already_AddRefed<mozilla::dom::Promise> DrawSnapshot( 178 const DOMRect* aRect, double aScale, const nsACString& aBackgroundColor, 179 bool aResetScrollPosition, mozilla::ErrorResult& aRv); 180 181 static already_AddRefed<WindowGlobalParent> CreateDisconnected( 182 const WindowGlobalInit& aInit); 183 184 // Initialize the mFrameLoader fields for a created WindowGlobalParent. Must 185 // be called after setting the Manager actor. 186 void Init() final; 187 188 nsIGlobalObject* GetParentObject(); 189 JSObject* WrapObject(JSContext* aCx, 190 JS::Handle<JSObject*> aGivenProto) override; 191 192 void NotifyContentBlockingEvent( 193 uint32_t aEvent, nsIRequest* aRequest, bool aBlocked, 194 const nsACString& aTrackingOrigin, 195 const nsTArray<nsCString>& aTrackingFullHashes, 196 const Maybe< 197 ContentBlockingNotifier::StorageAccessPermissionGrantedReason>& 198 aReason, 199 const Maybe<CanvasFingerprintingEvent>& aCanvasFingerprintingEvent); 200 201 ContentBlockingLog* GetContentBlockingLog() { return &mContentBlockingLog; } 202 203 nsIDOMProcessParent* GetDomProcess(); 204 205 nsICookieJarSettings* CookieJarSettings() { return mCookieJarSettings; } 206 207 nsICookieJarSettings* GetCookieJarSettings() const { 208 return mCookieJarSettings; 209 } 210 211 bool DocumentHasLoaded() { return mDocumentHasLoaded; } 212 213 bool DocumentHasUserInteracted() { return mDocumentHasUserInteracted; } 214 215 uint32_t SandboxFlags() { return mSandboxFlags; } 216 217 bool GetDocumentBlockAllMixedContent() { return mBlockAllMixedContent; } 218 219 bool GetDocumentUpgradeInsecureRequests() { return mUpgradeInsecureRequests; } 220 221 void DidBecomeCurrentWindowGlobal(bool aCurrent); 222 223 uint32_t HttpsOnlyStatus() { return mHttpsOnlyStatus; } 224 225 void AddSecurityState(uint32_t aStateFlags); 226 uint32_t GetSecurityFlags() { return mSecurityState; } 227 228 nsITransportSecurityInfo* GetSecurityInfo() { return mSecurityInfo; } 229 230 const nsACString& GetRemoteType() const override; 231 232 void NotifySessionStoreUpdatesComplete(Element* aEmbedder); 233 234 Maybe<uint64_t> GetSingleChannelId() { return mSingleChannelId; } 235 236 uint32_t GetBFCacheStatus() { return mBFCacheStatus; } 237 238 bool HasActivePeerConnections(); 239 240 bool Fullscreen() { return mFullscreen; } 241 void SetFullscreen(bool aFullscreen) { mFullscreen = aFullscreen; } 242 243 void ExitTopChromeDocumentFullscreen(); 244 245 void SetShouldReportHasBlockedOpaqueResponse( 246 nsContentPolicyType aContentPolicy); 247 248 protected: 249 already_AddRefed<JSActor> InitJSActor(JS::Handle<JSObject*> aMaybeActor, 250 const nsACString& aName, 251 ErrorResult& aRv) override; 252 mozilla::ipc::IProtocol* AsNativeActor() override { return this; } 253 254 // IPC messages 255 mozilla::ipc::IPCResult RecvLoadURI( 256 const MaybeDiscarded<dom::BrowsingContext>& aTargetBC, 257 nsDocShellLoadState* aLoadState, bool aSetNavigating); 258 mozilla::ipc::IPCResult RecvInternalLoad(nsDocShellLoadState* aLoadState); 259 mozilla::ipc::IPCResult RecvUpdateDocumentURI(NotNull<nsIURI*> aURI); 260 mozilla::ipc::IPCResult RecvUpdateDocumentPrincipal( 261 nsIPrincipal* aNewDocumentPrincipal, 262 nsIPrincipal* aNewDocumentStoragePrincipal); 263 mozilla::ipc::IPCResult RecvUpdateDocumentHasLoaded(bool aDocumentHasLoaded); 264 mozilla::ipc::IPCResult RecvUpdateDocumentHasUserInteracted( 265 bool aDocumentHasUserInteracted); 266 mozilla::ipc::IPCResult RecvUpdateSandboxFlags(uint32_t aSandboxFlags); 267 mozilla::ipc::IPCResult RecvUpdateDocumentCspSettings( 268 bool aBlockAllMixedContent, bool aUpgradeInsecureRequests); 269 mozilla::ipc::IPCResult RecvUpdateDocumentTitle(const nsString& aTitle); 270 mozilla::ipc::IPCResult RecvUpdateHttpsOnlyStatus(uint32_t aHttpsOnlyStatus); 271 mozilla::ipc::IPCResult RecvSetIsInitialDocument(bool aIsInitialDocument) { 272 if (aIsInitialDocument && mIsInitialDocument.isSome() && 273 (mIsInitialDocument.value() != aIsInitialDocument)) { 274 return IPC_FAIL_NO_REASON(this); 275 } 276 277 mIsInitialDocument = Some(aIsInitialDocument); 278 mIsUncommittedInitialDocument = aIsInitialDocument; 279 return IPC_OK(); 280 } 281 mozilla::ipc::IPCResult RecvCommitToInitialDocument() { 282 MOZ_ASSERT(mIsInitialDocument.isSome() && mIsInitialDocument.value()); 283 mIsUncommittedInitialDocument = false; 284 return IPC_OK(); 285 } 286 mozilla::ipc::IPCResult RecvUpdateDocumentSecurityInfo( 287 nsITransportSecurityInfo* aSecurityInfo); 288 mozilla::ipc::IPCResult RecvSetClientInfo( 289 const IPCClientInfo& aIPCClientInfo); 290 mozilla::ipc::IPCResult RecvDestroy(); 291 mozilla::ipc::IPCResult RecvRawMessage( 292 const JSActorMessageMeta& aMeta, JSIPCValue&& aData, 293 const UniquePtr<ClonedMessageData>& aStack); 294 295 mozilla::ipc::IPCResult RecvGetContentBlockingEvents( 296 GetContentBlockingEventsResolver&& aResolver); 297 mozilla::ipc::IPCResult RecvUpdateCookieJarSettings( 298 const CookieJarSettingsArgs& aCookieJarSettingsArgs); 299 300 void ActorDestroy(ActorDestroyReason aWhy) override; 301 302 void DrawSnapshotInternal(gfx::CrossProcessPaint* aPaint, 303 const Maybe<IntRect>& aRect, float aScale, 304 nscolor aBackgroundColor, uint32_t aFlags); 305 306 // WebShare API - try to share 307 mozilla::ipc::IPCResult RecvShare(IPCWebShareData&& aData, 308 ShareResolver&& aResolver); 309 310 mozilla::ipc::IPCResult RecvCheckPermitUnload( 311 bool aHasInProcessBlocker, XPCOMPermitUnloadAction aAction, 312 CheckPermitUnloadResolver&& aResolver); 313 314 mozilla::ipc::IPCResult RecvExpectPageUseCounters( 315 const MaybeDiscarded<dom::WindowContext>& aTop); 316 mozilla::ipc::IPCResult RecvAccumulatePageUseCounters( 317 const UseCounters& aUseCounters); 318 319 mozilla::ipc::IPCResult RecvRequestRestoreTabContent(); 320 321 mozilla::ipc::IPCResult RecvUpdateBFCacheStatus(const uint32_t& aOnFlags, 322 const uint32_t& aOffFlags); 323 324 // This IPC method is to notify the parent process that the caller process 325 // creates the first active peer connection (aIsAdded = true) or closes the 326 // last active peer connection (aIsAdded = false). 327 mozilla::ipc::IPCResult RecvUpdateActivePeerConnectionStatus(bool aIsAdded); 328 329 public: 330 mozilla::ipc::IPCResult RecvSetSingleChannelId( 331 const Maybe<uint64_t>& aSingleChannelId); 332 333 mozilla::ipc::IPCResult RecvSetDocumentDomain(NotNull<nsIURI*> aDomain); 334 335 mozilla::ipc::IPCResult RecvReloadWithHttpsOnlyException(); 336 337 mozilla::ipc::IPCResult RecvGetStorageAccessPermission( 338 bool aIncludeIdentityCredential, 339 GetStorageAccessPermissionResolver&& aResolve); 340 341 mozilla::ipc::IPCResult RecvSetCookies( 342 const nsCString& aBaseDomain, const OriginAttributes& aOriginAttributes, 343 nsIURI* aHost, bool aFromHttp, bool aIsThirdParty, 344 const nsTArray<CookieStruct>& aCookies); 345 346 mozilla::ipc::IPCResult RecvOnInitialStorageAccess(); 347 348 mozilla::ipc::IPCResult RecvRecordUserActivationForBTP(); 349 350 already_AddRefed<dom::PWebAuthnTransactionParent> 351 AllocPWebAuthnTransactionParent(); 352 353 already_AddRefed<dom::PWebIdentityParent> AllocPWebIdentityParent(); 354 355 private: 356 WindowGlobalParent(CanonicalBrowsingContext* aBrowsingContext, 357 uint64_t aInnerWindowId, uint64_t aOuterWindowId, 358 FieldValues&& aInit); 359 360 ~WindowGlobalParent(); 361 362 bool ShouldTrackSiteOriginTelemetry(); 363 enum class PageUseCounterResultBits : uint8_t { 364 WAITING, 365 DATA_RECEIVED, 366 EMPTY_DATA, 367 }; 368 using PageUseCounterResult = EnumSet<PageUseCounterResultBits>; 369 PageUseCounterResult FinishAccumulatingPageUseCounters(); 370 371 // Returns failure if the new storage principal cannot be validated 372 // against the current document principle. 373 nsresult SetDocumentStoragePrincipal( 374 nsIPrincipal* aNewDocumentStoragePrincipal); 375 376 // NOTE: Neither this document principal nor the document storage 377 // principal doesn't reflect possible |document.domain| mutations 378 // which may have been made in the actual document. 379 nsCOMPtr<nsIPrincipal> mDocumentPrincipal; 380 nsCOMPtr<nsIPrincipal> mDocumentStoragePrincipal; 381 382 // The principal to use for the content blocking allow list. 383 nsCOMPtr<nsIPrincipal> mDocContentBlockingAllowListPrincipal; 384 385 nsCOMPtr<nsIURI> mDocumentURI; 386 Maybe<nsString> mDocumentTitle; 387 388 Maybe<bool> mIsInitialDocument; 389 390 bool mIsUncommittedInitialDocument; 391 392 // True if this window has a "beforeunload" event listener. 393 bool mHasBeforeUnload; 394 395 // The log of all content blocking actions taken on the document related to 396 // this WindowGlobalParent. This is only stored on top-level documents and 397 // includes the activity log for all of the nested subdocuments as well. 398 ContentBlockingLog mContentBlockingLog; 399 400 uint32_t mSecurityState = 0; 401 402 Maybe<ClientInfo> mClientInfo; 403 // Fields being mirrored from the corresponding document 404 nsCOMPtr<nsICookieJarSettings> mCookieJarSettings; 405 nsCOMPtr<nsITransportSecurityInfo> mSecurityInfo; 406 407 uint32_t mSandboxFlags; 408 409 struct OriginCounter { 410 void UpdateSiteOriginsFrom(WindowGlobalParent* aParent, bool aIncrease); 411 void Accumulate(); 412 413 nsTHashMap<nsCStringHashKey, int32_t> mOriginMap; 414 uint32_t mMaxOrigins = 0; 415 }; 416 417 // Used to collect unique site origin telemetry. 418 // 419 // Is only Some() on top-level content windows. 420 Maybe<OriginCounter> mOriginCounter; 421 422 bool mDocumentHasLoaded; 423 bool mDocumentHasUserInteracted; 424 bool mDocumentTreeWouldPreloadResources = false; 425 bool mBlockAllMixedContent; 426 bool mUpgradeInsecureRequests; 427 428 // HTTPS-Only Mode flags 429 uint32_t mHttpsOnlyStatus; 430 431 // The window of the document whose page use counters our document's use 432 // counters will contribute to. (If we are a top-level document, this 433 // will point to ourselves.) 434 RefPtr<WindowGlobalParent> mPageUseCountersWindow; 435 436 // Our page use counters, if we are a top-level document. 437 UniquePtr<PageUseCounters> mPageUseCounters; 438 439 // Whether we have sent our page use counters, and so should ignore any 440 // subsequent ExpectPageUseCounters calls. 441 bool mSentPageUseCounters = false; 442 443 uint32_t mBFCacheStatus = 0; 444 445 // If this WindowGlobalParent is a top window, this field indicates how many 446 // child processes have active peer connections for this window and its 447 // descendants. 448 uint32_t mNumOfProcessesWithActivePeerConnections = 0; 449 450 // mSingleChannelId records whether the loadgroup contains a single request 451 // with an id. If there is one channel in the loadgroup and it has an id then 452 // mSingleChannelId is set to Some(id) (ids are non-zero). If there is one 453 // request in the loadgroup and it's not a channel or it doesn't have an id, 454 // or there are multiple requests in the loadgroup, then mSingleChannelId is 455 // set to Some(0). If there are no requests in the loadgroup then 456 // mSingleChannelId is set to Nothing(). 457 // Note: We ignore favicon loads when considering the requests in the 458 // loadgroup. 459 Maybe<uint64_t> mSingleChannelId; 460 461 // True if the current loaded document is in fullscreen. 462 bool mFullscreen = false; 463 464 bool mShouldReportHasBlockedOpaqueResponse = false; 465 }; 466 467 } // namespace dom 468 } // namespace mozilla 469 470 inline nsISupports* ToSupports( 471 mozilla::dom::WindowGlobalParent* aWindowGlobal) { 472 return static_cast<mozilla::dom::WindowContext*>(aWindowGlobal); 473 } 474 475 #endif // !defined(mozilla_dom_WindowGlobalParent_h)