ContentProcessManager.cpp (4414B)
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/. */ 6 7 #include "ContentProcessManager.h" 8 9 #include "ContentParent.h" 10 #include "mozilla/AppShutdown.h" 11 #include "mozilla/ClearOnShutdown.h" 12 #include "mozilla/StaticPtr.h" 13 #include "mozilla/dom/BrowserParent.h" 14 #include "mozilla/dom/BrowsingContextGroup.h" 15 #include "mozilla/dom/CanonicalBrowsingContext.h" 16 #include "nsPrintfCString.h" 17 18 namespace mozilla::dom { 19 20 /* static */ 21 StaticAutoPtr<ContentProcessManager> ContentProcessManager::sSingleton; 22 23 /* static */ 24 ContentProcessManager* ContentProcessManager::GetSingleton() { 25 MOZ_ASSERT(XRE_IsParentProcess()); 26 27 if (!sSingleton && 28 !AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMShutdownFinal)) { 29 sSingleton = new ContentProcessManager(); 30 ClearOnShutdown(&sSingleton); 31 } 32 return sSingleton; 33 } 34 35 void ContentProcessManager::AddContentProcess(ContentParent* aChildCp) { 36 MOZ_ASSERT(NS_IsMainThread()); 37 MOZ_ASSERT(aChildCp); 38 39 mContentParentMap.WithEntryHandle(aChildCp->ChildID(), [&](auto&& entry) { 40 MOZ_ASSERT_IF(entry, entry.Data() == aChildCp); 41 entry.OrInsert(aChildCp); 42 }); 43 } 44 45 void ContentProcessManager::RemoveContentProcess( 46 const ContentParentId& aChildCpId) { 47 MOZ_ASSERT(NS_IsMainThread()); 48 49 MOZ_ALWAYS_TRUE(mContentParentMap.Remove(aChildCpId)); 50 } 51 52 ContentParent* ContentProcessManager::GetContentProcessById( 53 const ContentParentId& aChildCpId) { 54 MOZ_ASSERT(NS_IsMainThread()); 55 56 ContentParent* contentParent = mContentParentMap.Get(aChildCpId); 57 if (NS_WARN_IF(!contentParent)) { 58 return nullptr; 59 } 60 return contentParent; 61 } 62 63 bool ContentProcessManager::RegisterRemoteFrame(BrowserParent* aChildBp) { 64 MOZ_ASSERT(NS_IsMainThread()); 65 MOZ_ASSERT(aChildBp); 66 67 return mBrowserParentMap.WithEntryHandle( 68 aChildBp->GetTabId(), [&](auto&& entry) { 69 if (entry) { 70 MOZ_ASSERT(entry.Data() == aChildBp); 71 return false; 72 } 73 74 // Ensure that this BrowserParent's BrowsingContextGroup is kept alive 75 // until the BrowserParent has been unregistered, ensuring the group 76 // isn't destroyed while this BrowserParent can still send messages. 77 aChildBp->GetBrowsingContext()->Group()->AddKeepAlive(); 78 entry.Insert(aChildBp); 79 return true; 80 }); 81 } 82 83 void ContentProcessManager::UnregisterRemoteFrame(const TabId& aChildTabId) { 84 MOZ_ASSERT(NS_IsMainThread()); 85 86 auto childBp = mBrowserParentMap.Extract(aChildTabId); 87 MOZ_DIAGNOSTIC_ASSERT(childBp); 88 89 // Clear the corresponding keepalive which was added in `RegisterRemoteFrame`. 90 (*childBp)->GetBrowsingContext()->Group()->RemoveKeepAlive(); 91 } 92 93 ContentParentId ContentProcessManager::GetTabProcessId( 94 const TabId& aChildTabId) { 95 MOZ_ASSERT(NS_IsMainThread()); 96 97 if (BrowserParent* browserParent = mBrowserParentMap.Get(aChildTabId)) { 98 return browserParent->Manager()->ChildID(); 99 } 100 return ContentParentId(0); 101 } 102 103 uint32_t ContentProcessManager::GetBrowserParentCountByProcessId( 104 const ContentParentId& aChildCpId) { 105 MOZ_ASSERT(NS_IsMainThread()); 106 107 ContentParent* contentParent = mContentParentMap.Get(aChildCpId); 108 if (NS_WARN_IF(!contentParent)) { 109 return 0; 110 } 111 return contentParent->ManagedPBrowserParent().Count(); 112 } 113 114 already_AddRefed<BrowserParent> 115 ContentProcessManager::GetBrowserParentByProcessAndTabId( 116 const ContentParentId& aChildCpId, const TabId& aChildTabId) { 117 RefPtr<BrowserParent> browserParent = mBrowserParentMap.Get(aChildTabId); 118 if (NS_WARN_IF(!browserParent)) { 119 return nullptr; 120 } 121 122 if (NS_WARN_IF(browserParent->Manager()->ChildID() != aChildCpId)) { 123 return nullptr; 124 } 125 126 return browserParent.forget(); 127 } 128 129 already_AddRefed<BrowserParent> 130 ContentProcessManager::GetTopLevelBrowserParentByProcessAndTabId( 131 const ContentParentId& aChildCpId, const TabId& aChildTabId) { 132 RefPtr<BrowserParent> browserParent = 133 GetBrowserParentByProcessAndTabId(aChildCpId, aChildTabId); 134 while (browserParent && browserParent->GetBrowserBridgeParent()) { 135 browserParent = browserParent->GetBrowserBridgeParent()->Manager(); 136 } 137 138 return browserParent.forget(); 139 } 140 141 } // namespace mozilla::dom