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/dom/BrowserParent.h"
10 #include "mozilla/dom/BrowsingContextGroup.h"
11 #include "mozilla/dom/CanonicalBrowsingContext.h"
13 #include "mozilla/StaticPtr.h"
14 #include "mozilla/ClearOnShutdown.h"
16 #include "nsPrintfCString.h"
18 namespace mozilla::dom
{
21 StaticAutoPtr
<ContentProcessManager
> ContentProcessManager::sSingleton
;
24 ContentProcessManager
* ContentProcessManager::GetSingleton() {
25 MOZ_ASSERT(XRE_IsParentProcess());
28 sSingleton
= new ContentProcessManager();
29 ClearOnShutdown(&sSingleton
);
34 void ContentProcessManager::AddContentProcess(ContentParent
* aChildCp
) {
35 MOZ_ASSERT(NS_IsMainThread());
38 mContentParentMap
.WithEntryHandle(aChildCp
->ChildID(), [&](auto&& entry
) {
39 MOZ_ASSERT_IF(entry
, entry
.Data() == aChildCp
);
40 entry
.OrInsert(aChildCp
);
44 void ContentProcessManager::RemoveContentProcess(
45 const ContentParentId
& aChildCpId
) {
46 MOZ_ASSERT(NS_IsMainThread());
48 MOZ_ALWAYS_TRUE(mContentParentMap
.Remove(aChildCpId
));
51 ContentParent
* ContentProcessManager::GetContentProcessById(
52 const ContentParentId
& aChildCpId
) {
53 MOZ_ASSERT(NS_IsMainThread());
55 ContentParent
* contentParent
= mContentParentMap
.Get(aChildCpId
);
56 if (NS_WARN_IF(!contentParent
)) {
62 bool ContentProcessManager::RegisterRemoteFrame(BrowserParent
* aChildBp
) {
63 MOZ_ASSERT(NS_IsMainThread());
66 return mBrowserParentMap
.WithEntryHandle(
67 aChildBp
->GetTabId(), [&](auto&& entry
) {
69 MOZ_ASSERT(entry
.Data() == aChildBp
);
73 // Ensure that this BrowserParent's BrowsingContextGroup is kept alive
74 // until the BrowserParent has been unregistered, ensuring the group
75 // isn't destroyed while this BrowserParent can still send messages.
76 aChildBp
->GetBrowsingContext()->Group()->AddKeepAlive();
77 entry
.Insert(aChildBp
);
82 void ContentProcessManager::UnregisterRemoteFrame(const TabId
& aChildTabId
) {
83 MOZ_ASSERT(NS_IsMainThread());
85 auto childBp
= mBrowserParentMap
.GetAndRemove(aChildTabId
);
86 MOZ_DIAGNOSTIC_ASSERT(childBp
);
88 // Clear the corresponding keepalive which was added in `RegisterRemoteFrame`.
89 (*childBp
)->GetBrowsingContext()->Group()->RemoveKeepAlive();
92 ContentParentId
ContentProcessManager::GetTabProcessId(
93 const TabId
& aChildTabId
) {
94 MOZ_ASSERT(NS_IsMainThread());
96 if (BrowserParent
* browserParent
= mBrowserParentMap
.Get(aChildTabId
)) {
97 return browserParent
->Manager()->ChildID();
99 return ContentParentId(0);
102 uint32_t ContentProcessManager::GetBrowserParentCountByProcessId(
103 const ContentParentId
& aChildCpId
) {
104 MOZ_ASSERT(NS_IsMainThread());
106 ContentParent
* contentParent
= mContentParentMap
.Get(aChildCpId
);
107 if (NS_WARN_IF(!contentParent
)) {
110 return contentParent
->ManagedPBrowserParent().Count();
113 already_AddRefed
<BrowserParent
>
114 ContentProcessManager::GetBrowserParentByProcessAndTabId(
115 const ContentParentId
& aChildCpId
, const TabId
& aChildTabId
) {
116 RefPtr
<BrowserParent
> browserParent
= mBrowserParentMap
.Get(aChildTabId
);
117 if (NS_WARN_IF(!browserParent
)) {
121 if (NS_WARN_IF(browserParent
->Manager()->ChildID() != aChildCpId
)) {
125 return browserParent
.forget();
128 already_AddRefed
<BrowserParent
>
129 ContentProcessManager::GetTopLevelBrowserParentByProcessAndTabId(
130 const ContentParentId
& aChildCpId
, const TabId
& aChildTabId
) {
131 RefPtr
<BrowserParent
> browserParent
=
132 GetBrowserParentByProcessAndTabId(aChildCpId
, aChildTabId
);
133 while (browserParent
&& browserParent
->GetBrowserBridgeParent()) {
134 browserParent
= browserParent
->GetBrowserBridgeParent()->Manager();
137 return browserParent
.forget();
140 } // namespace mozilla::dom