no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / docshell / base / WindowContext.cpp
blobd2032bc55170e73c8f4c4c0a4f261e86f8128e98
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 #include "mozilla/dom/WindowContext.h"
8 #include "mozilla/dom/WindowGlobalActorsBinding.h"
9 #include "mozilla/dom/WindowGlobalChild.h"
10 #include "mozilla/dom/WindowGlobalParent.h"
11 #include "mozilla/dom/SyncedContextInlines.h"
12 #include "mozilla/dom/BrowsingContext.h"
13 #include "mozilla/dom/Document.h"
14 #include "mozilla/dom/UserActivationIPCUtils.h"
15 #include "mozilla/PermissionDelegateIPCUtils.h"
16 #include "mozilla/RFPTargetIPCUtils.h"
17 #include "mozilla/StaticPrefs_dom.h"
18 #include "mozilla/StaticPtr.h"
19 #include "mozilla/ClearOnShutdown.h"
20 #include "nsGlobalWindowInner.h"
21 #include "nsIScriptError.h"
22 #include "nsIWebProgressListener.h"
23 #include "nsIXULRuntime.h"
24 #include "nsRefPtrHashtable.h"
25 #include "nsContentUtils.h"
27 namespace mozilla {
28 namespace dom {
30 // Explicit specialization of the `Transaction` type. Required by the `extern
31 // template class` declaration in the header.
32 template class syncedcontext::Transaction<WindowContext>;
34 static LazyLogModule gWindowContextLog("WindowContext");
35 static LazyLogModule gWindowContextSyncLog("WindowContextSync");
37 extern mozilla::LazyLogModule gUserInteractionPRLog;
39 #define USER_ACTIVATION_LOG(msg, ...) \
40 MOZ_LOG(gUserInteractionPRLog, LogLevel::Debug, (msg, ##__VA_ARGS__))
42 using WindowContextByIdMap = nsTHashMap<nsUint64HashKey, WindowContext*>;
43 static StaticAutoPtr<WindowContextByIdMap> gWindowContexts;
45 /* static */
46 LogModule* WindowContext::GetLog() { return gWindowContextLog; }
48 /* static */
49 LogModule* WindowContext::GetSyncLog() { return gWindowContextSyncLog; }
51 /* static */
52 already_AddRefed<WindowContext> WindowContext::GetById(
53 uint64_t aInnerWindowId) {
54 if (!gWindowContexts) {
55 return nullptr;
57 return do_AddRef(gWindowContexts->Get(aInnerWindowId));
60 BrowsingContextGroup* WindowContext::Group() const {
61 return mBrowsingContext->Group();
64 WindowGlobalParent* WindowContext::Canonical() {
65 MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
66 return static_cast<WindowGlobalParent*>(this);
69 bool WindowContext::IsCurrent() const {
70 return mBrowsingContext->mCurrentWindowContext == this;
73 bool WindowContext::IsInBFCache() {
74 if (mozilla::SessionHistoryInParent()) {
75 return mBrowsingContext->IsInBFCache();
77 return TopWindowContext()->GetWindowStateSaved();
80 nsGlobalWindowInner* WindowContext::GetInnerWindow() const {
81 return mWindowGlobalChild ? mWindowGlobalChild->GetWindowGlobal() : nullptr;
84 Document* WindowContext::GetDocument() const {
85 nsGlobalWindowInner* innerWindow = GetInnerWindow();
86 return innerWindow ? innerWindow->GetDocument() : nullptr;
89 Document* WindowContext::GetExtantDoc() const {
90 nsGlobalWindowInner* innerWindow = GetInnerWindow();
91 return innerWindow ? innerWindow->GetExtantDoc() : nullptr;
94 WindowGlobalChild* WindowContext::GetWindowGlobalChild() const {
95 return mWindowGlobalChild;
98 WindowContext* WindowContext::GetParentWindowContext() {
99 return mBrowsingContext->GetParentWindowContext();
102 WindowContext* WindowContext::TopWindowContext() {
103 WindowContext* current = this;
104 while (current->GetParentWindowContext()) {
105 current = current->GetParentWindowContext();
107 return current;
110 bool WindowContext::IsTop() const { return mBrowsingContext->IsTop(); }
112 bool WindowContext::SameOriginWithTop() const {
113 return mBrowsingContext->SameOriginWithTop();
116 nsIGlobalObject* WindowContext::GetParentObject() const {
117 return xpc::NativeGlobal(xpc::PrivilegedJunkScope());
120 void WindowContext::AppendChildBrowsingContext(
121 BrowsingContext* aBrowsingContext) {
122 MOZ_DIAGNOSTIC_ASSERT(Group() == aBrowsingContext->Group(),
123 "Mismatched groups?");
124 MOZ_DIAGNOSTIC_ASSERT(!mChildren.Contains(aBrowsingContext));
126 mChildren.AppendElement(aBrowsingContext);
127 if (!aBrowsingContext->IsEmbedderTypeObjectOrEmbed()) {
128 mNonSyntheticChildren.AppendElement(aBrowsingContext);
131 // If we're the current WindowContext in our BrowsingContext, make sure to
132 // clear any cached `children` value.
133 if (IsCurrent()) {
134 BrowsingContext_Binding::ClearCachedChildrenValue(mBrowsingContext);
138 void WindowContext::RemoveChildBrowsingContext(
139 BrowsingContext* aBrowsingContext) {
140 MOZ_DIAGNOSTIC_ASSERT(Group() == aBrowsingContext->Group(),
141 "Mismatched groups?");
143 mChildren.RemoveElement(aBrowsingContext);
144 mNonSyntheticChildren.RemoveElement(aBrowsingContext);
146 // If we're the current WindowContext in our BrowsingContext, make sure to
147 // clear any cached `children` value.
148 if (IsCurrent()) {
149 BrowsingContext_Binding::ClearCachedChildrenValue(mBrowsingContext);
153 void WindowContext::UpdateChildSynthetic(BrowsingContext* aBrowsingContext,
154 bool aIsSynthetic) {
155 if (aIsSynthetic) {
156 mNonSyntheticChildren.RemoveElement(aBrowsingContext);
157 } else {
158 // The same BrowsingContext will be reused for error pages, so it can be in
159 // the list already.
160 if (!mNonSyntheticChildren.Contains(aBrowsingContext)) {
161 mNonSyntheticChildren.AppendElement(aBrowsingContext);
166 void WindowContext::SendCommitTransaction(ContentParent* aParent,
167 const BaseTransaction& aTxn,
168 uint64_t aEpoch) {
169 Unused << aParent->SendCommitWindowContextTransaction(this, aTxn, aEpoch);
172 void WindowContext::SendCommitTransaction(ContentChild* aChild,
173 const BaseTransaction& aTxn,
174 uint64_t aEpoch) {
175 aChild->SendCommitWindowContextTransaction(this, aTxn, aEpoch);
178 bool WindowContext::CheckOnlyOwningProcessCanSet(ContentParent* aSource) {
179 if (IsInProcess()) {
180 return true;
183 if (XRE_IsParentProcess() && aSource) {
184 return Canonical()->GetContentParent() == aSource;
187 return false;
190 bool WindowContext::CanSet(FieldIndex<IDX_IsSecure>, const bool& aIsSecure,
191 ContentParent* aSource) {
192 return CheckOnlyOwningProcessCanSet(aSource);
195 bool WindowContext::CanSet(FieldIndex<IDX_AllowMixedContent>,
196 const bool& aAllowMixedContent,
197 ContentParent* aSource) {
198 return CheckOnlyOwningProcessCanSet(aSource);
201 bool WindowContext::CanSet(FieldIndex<IDX_HasBeforeUnload>,
202 const bool& aHasBeforeUnload,
203 ContentParent* aSource) {
204 return CheckOnlyOwningProcessCanSet(aSource);
207 bool WindowContext::CanSet(FieldIndex<IDX_CookieBehavior>,
208 const Maybe<uint32_t>& aValue,
209 ContentParent* aSource) {
210 return CheckOnlyOwningProcessCanSet(aSource);
213 bool WindowContext::CanSet(FieldIndex<IDX_IsOnContentBlockingAllowList>,
214 const bool& aValue, ContentParent* aSource) {
215 return CheckOnlyOwningProcessCanSet(aSource);
218 bool WindowContext::CanSet(FieldIndex<IDX_IsThirdPartyWindow>,
219 const bool& IsThirdPartyWindow,
220 ContentParent* aSource) {
221 return CheckOnlyOwningProcessCanSet(aSource);
224 bool WindowContext::CanSet(FieldIndex<IDX_IsThirdPartyTrackingResourceWindow>,
225 const bool& aIsThirdPartyTrackingResourceWindow,
226 ContentParent* aSource) {
227 return CheckOnlyOwningProcessCanSet(aSource);
230 bool WindowContext::CanSet(FieldIndex<IDX_UsingStorageAccess>,
231 const bool& aUsingStorageAccess,
232 ContentParent* aSource) {
233 return CheckOnlyOwningProcessCanSet(aSource);
236 bool WindowContext::CanSet(FieldIndex<IDX_ShouldResistFingerprinting>,
237 const bool& aShouldResistFingerprinting,
238 ContentParent* aSource) {
239 return CheckOnlyOwningProcessCanSet(aSource);
242 bool WindowContext::CanSet(FieldIndex<IDX_OverriddenFingerprintingSettings>,
243 const Maybe<RFPTarget>& aValue,
244 ContentParent* aSource) {
245 return CheckOnlyOwningProcessCanSet(aSource);
248 bool WindowContext::CanSet(FieldIndex<IDX_IsSecureContext>,
249 const bool& aIsSecureContext,
250 ContentParent* aSource) {
251 return CheckOnlyOwningProcessCanSet(aSource);
254 bool WindowContext::CanSet(FieldIndex<IDX_IsOriginalFrameSource>,
255 const bool& aIsOriginalFrameSource,
256 ContentParent* aSource) {
257 return CheckOnlyOwningProcessCanSet(aSource);
260 bool WindowContext::CanSet(FieldIndex<IDX_DocTreeHadMedia>, const bool& aValue,
261 ContentParent* aSource) {
262 return IsTop();
265 bool WindowContext::CanSet(FieldIndex<IDX_AutoplayPermission>,
266 const uint32_t& aValue, ContentParent* aSource) {
267 return CheckOnlyOwningProcessCanSet(aSource);
270 bool WindowContext::CanSet(FieldIndex<IDX_ShortcutsPermission>,
271 const uint32_t& aValue, ContentParent* aSource) {
272 return IsTop() && CheckOnlyOwningProcessCanSet(aSource);
275 bool WindowContext::CanSet(FieldIndex<IDX_ActiveMediaSessionContextId>,
276 const Maybe<uint64_t>& aValue,
277 ContentParent* aSource) {
278 return IsTop();
281 bool WindowContext::CanSet(FieldIndex<IDX_PopupPermission>, const uint32_t&,
282 ContentParent* aSource) {
283 return CheckOnlyOwningProcessCanSet(aSource);
286 bool WindowContext::CanSet(
287 FieldIndex<IDX_DelegatedPermissions>,
288 const PermissionDelegateHandler::DelegatedPermissionList& aValue,
289 ContentParent* aSource) {
290 return CheckOnlyOwningProcessCanSet(aSource);
293 bool WindowContext::CanSet(
294 FieldIndex<IDX_DelegatedExactHostMatchPermissions>,
295 const PermissionDelegateHandler::DelegatedPermissionList& aValue,
296 ContentParent* aSource) {
297 return CheckOnlyOwningProcessCanSet(aSource);
300 bool WindowContext::CanSet(FieldIndex<IDX_IsLocalIP>, const bool& aValue,
301 ContentParent* aSource) {
302 return CheckOnlyOwningProcessCanSet(aSource);
305 bool WindowContext::CanSet(FieldIndex<IDX_AllowJavascript>, bool aValue,
306 ContentParent* aSource) {
307 return (XRE_IsParentProcess() && !aSource) ||
308 CheckOnlyOwningProcessCanSet(aSource);
311 void WindowContext::DidSet(FieldIndex<IDX_AllowJavascript>, bool aOldValue) {
312 RecomputeCanExecuteScripts();
315 bool WindowContext::CanSet(FieldIndex<IDX_HasActivePeerConnections>, bool,
316 ContentParent*) {
317 return XRE_IsParentProcess() && IsTop();
320 void WindowContext::RecomputeCanExecuteScripts(bool aApplyChanges) {
321 const bool old = mCanExecuteScripts;
322 if (!AllowJavascript()) {
323 // Scripting has been explicitly disabled on our WindowContext.
324 mCanExecuteScripts = false;
325 } else {
326 // Otherwise, inherit.
327 mCanExecuteScripts = mBrowsingContext->CanExecuteScripts();
330 if (aApplyChanges && old != mCanExecuteScripts) {
331 // Inform our active DOM window.
332 if (nsGlobalWindowInner* window = GetInnerWindow()) {
333 // Only update scriptability if the window is current. Windows will have
334 // scriptability disabled when entering the bfcache and updated when
335 // coming out.
336 if (window->IsCurrentInnerWindow()) {
337 auto& scriptability =
338 xpc::Scriptability::Get(window->GetGlobalJSObject());
339 scriptability.SetWindowAllowsScript(mCanExecuteScripts);
343 for (const RefPtr<BrowsingContext>& child : Children()) {
344 child->RecomputeCanExecuteScripts();
349 void WindowContext::DidSet(FieldIndex<IDX_SHEntryHasUserInteraction>,
350 bool aOldValue) {
351 MOZ_ASSERT(
352 TopWindowContext() == this,
353 "SHEntryHasUserInteraction can only be set on the top window context");
354 // This field is set when the child notifies us of new user interaction, so we
355 // also set the currently active shentry in the parent as having interaction.
356 if (XRE_IsParentProcess() && mBrowsingContext) {
357 SessionHistoryEntry* activeEntry =
358 mBrowsingContext->Canonical()->GetActiveSessionHistoryEntry();
359 if (activeEntry && GetSHEntryHasUserInteraction()) {
360 activeEntry->SetHasUserInteraction(true);
365 void WindowContext::DidSet(FieldIndex<IDX_UserActivationStateAndModifiers>) {
366 MOZ_ASSERT_IF(!IsInProcess(), mUserGestureStart.IsNull());
367 USER_ACTIVATION_LOG("Set user gesture activation 0x%02" PRIu8
368 " for %s browsing context 0x%08" PRIx64,
369 GetUserActivationStateAndModifiers(),
370 XRE_IsParentProcess() ? "Parent" : "Child", Id());
371 if (IsInProcess()) {
372 USER_ACTIVATION_LOG(
373 "Set user gesture start time for %s browsing context 0x%08" PRIx64,
374 XRE_IsParentProcess() ? "Parent" : "Child", Id());
375 if (GetUserActivationState() == UserActivation::State::FullActivated) {
376 mUserGestureStart = TimeStamp::Now();
377 } else if (GetUserActivationState() == UserActivation::State::None) {
378 mUserGestureStart = TimeStamp();
383 void WindowContext::DidSet(FieldIndex<IDX_HasReportedShadowDOMUsage>,
384 bool aOldValue) {
385 if (!aOldValue && GetHasReportedShadowDOMUsage() && IsInProcess()) {
386 MOZ_ASSERT(TopWindowContext() == this);
387 if (mBrowsingContext) {
388 Document* topLevelDoc = mBrowsingContext->GetDocument();
389 if (topLevelDoc) {
390 nsAutoString uri;
391 Unused << topLevelDoc->GetDocumentURI(uri);
392 if (!uri.IsEmpty()) {
393 nsAutoString msg = u"Shadow DOM used in ["_ns + uri +
394 u"] or in some of its subdocuments."_ns;
395 nsContentUtils::ReportToConsoleNonLocalized(
396 msg, nsIScriptError::infoFlag, "DOM"_ns, topLevelDoc);
403 bool WindowContext::CanSet(FieldIndex<IDX_WindowStateSaved>, bool aValue,
404 ContentParent* aSource) {
405 return !mozilla::SessionHistoryInParent() && IsTop() &&
406 CheckOnlyOwningProcessCanSet(aSource);
409 void WindowContext::CreateFromIPC(IPCInitializer&& aInit) {
410 MOZ_RELEASE_ASSERT(XRE_IsContentProcess(),
411 "Should be a WindowGlobalParent in the parent");
413 RefPtr<BrowsingContext> bc = BrowsingContext::Get(aInit.mBrowsingContextId);
414 MOZ_RELEASE_ASSERT(bc);
416 if (bc->IsDiscarded()) {
417 // If we have already closed our browsing context, the
418 // WindowGlobalChild actor is bound to be destroyed soon and it's
419 // safe to ignore creating the WindowContext.
420 return;
423 RefPtr<WindowContext> context = new WindowContext(
424 bc, aInit.mInnerWindowId, aInit.mOuterWindowId, std::move(aInit.mFields));
425 context->Init();
428 void WindowContext::Init() {
429 MOZ_LOG(GetLog(), LogLevel::Debug,
430 ("Registering 0x%" PRIx64 " (bc=0x%" PRIx64 ")", mInnerWindowId,
431 mBrowsingContext->Id()));
433 // Register the WindowContext in the `WindowContextByIdMap`.
434 if (!gWindowContexts) {
435 gWindowContexts = new WindowContextByIdMap();
436 ClearOnShutdown(&gWindowContexts);
438 auto& entry = gWindowContexts->LookupOrInsert(mInnerWindowId);
439 MOZ_RELEASE_ASSERT(!entry, "Duplicate WindowContext for ID!");
440 entry = this;
442 // Register this to the browsing context.
443 mBrowsingContext->RegisterWindowContext(this);
444 Group()->Register(this);
447 void WindowContext::Discard() {
448 MOZ_LOG(GetLog(), LogLevel::Debug,
449 ("Discarding 0x%" PRIx64 " (bc=0x%" PRIx64 ")", mInnerWindowId,
450 mBrowsingContext->Id()));
451 if (mIsDiscarded) {
452 return;
455 mIsDiscarded = true;
456 if (gWindowContexts) {
457 gWindowContexts->Remove(InnerWindowId());
459 mBrowsingContext->UnregisterWindowContext(this);
460 Group()->Unregister(this);
463 void WindowContext::AddSecurityState(uint32_t aStateFlags) {
464 MOZ_ASSERT(TopWindowContext() == this);
465 MOZ_ASSERT((aStateFlags &
466 (nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT |
467 nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT |
468 nsIWebProgressListener::STATE_BLOCKED_MIXED_DISPLAY_CONTENT |
469 nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT |
470 nsIWebProgressListener::STATE_HTTPS_ONLY_MODE_UPGRADED |
471 nsIWebProgressListener::STATE_HTTPS_ONLY_MODE_UPGRADE_FAILED |
472 nsIWebProgressListener::STATE_HTTPS_ONLY_MODE_UPGRADED_FIRST)) ==
473 aStateFlags,
474 "Invalid flags specified!");
476 if (XRE_IsParentProcess()) {
477 Canonical()->AddSecurityState(aStateFlags);
478 } else {
479 ContentChild* child = ContentChild::GetSingleton();
480 child->SendAddSecurityState(this, aStateFlags);
484 void WindowContext::NotifyUserGestureActivation(
485 UserActivation::Modifiers
486 aModifiers /* = UserActivation::Modifiers::None() */) {
487 UserActivation::StateAndModifiers stateAndModifiers;
488 stateAndModifiers.SetState(UserActivation::State::FullActivated);
489 stateAndModifiers.SetModifiers(aModifiers);
490 Unused << SetUserActivationStateAndModifiers(stateAndModifiers.GetRawData());
493 void WindowContext::NotifyResetUserGestureActivation() {
494 UserActivation::StateAndModifiers stateAndModifiers;
495 stateAndModifiers.SetState(UserActivation::State::None);
496 Unused << SetUserActivationStateAndModifiers(stateAndModifiers.GetRawData());
499 bool WindowContext::HasBeenUserGestureActivated() {
500 return GetUserActivationState() != UserActivation::State::None;
503 const TimeStamp& WindowContext::GetUserGestureStart() const {
504 MOZ_ASSERT(IsInProcess());
505 return mUserGestureStart;
508 bool WindowContext::HasValidTransientUserGestureActivation() {
509 MOZ_ASSERT(IsInProcess());
511 if (GetUserActivationState() != UserActivation::State::FullActivated) {
512 // mUserGestureStart should be null if the document hasn't ever been
513 // activated by user gesture
514 MOZ_ASSERT_IF(GetUserActivationState() == UserActivation::State::None,
515 mUserGestureStart.IsNull());
516 return false;
519 MOZ_ASSERT(!mUserGestureStart.IsNull(),
520 "mUserGestureStart shouldn't be null if the document has ever "
521 "been activated by user gesture");
522 TimeDuration timeout = TimeDuration::FromMilliseconds(
523 StaticPrefs::dom_user_activation_transient_timeout());
525 return timeout <= TimeDuration() ||
526 (TimeStamp::Now() - mUserGestureStart) <= timeout;
529 bool WindowContext::ConsumeTransientUserGestureActivation() {
530 MOZ_ASSERT(IsInProcess());
531 MOZ_ASSERT(IsCurrent());
533 if (!HasValidTransientUserGestureActivation()) {
534 return false;
537 BrowsingContext* top = mBrowsingContext->Top();
538 top->PreOrderWalk([&](BrowsingContext* aBrowsingContext) {
539 WindowContext* windowContext = aBrowsingContext->GetCurrentWindowContext();
540 if (windowContext && windowContext->GetUserActivationState() ==
541 UserActivation::State::FullActivated) {
542 auto stateAndModifiers = UserActivation::StateAndModifiers(
543 GetUserActivationStateAndModifiers());
544 stateAndModifiers.SetState(UserActivation::State::HasBeenActivated);
545 Unused << windowContext->SetUserActivationStateAndModifiers(
546 stateAndModifiers.GetRawData());
550 return true;
553 bool WindowContext::GetTransientUserGestureActivationModifiers(
554 UserActivation::Modifiers* aModifiers) {
555 if (!HasValidTransientUserGestureActivation()) {
556 return false;
559 auto stateAndModifiers =
560 UserActivation::StateAndModifiers(GetUserActivationStateAndModifiers());
561 *aModifiers = stateAndModifiers.GetModifiers();
562 return true;
565 bool WindowContext::CanShowPopup() {
566 uint32_t permit = GetPopupPermission();
567 if (permit == nsIPermissionManager::ALLOW_ACTION) {
568 return true;
570 if (permit == nsIPermissionManager::DENY_ACTION) {
571 return false;
574 return !StaticPrefs::dom_disable_open_during_load();
577 void WindowContext::TransientSetHasActivePeerConnections() {
578 if (!IsTop()) {
579 return;
582 mFields.SetWithoutSyncing<IDX_HasActivePeerConnections>(true);
585 WindowContext::IPCInitializer WindowContext::GetIPCInitializer() {
586 IPCInitializer init;
587 init.mInnerWindowId = mInnerWindowId;
588 init.mOuterWindowId = mOuterWindowId;
589 init.mBrowsingContextId = mBrowsingContext->Id();
590 init.mFields = mFields.RawValues();
591 return init;
594 WindowContext::WindowContext(BrowsingContext* aBrowsingContext,
595 uint64_t aInnerWindowId, uint64_t aOuterWindowId,
596 FieldValues&& aInit)
597 : mFields(std::move(aInit)),
598 mInnerWindowId(aInnerWindowId),
599 mOuterWindowId(aOuterWindowId),
600 mBrowsingContext(aBrowsingContext) {
601 MOZ_ASSERT(mBrowsingContext);
602 MOZ_ASSERT(mInnerWindowId);
603 MOZ_ASSERT(mOuterWindowId);
604 RecomputeCanExecuteScripts(/* aApplyChanges */ false);
607 WindowContext::~WindowContext() {
608 if (gWindowContexts) {
609 gWindowContexts->Remove(InnerWindowId());
613 JSObject* WindowContext::WrapObject(JSContext* cx,
614 JS::Handle<JSObject*> aGivenProto) {
615 return WindowContext_Binding::Wrap(cx, this, aGivenProto);
618 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WindowContext)
619 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
620 NS_INTERFACE_MAP_ENTRY(nsISupports)
621 NS_INTERFACE_MAP_END
623 NS_IMPL_CYCLE_COLLECTING_ADDREF(WindowContext)
624 NS_IMPL_CYCLE_COLLECTING_RELEASE(WindowContext)
626 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(WindowContext)
628 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WindowContext)
629 if (gWindowContexts) {
630 gWindowContexts->Remove(tmp->InnerWindowId());
633 NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowsingContext)
634 NS_IMPL_CYCLE_COLLECTION_UNLINK(mChildren)
635 NS_IMPL_CYCLE_COLLECTION_UNLINK(mNonSyntheticChildren)
636 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
637 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
639 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WindowContext)
640 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowsingContext)
641 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildren)
642 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNonSyntheticChildren)
643 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
645 } // namespace dom
647 namespace ipc {
649 void IPDLParamTraits<dom::MaybeDiscarded<dom::WindowContext>>::Write(
650 IPC::MessageWriter* aWriter, IProtocol* aActor,
651 const dom::MaybeDiscarded<dom::WindowContext>& aParam) {
652 uint64_t id = aParam.ContextId();
653 WriteIPDLParam(aWriter, aActor, id);
656 bool IPDLParamTraits<dom::MaybeDiscarded<dom::WindowContext>>::Read(
657 IPC::MessageReader* aReader, IProtocol* aActor,
658 dom::MaybeDiscarded<dom::WindowContext>* aResult) {
659 uint64_t id = 0;
660 if (!ReadIPDLParam(aReader, aActor, &id)) {
661 return false;
664 if (id == 0) {
665 *aResult = nullptr;
666 } else if (RefPtr<dom::WindowContext> wc = dom::WindowContext::GetById(id)) {
667 *aResult = std::move(wc);
668 } else {
669 aResult->SetDiscarded(id);
671 return true;
674 void IPDLParamTraits<dom::WindowContext::IPCInitializer>::Write(
675 IPC::MessageWriter* aWriter, IProtocol* aActor,
676 const dom::WindowContext::IPCInitializer& aInit) {
677 // Write actor ID parameters.
678 WriteIPDLParam(aWriter, aActor, aInit.mInnerWindowId);
679 WriteIPDLParam(aWriter, aActor, aInit.mOuterWindowId);
680 WriteIPDLParam(aWriter, aActor, aInit.mBrowsingContextId);
681 WriteIPDLParam(aWriter, aActor, aInit.mFields);
684 bool IPDLParamTraits<dom::WindowContext::IPCInitializer>::Read(
685 IPC::MessageReader* aReader, IProtocol* aActor,
686 dom::WindowContext::IPCInitializer* aInit) {
687 // Read actor ID parameters.
688 return ReadIPDLParam(aReader, aActor, &aInit->mInnerWindowId) &&
689 ReadIPDLParam(aReader, aActor, &aInit->mOuterWindowId) &&
690 ReadIPDLParam(aReader, aActor, &aInit->mBrowsingContextId) &&
691 ReadIPDLParam(aReader, aActor, &aInit->mFields);
694 template struct IPDLParamTraits<dom::WindowContext::BaseTransaction>;
696 } // namespace ipc
697 } // namespace mozilla