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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "ContentProcessManager.h"
8 #include "ContentParent.h"
9 #include "mozilla/AppShutdown.h"
10 #include "mozilla/dom/BrowserParent.h"
11 #include "mozilla/dom/BrowsingContextGroup.h"
12 #include "mozilla/dom/CanonicalBrowsingContext.h"
14 #include "mozilla/StaticPtr.h"
15 #include "mozilla/ClearOnShutdown.h"
17 #include "nsPrintfCString.h"
19 namespace mozilla::dom
{
22 StaticAutoPtr
<ContentProcessManager
> ContentProcessManager::sSingleton
;
25 ContentProcessManager
* ContentProcessManager::GetSingleton() {
26 MOZ_ASSERT(XRE_IsParentProcess());
29 !AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMShutdownFinal
)) {
30 sSingleton
= new ContentProcessManager();
31 ClearOnShutdown(&sSingleton
);
36 void ContentProcessManager::AddContentProcess(ContentParent
* aChildCp
) {
37 MOZ_ASSERT(NS_IsMainThread());
40 mContentParentMap
.WithEntryHandle(aChildCp
->ChildID(), [&](auto&& entry
) {
41 MOZ_ASSERT_IF(entry
, entry
.Data() == aChildCp
);
42 entry
.OrInsert(aChildCp
);
46 void ContentProcessManager::RemoveContentProcess(
47 const ContentParentId
& aChildCpId
) {
48 MOZ_ASSERT(NS_IsMainThread());
50 MOZ_ALWAYS_TRUE(mContentParentMap
.Remove(aChildCpId
));
53 ContentParent
* ContentProcessManager::GetContentProcessById(
54 const ContentParentId
& aChildCpId
) {
55 MOZ_ASSERT(NS_IsMainThread());
57 ContentParent
* contentParent
= mContentParentMap
.Get(aChildCpId
);
58 if (NS_WARN_IF(!contentParent
)) {
64 bool ContentProcessManager::RegisterRemoteFrame(BrowserParent
* aChildBp
) {
65 MOZ_ASSERT(NS_IsMainThread());
68 return mBrowserParentMap
.WithEntryHandle(
69 aChildBp
->GetTabId(), [&](auto&& entry
) {
71 MOZ_ASSERT(entry
.Data() == aChildBp
);
75 // Ensure that this BrowserParent's BrowsingContextGroup is kept alive
76 // until the BrowserParent has been unregistered, ensuring the group
77 // isn't destroyed while this BrowserParent can still send messages.
78 aChildBp
->GetBrowsingContext()->Group()->AddKeepAlive();
79 entry
.Insert(aChildBp
);
84 void ContentProcessManager::UnregisterRemoteFrame(const TabId
& aChildTabId
) {
85 MOZ_ASSERT(NS_IsMainThread());
87 auto childBp
= mBrowserParentMap
.Extract(aChildTabId
);
88 MOZ_DIAGNOSTIC_ASSERT(childBp
);
90 // Clear the corresponding keepalive which was added in `RegisterRemoteFrame`.
91 (*childBp
)->GetBrowsingContext()->Group()->RemoveKeepAlive();
94 ContentParentId
ContentProcessManager::GetTabProcessId(
95 const TabId
& aChildTabId
) {
96 MOZ_ASSERT(NS_IsMainThread());
98 if (BrowserParent
* browserParent
= mBrowserParentMap
.Get(aChildTabId
)) {
99 return browserParent
->Manager()->ChildID();
101 return ContentParentId(0);
104 uint32_t ContentProcessManager::GetBrowserParentCountByProcessId(
105 const ContentParentId
& aChildCpId
) {
106 MOZ_ASSERT(NS_IsMainThread());
108 ContentParent
* contentParent
= mContentParentMap
.Get(aChildCpId
);
109 if (NS_WARN_IF(!contentParent
)) {
112 return contentParent
->ManagedPBrowserParent().Count();
115 already_AddRefed
<BrowserParent
>
116 ContentProcessManager::GetBrowserParentByProcessAndTabId(
117 const ContentParentId
& aChildCpId
, const TabId
& aChildTabId
) {
118 RefPtr
<BrowserParent
> browserParent
= mBrowserParentMap
.Get(aChildTabId
);
119 if (NS_WARN_IF(!browserParent
)) {
123 if (NS_WARN_IF(browserParent
->Manager()->ChildID() != aChildCpId
)) {
127 return browserParent
.forget();
130 already_AddRefed
<BrowserParent
>
131 ContentProcessManager::GetTopLevelBrowserParentByProcessAndTabId(
132 const ContentParentId
& aChildCpId
, const TabId
& aChildTabId
) {
133 RefPtr
<BrowserParent
> browserParent
=
134 GetBrowserParentByProcessAndTabId(aChildCpId
, aChildTabId
);
135 while (browserParent
&& browserParent
->GetBrowserBridgeParent()) {
136 browserParent
= browserParent
->GetBrowserBridgeParent()->Manager();
139 return browserParent
.forget();
142 } // namespace mozilla::dom