LCOV - code coverage report
Current view: top level - dom/ipc - ContentProcessManager.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 28 159 17.6 %
Date: 2017-07-14 16:53:18 Functions: 3 16 18.8 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #include "ContentParent.h"
       9             : #include "mozilla/dom/TabParent.h"
      10             : 
      11             : #include "mozilla/StaticPtr.h"
      12             : #include "mozilla/ClearOnShutdown.h"
      13             : 
      14             : #include "nsPrintfCString.h"
      15             : #include "nsIScriptSecurityManager.h"
      16             : 
      17             : // XXX need another bug to move this to a common header.
      18             : #ifdef DISABLE_ASSERTS_FOR_FUZZING
      19             : #define ASSERT_UNLESS_FUZZING(...) do { } while (0)
      20             : #else
      21             : #define ASSERT_UNLESS_FUZZING(...) MOZ_ASSERT(false, __VA_ARGS__)
      22             : #endif
      23             : 
      24             : namespace mozilla {
      25             : namespace dom {
      26             : 
      27             : /* static */
      28             : StaticAutoPtr<ContentProcessManager>
      29           3 : ContentProcessManager::sSingleton;
      30             : 
      31             : /* static */ ContentProcessManager*
      32           3 : ContentProcessManager::GetSingleton()
      33             : {
      34           3 :   MOZ_ASSERT(XRE_IsParentProcess());
      35             : 
      36           3 :   if (!sSingleton) {
      37           1 :     sSingleton = new ContentProcessManager();
      38           1 :     ClearOnShutdown(&sSingleton);
      39             :   }
      40           3 :   return sSingleton;
      41             : }
      42             : 
      43             : void
      44           2 : ContentProcessManager::AddContentProcess(ContentParent* aChildCp,
      45             :                                          const ContentParentId& aParentCpId)
      46             : {
      47           2 :   MOZ_ASSERT(NS_IsMainThread());
      48           2 :   MOZ_ASSERT(aChildCp);
      49             : 
      50           2 :   ContentProcessInfo& info = mContentParentMap[aChildCp->ChildID()];
      51           2 :   if (!info.mCp) {
      52           2 :     info.mCp = aChildCp;
      53             :   } else {
      54           0 :     MOZ_ASSERT(info.mCp == aChildCp);
      55           0 :     MOZ_ASSERT_IF(!!info.mParentCpId, info.mParentCpId == aParentCpId);
      56             :   }
      57           2 :   info.mParentCpId = aParentCpId;
      58           2 : }
      59             : 
      60             : void
      61           0 : ContentProcessManager::RemoveContentProcess(const ContentParentId& aChildCpId)
      62             : {
      63           0 :   MOZ_ASSERT(NS_IsMainThread());
      64           0 :   MOZ_ASSERT(mContentParentMap.find(aChildCpId) != mContentParentMap.end());
      65             : 
      66           0 :   mContentParentMap.erase(aChildCpId);
      67           0 :   for (auto iter = mContentParentMap.begin();
      68           0 :        iter != mContentParentMap.end();
      69             :        ++iter) {
      70           0 :     if (!iter->second.mChildrenCpId.empty()) {
      71           0 :       iter->second.mChildrenCpId.erase(aChildCpId);
      72             :     }
      73             :   }
      74           0 : }
      75             : 
      76             : bool
      77           0 : ContentProcessManager::AddGrandchildProcess(const ContentParentId& aParentCpId,
      78             :                                             const ContentParentId& aChildCpId)
      79             : {
      80           0 :   MOZ_ASSERT(NS_IsMainThread());
      81             : 
      82           0 :   auto iter = mContentParentMap.find(aParentCpId);
      83           0 :   if (NS_WARN_IF(iter == mContentParentMap.end())) {
      84           0 :     ASSERT_UNLESS_FUZZING("Parent process should be already in map!");
      85             :     return false;
      86             :   }
      87           0 :   iter->second.mChildrenCpId.insert(aChildCpId);
      88           0 :   return true;
      89             : }
      90             : 
      91             : bool
      92           0 : ContentProcessManager::GetParentProcessId(const ContentParentId& aChildCpId,
      93             :                                           /*out*/ ContentParentId* aParentCpId)
      94             : {
      95           0 :   MOZ_ASSERT(NS_IsMainThread());
      96             : 
      97           0 :   auto iter = mContentParentMap.find(aChildCpId);
      98           0 :   if (NS_WARN_IF(iter == mContentParentMap.end())) {
      99           0 :     ASSERT_UNLESS_FUZZING();
     100             :     return false;
     101             :   }
     102           0 :   *aParentCpId = iter->second.mParentCpId;
     103           0 :   return true;
     104             : }
     105             : 
     106             : ContentParent*
     107           0 : ContentProcessManager::GetContentProcessById(const ContentParentId& aChildCpId)
     108             : {
     109           0 :   MOZ_ASSERT(NS_IsMainThread());
     110             : 
     111           0 :   auto iter = mContentParentMap.find(aChildCpId);
     112           0 :   if (NS_WARN_IF(iter == mContentParentMap.end())) {
     113           0 :     ASSERT_UNLESS_FUZZING();
     114             :     return nullptr;
     115             :   }
     116           0 :   return iter->second.mCp;
     117             : }
     118             : 
     119             : nsTArray<ContentParentId>
     120           0 : ContentProcessManager::GetAllChildProcessById(const ContentParentId& aParentCpId)
     121             : {
     122           0 :   MOZ_ASSERT(NS_IsMainThread());
     123             : 
     124           0 :   nsTArray<ContentParentId> cpIdArray;
     125           0 :   auto iter = mContentParentMap.find(aParentCpId);
     126           0 :   if (NS_WARN_IF(iter == mContentParentMap.end())) {
     127           0 :     ASSERT_UNLESS_FUZZING();
     128             :     return Move(cpIdArray);
     129             :   }
     130             : 
     131           0 :   for (auto cpIter = iter->second.mChildrenCpId.begin();
     132           0 :        cpIter != iter->second.mChildrenCpId.end();
     133             :        ++cpIter) {
     134           0 :     cpIdArray.AppendElement(*cpIter);
     135             :   }
     136             : 
     137           0 :   return Move(cpIdArray);
     138             : }
     139             : 
     140             : bool
     141           1 : ContentProcessManager::RegisterRemoteFrame(const TabId& aTabId,
     142             :                                            const ContentParentId& aOpenerCpId,
     143             :                                            const TabId& aOpenerTabId,
     144             :                                            const IPCTabContext& aContext,
     145             :                                            const ContentParentId& aChildCpId)
     146             : {
     147           1 :   MOZ_ASSERT(NS_IsMainThread());
     148             : 
     149           1 :   auto iter = mContentParentMap.find(aChildCpId);
     150           1 :   if (NS_WARN_IF(iter == mContentParentMap.end())) {
     151           0 :     ASSERT_UNLESS_FUZZING();
     152             :     return false;
     153             :   }
     154             : 
     155           2 :   struct RemoteFrameInfo info;
     156             : 
     157             :   // If it's a PopupIPCTabContext, it's the case that a TabChild want to
     158             :   // open a new tab. aOpenerTabId has to be it's parent frame's opener id.
     159           1 :   if (aContext.type() == IPCTabContext::TPopupIPCTabContext) {
     160           0 :     auto remoteFrameIter = iter->second.mRemoteFrames.find(aOpenerTabId);
     161           0 :     if (remoteFrameIter == iter->second.mRemoteFrames.end()) {
     162           0 :       ASSERT_UNLESS_FUZZING("Failed to find parent frame's opener id.");
     163             :       return false;
     164             :     }
     165             : 
     166           0 :     info.mOpenerCpId = remoteFrameIter->second.mOpenerCpId;
     167           0 :     info.mOpenerTabId = remoteFrameIter->second.mOpenerTabId;
     168           0 :     info.mContext = remoteFrameIter->second.mContext;
     169             :   }
     170             :   else {
     171           2 :     MaybeInvalidTabContext tc(aContext);
     172           1 :     if (!tc.IsValid()) {
     173           0 :       NS_ERROR(nsPrintfCString("Received an invalid TabContext from "
     174             :                                "the child process. (%s)",
     175             :                                tc.GetInvalidReason()).get());
     176           0 :       return false;
     177             :     }
     178           1 :     info.mOpenerCpId = aOpenerCpId;
     179           1 :     info.mOpenerTabId = aOpenerTabId;
     180           1 :     info.mContext = tc.GetTabContext();
     181             :   }
     182             : 
     183           1 :   iter->second.mRemoteFrames[aTabId] = info;
     184           1 :   return true;
     185             : }
     186             : 
     187             : void
     188           0 : ContentProcessManager::UnregisterRemoteFrame(const ContentParentId& aChildCpId,
     189             :                                              const TabId& aChildTabId)
     190             : {
     191           0 :   MOZ_ASSERT(NS_IsMainThread());
     192             : 
     193           0 :   auto iter = mContentParentMap.find(aChildCpId);
     194           0 :   if (NS_WARN_IF(iter == mContentParentMap.end())) {
     195           0 :     ASSERT_UNLESS_FUZZING();
     196             :     return;
     197             :   }
     198             : 
     199           0 :   auto remoteFrameIter = iter->second.mRemoteFrames.find(aChildTabId);
     200           0 :   if (remoteFrameIter != iter->second.mRemoteFrames.end()) {
     201           0 :     iter->second.mRemoteFrames.erase(aChildTabId);
     202             :   }
     203           0 : }
     204             : 
     205             : bool
     206           0 : ContentProcessManager::GetTabContextByProcessAndTabId(const ContentParentId& aChildCpId,
     207             :                                                       const TabId& aChildTabId,
     208             :                                                       /*out*/ TabContext* aTabContext)
     209             : {
     210           0 :   MOZ_ASSERT(NS_IsMainThread());
     211           0 :   MOZ_ASSERT(aTabContext);
     212             : 
     213           0 :   auto iter = mContentParentMap.find(aChildCpId);
     214           0 :   if (NS_WARN_IF(iter == mContentParentMap.end())) {
     215           0 :     ASSERT_UNLESS_FUZZING();
     216             :     return false;
     217             :   }
     218             : 
     219           0 :   auto remoteFrameIter = iter->second.mRemoteFrames.find(aChildTabId);
     220           0 :   if (NS_WARN_IF(remoteFrameIter == iter->second.mRemoteFrames.end())) {
     221           0 :     ASSERT_UNLESS_FUZZING();
     222             :     return false;
     223             :   }
     224             : 
     225           0 :   *aTabContext = remoteFrameIter->second.mContext;
     226             : 
     227           0 :   return true;
     228             : }
     229             : 
     230             : nsTArray<TabContext>
     231           0 : ContentProcessManager::GetTabContextByContentProcess(const ContentParentId& aChildCpId)
     232             : {
     233           0 :   MOZ_ASSERT(NS_IsMainThread());
     234             : 
     235           0 :   nsTArray<TabContext> tabContextArray;
     236           0 :   auto iter = mContentParentMap.find(aChildCpId);
     237           0 :   if (NS_WARN_IF(iter == mContentParentMap.end())) {
     238           0 :     ASSERT_UNLESS_FUZZING();
     239             :     return Move(tabContextArray);
     240             :   }
     241             : 
     242           0 :   for (auto remoteFrameIter = iter->second.mRemoteFrames.begin();
     243           0 :        remoteFrameIter != iter->second.mRemoteFrames.end();
     244             :        ++remoteFrameIter) {
     245           0 :     tabContextArray.AppendElement(remoteFrameIter->second.mContext);
     246             :   }
     247             : 
     248           0 :   return Move(tabContextArray);
     249             : }
     250             : 
     251             : bool
     252           0 : ContentProcessManager::GetRemoteFrameOpenerTabId(const ContentParentId& aChildCpId,
     253             :                                                  const TabId& aChildTabId,
     254             :                                                  /*out*/ContentParentId* aOpenerCpId,
     255             :                                                  /*out*/TabId* aOpenerTabId)
     256             : {
     257           0 :   MOZ_ASSERT(NS_IsMainThread());
     258           0 :   auto iter = mContentParentMap.find(aChildCpId);
     259           0 :   if (NS_WARN_IF(iter == mContentParentMap.end())) {
     260           0 :     ASSERT_UNLESS_FUZZING();
     261             :     return false;
     262             :   }
     263             : 
     264           0 :   auto remoteFrameIter = iter->second.mRemoteFrames.find(aChildTabId);
     265           0 :   if (NS_WARN_IF(remoteFrameIter == iter->second.mRemoteFrames.end())) {
     266           0 :     ASSERT_UNLESS_FUZZING();
     267             :     return false;
     268             :   }
     269             : 
     270           0 :   *aOpenerCpId = remoteFrameIter->second.mOpenerCpId;
     271           0 :   *aOpenerTabId = remoteFrameIter->second.mOpenerTabId;
     272             : 
     273           0 :   return true;
     274             : }
     275             : 
     276             : already_AddRefed<TabParent>
     277           0 : ContentProcessManager::GetTabParentByProcessAndTabId(const ContentParentId& aChildCpId,
     278             :                                                      const TabId& aChildTabId)
     279             : {
     280           0 :   MOZ_ASSERT(NS_IsMainThread());
     281             : 
     282           0 :   auto iter = mContentParentMap.find(aChildCpId);
     283           0 :   if (NS_WARN_IF(iter == mContentParentMap.end())) {
     284           0 :     ASSERT_UNLESS_FUZZING();
     285             :     return nullptr;
     286             :   }
     287             : 
     288           0 :   const ManagedContainer<PBrowserParent>& browsers = iter->second.mCp->ManagedPBrowserParent();
     289           0 :   for (auto iter = browsers.ConstIter(); !iter.Done(); iter.Next()) {
     290           0 :     RefPtr<TabParent> tab = TabParent::GetFrom(iter.Get()->GetKey());
     291           0 :     if (tab->GetTabId() == aChildTabId) {
     292           0 :       return tab.forget();
     293             :     }
     294             :   }
     295             : 
     296           0 :   return nullptr;
     297             : }
     298             : 
     299             : already_AddRefed<TabParent>
     300           0 : ContentProcessManager::GetTopLevelTabParentByProcessAndTabId(const ContentParentId& aChildCpId,
     301             :                                                              const TabId& aChildTabId)
     302             : {
     303           0 :   MOZ_ASSERT(NS_IsMainThread());
     304             : 
     305             :   // Used to keep the current ContentParentId and the current TabId
     306             :   // in the iteration(do-while loop below)
     307           0 :   ContentParentId currentCpId;
     308           0 :   TabId currentTabId;
     309             : 
     310             :   // To get the ContentParentId and the TabParentId on upper level
     311           0 :   ContentParentId parentCpId = aChildCpId;
     312           0 :   TabId openerTabId = aChildTabId;
     313             : 
     314             :   // Stop this loop when the upper ContentParentId of
     315             :   // the current ContentParentId is chrome(ContentParentId = 0).
     316           0 :   do {
     317             :     // Update the current ContentParentId and TabId in iteration
     318           0 :     currentCpId = parentCpId;
     319           0 :     currentTabId = openerTabId;
     320             : 
     321             :     // Get the ContentParentId and TabId on upper level
     322           0 :     if (!GetRemoteFrameOpenerTabId(currentCpId, currentTabId, &parentCpId, &openerTabId)) {
     323           0 :       return nullptr;
     324             :     }
     325           0 :   } while (parentCpId);
     326             : 
     327             :   // Get the top level TabParent by the current ContentParentId and TabId
     328           0 :   return GetTabParentByProcessAndTabId(currentCpId, currentTabId);
     329             : }
     330             : 
     331             : nsTArray<TabId>
     332           0 : ContentProcessManager::GetTabParentsByProcessId(const ContentParentId& aChildCpId)
     333             : {
     334           0 :   MOZ_ASSERT(NS_IsMainThread());
     335             : 
     336           0 :   nsTArray<TabId> tabIdList;
     337           0 :   auto iter = mContentParentMap.find(aChildCpId);
     338           0 :   if (NS_WARN_IF(iter == mContentParentMap.end())) {
     339           0 :     ASSERT_UNLESS_FUZZING();
     340             :     return Move(tabIdList);
     341             :   }
     342             : 
     343           0 :   for (auto remoteFrameIter = iter->second.mRemoteFrames.begin();
     344           0 :       remoteFrameIter != iter->second.mRemoteFrames.end();
     345             :       ++remoteFrameIter) {
     346           0 :     tabIdList.AppendElement(remoteFrameIter->first);
     347             :   }
     348             : 
     349           0 :   return Move(tabIdList);
     350             : }
     351             : 
     352             : uint32_t
     353           0 : ContentProcessManager::GetTabParentCountByProcessId(const ContentParentId& aChildCpId)
     354             : {
     355           0 :   MOZ_ASSERT(NS_IsMainThread());
     356             : 
     357           0 :   auto iter = mContentParentMap.find(aChildCpId);
     358           0 :   if (NS_WARN_IF(iter == mContentParentMap.end())) {
     359           0 :     return 0;
     360             :   }
     361             : 
     362           0 :   return iter->second.mRemoteFrames.size();
     363             : }
     364             : 
     365             : } // namespace dom
     366             : } // namespace mozilla

Generated by: LCOV version 1.13