LCOV - code coverage report
Current view: top level - dom/ipc - ContentParent.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 464 2228 20.8 %
Date: 2017-07-14 16:53:18 Functions: 54 302 17.9 %
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
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/DebugOnly.h"
       8             : 
       9             : #include "base/basictypes.h"
      10             : 
      11             : #include "ContentParent.h"
      12             : #include "TabParent.h"
      13             : 
      14             : #if defined(ANDROID) || defined(LINUX)
      15             : # include <sys/time.h>
      16             : # include <sys/resource.h>
      17             : #endif
      18             : 
      19             : #ifdef MOZ_WIDGET_GONK
      20             : #include <sys/types.h>
      21             : #include <sys/wait.h>
      22             : #endif
      23             : 
      24             : #include "chrome/common/process_watcher.h"
      25             : 
      26             : #include "mozilla/a11y/PDocAccessible.h"
      27             : #include "GeckoProfiler.h"
      28             : #include "GMPServiceParent.h"
      29             : #include "HandlerServiceParent.h"
      30             : #include "IHistory.h"
      31             : #include "imgIContainer.h"
      32             : #if defined(XP_WIN) && defined(ACCESSIBILITY)
      33             : #include "mozilla/a11y/AccessibleWrap.h"
      34             : #endif
      35             : #include "mozilla/ClearOnShutdown.h"
      36             : #include "mozilla/StyleSheetInlines.h"
      37             : #include "mozilla/DataStorage.h"
      38             : #include "mozilla/devtools/HeapSnapshotTempFileHelperParent.h"
      39             : #include "mozilla/docshell/OfflineCacheUpdateParent.h"
      40             : #include "mozilla/dom/DataTransfer.h"
      41             : #include "mozilla/dom/Element.h"
      42             : #include "mozilla/dom/File.h"
      43             : #include "mozilla/dom/FileCreatorHelper.h"
      44             : #include "mozilla/dom/FileSystemSecurity.h"
      45             : #include "mozilla/dom/IPCBlobUtils.h"
      46             : #include "mozilla/dom/ExternalHelperAppParent.h"
      47             : #include "mozilla/dom/GetFilesHelper.h"
      48             : #include "mozilla/dom/GeolocationBinding.h"
      49             : #include "mozilla/dom/MemoryReportRequest.h"
      50             : #include "mozilla/dom/Notification.h"
      51             : #include "mozilla/dom/PContentBridgeParent.h"
      52             : #include "mozilla/dom/PContentPermissionRequestParent.h"
      53             : #include "mozilla/dom/PCycleCollectWithLogsParent.h"
      54             : #include "mozilla/dom/ServiceWorkerRegistrar.h"
      55             : #include "mozilla/dom/Storage.h"
      56             : #include "mozilla/dom/StorageIPC.h"
      57             : #include "mozilla/dom/power/PowerManagerService.h"
      58             : #include "mozilla/dom/Permissions.h"
      59             : #include "mozilla/dom/PresentationParent.h"
      60             : #include "mozilla/dom/PPresentationParent.h"
      61             : #include "mozilla/dom/PushNotifier.h"
      62             : #include "mozilla/dom/FlyWebPublishedServerIPC.h"
      63             : #include "mozilla/dom/quota/QuotaManagerService.h"
      64             : #include "mozilla/dom/time/DateCacheCleaner.h"
      65             : #include "mozilla/dom/URLClassifierParent.h"
      66             : #include "mozilla/embedding/printingui/PrintingParent.h"
      67             : #include "mozilla/gfx/gfxVars.h"
      68             : #include "mozilla/gfx/GPUProcessManager.h"
      69             : #include "mozilla/hal_sandbox/PHalParent.h"
      70             : #include "mozilla/ipc/BackgroundChild.h"
      71             : #include "mozilla/ipc/BackgroundParent.h"
      72             : #include "mozilla/ipc/FileDescriptorUtils.h"
      73             : #include "mozilla/ipc/PChildToParentStreamParent.h"
      74             : #include "mozilla/ipc/TestShellParent.h"
      75             : #include "mozilla/ipc/IPCStreamUtils.h"
      76             : #include "mozilla/intl/LocaleService.h"
      77             : #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
      78             : #include "mozilla/layers/PAPZParent.h"
      79             : #include "mozilla/layers/CompositorThread.h"
      80             : #include "mozilla/layers/ImageBridgeParent.h"
      81             : #include "mozilla/layers/LayerTreeOwnerTracker.h"
      82             : #include "mozilla/layout/RenderFrameParent.h"
      83             : #include "mozilla/loader/ScriptCacheActors.h"
      84             : #include "mozilla/LookAndFeel.h"
      85             : #include "mozilla/media/MediaParent.h"
      86             : #include "mozilla/Move.h"
      87             : #include "mozilla/net/NeckoParent.h"
      88             : #include "mozilla/plugins/PluginBridge.h"
      89             : #include "mozilla/Preferences.h"
      90             : #include "mozilla/ProcessHangMonitor.h"
      91             : #include "mozilla/ProcessHangMonitorIPC.h"
      92             : #include "mozilla/ScopeExit.h"
      93             : #include "mozilla/ScriptPreloader.h"
      94             : #include "mozilla/Services.h"
      95             : #include "mozilla/StaticPtr.h"
      96             : #include "mozilla/Telemetry.h"
      97             : #include "mozilla/TelemetryIPC.h"
      98             : #include "mozilla/WebBrowserPersistDocumentParent.h"
      99             : #include "mozilla/widget/ScreenManager.h"
     100             : #include "mozilla/Unused.h"
     101             : #include "nsAnonymousTemporaryFile.h"
     102             : #include "nsAppRunner.h"
     103             : #include "nsCDefaultURIFixup.h"
     104             : #include "nsCExternalHandlerService.h"
     105             : #include "nsCOMPtr.h"
     106             : #include "nsChromeRegistryChrome.h"
     107             : #include "nsConsoleMessage.h"
     108             : #include "nsConsoleService.h"
     109             : #include "nsContentUtils.h"
     110             : #include "nsDebugImpl.h"
     111             : #include "nsFrameLoader.h"
     112             : #include "nsFrameMessageManager.h"
     113             : #include "nsHashPropertyBag.h"
     114             : #include "nsIAlertsService.h"
     115             : #include "nsIClipboard.h"
     116             : #include "nsContentPermissionHelper.h"
     117             : #include "nsIContentProcess.h"
     118             : #include "nsICycleCollectorListener.h"
     119             : #include "nsIDocShellTreeOwner.h"
     120             : #include "nsIDocument.h"
     121             : #include "nsIDOMGeoGeolocation.h"
     122             : #include "nsIDOMGeoPositionError.h"
     123             : #include "nsIDragService.h"
     124             : #include "mozilla/dom/WakeLock.h"
     125             : #include "nsIDOMWindow.h"
     126             : #include "nsIExternalProtocolService.h"
     127             : #include "nsIFormProcessor.h"
     128             : #include "nsIGfxInfo.h"
     129             : #include "nsIIdleService.h"
     130             : #include "nsIInterfaceRequestorUtils.h"
     131             : #include "nsIMemoryInfoDumper.h"
     132             : #include "nsIMemoryReporter.h"
     133             : #include "nsIMozBrowserFrame.h"
     134             : #include "nsIMutable.h"
     135             : #include "nsINSSU2FToken.h"
     136             : #include "nsIObserverService.h"
     137             : #include "nsIParentChannel.h"
     138             : #include "nsIPresShell.h"
     139             : #include "nsIRemoteWindowContext.h"
     140             : #include "nsIScriptError.h"
     141             : #include "nsIScriptSecurityManager.h"
     142             : #include "nsISiteSecurityService.h"
     143             : #include "nsISpellChecker.h"
     144             : #include "nsISupportsPrimitives.h"
     145             : #include "nsITimer.h"
     146             : #include "nsIURIFixup.h"
     147             : #include "nsIDocShellTreeOwner.h"
     148             : #include "nsIXULWindow.h"
     149             : #include "nsIDOMChromeWindow.h"
     150             : #include "nsIWindowWatcher.h"
     151             : #include "nsPIWindowWatcher.h"
     152             : #include "nsWindowWatcher.h"
     153             : #include "nsIXULRuntime.h"
     154             : #include "mozilla/dom/nsMixedContentBlocker.h"
     155             : #include "nsMemoryInfoDumper.h"
     156             : #include "nsMemoryReporterManager.h"
     157             : #include "nsServiceManagerUtils.h"
     158             : #include "nsStyleSheetService.h"
     159             : #include "nsThreadUtils.h"
     160             : #include "nsToolkitCompsCID.h"
     161             : #include "nsWidgetsCID.h"
     162             : #include "PreallocatedProcessManager.h"
     163             : #include "ProcessPriorityManager.h"
     164             : #include "SandboxHal.h"
     165             : #include "SourceSurfaceRawData.h"
     166             : #include "TabParent.h"
     167             : #include "URIUtils.h"
     168             : #include "nsIWebBrowserChrome.h"
     169             : #include "nsIDocShell.h"
     170             : #include "nsDocShell.h"
     171             : #include "nsOpenURIInFrameParams.h"
     172             : #include "mozilla/net/NeckoMessageUtils.h"
     173             : #include "gfxPrefs.h"
     174             : #include "prio.h"
     175             : #include "private/pprio.h"
     176             : #include "ContentProcessManager.h"
     177             : #include "mozilla/dom/ipc/StructuredCloneData.h"
     178             : #include "mozilla/psm/PSMContentListener.h"
     179             : #include "nsPluginHost.h"
     180             : #include "nsPluginTags.h"
     181             : #include "nsIBlocklistService.h"
     182             : #include "mozilla/StyleSheet.h"
     183             : #include "mozilla/StyleSheetInlines.h"
     184             : #include "nsHostObjectProtocolHandler.h"
     185             : #include "nsICaptivePortalService.h"
     186             : #include "nsIObjectLoadingContent.h"
     187             : 
     188             : #include "nsIBidiKeyboard.h"
     189             : 
     190             : #include "nsLayoutStylesheetCache.h"
     191             : 
     192             : #include "ContentPrefs.h"
     193             : #include "mozilla/Sprintf.h"
     194             : 
     195             : #ifdef MOZ_WEBRTC
     196             : #include "signaling/src/peerconnection/WebrtcGlobalParent.h"
     197             : #endif
     198             : 
     199             : #if defined(ANDROID) || defined(LINUX)
     200             : #include "nsSystemInfo.h"
     201             : #endif
     202             : 
     203             : #if defined(XP_LINUX)
     204             : #include "mozilla/Hal.h"
     205             : #endif
     206             : 
     207             : #ifdef ANDROID
     208             : # include "gfxAndroidPlatform.h"
     209             : #endif
     210             : 
     211             : #ifdef MOZ_PERMISSIONS
     212             : # include "nsPermissionManager.h"
     213             : #endif
     214             : 
     215             : #ifdef MOZ_WIDGET_ANDROID
     216             : # include "AndroidBridge.h"
     217             : #endif
     218             : 
     219             : #ifdef MOZ_WIDGET_GTK
     220             : #include <gdk/gdk.h>
     221             : #endif
     222             : 
     223             : #include "mozilla/RemoteSpellCheckEngineParent.h"
     224             : 
     225             : #include "Crypto.h"
     226             : 
     227             : #ifdef MOZ_WEBSPEECH
     228             : #include "mozilla/dom/SpeechSynthesisParent.h"
     229             : #endif
     230             : 
     231             : #if defined(MOZ_CONTENT_SANDBOX)
     232             : #include "mozilla/SandboxSettings.h"
     233             : #if defined(XP_LINUX)
     234             : #include "mozilla/SandboxInfo.h"
     235             : #include "mozilla/SandboxBroker.h"
     236             : #include "mozilla/SandboxBrokerPolicyFactory.h"
     237             : #endif
     238             : #endif
     239             : 
     240             : #ifdef MOZ_TOOLKIT_SEARCH
     241             : #include "nsIBrowserSearchService.h"
     242             : #endif
     243             : 
     244             : #ifdef XP_WIN
     245             : #include "mozilla/widget/AudioSession.h"
     246             : #endif
     247             : 
     248             : #ifdef MOZ_CRASHREPORTER
     249             : #include "nsThread.h"
     250             : #include "mozilla/ipc/CrashReporterHost.h"
     251             : #endif
     252             : 
     253             : #ifdef ACCESSIBILITY
     254             : #include "nsAccessibilityService.h"
     255             : #endif
     256             : 
     257             : #ifdef MOZ_GECKO_PROFILER
     258             : #include "nsIProfiler.h"
     259             : #include "ProfilerParent.h"
     260             : #endif
     261             : 
     262             : #ifdef MOZ_CODE_COVERAGE
     263             : #include "mozilla/CodeCoverageHandler.h"
     264             : #endif
     265             : 
     266             : // For VP9Benchmark::sBenchmarkFpsPref
     267             : #include "Benchmark.h"
     268             : 
     269             : static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
     270             : 
     271             : #if defined(XP_WIN)
     272             : // e10s forced enable pref, defined in nsAppRunner.cpp
     273             : extern const char* kForceEnableE10sPref;
     274             : #endif
     275             : 
     276             : using base::ChildPrivileges;
     277             : using base::KillProcess;
     278             : 
     279             : #ifdef MOZ_CRASHREPORTER
     280             : using namespace CrashReporter;
     281             : #endif
     282             : using namespace mozilla::dom::power;
     283             : using namespace mozilla::media;
     284             : using namespace mozilla::embedding;
     285             : using namespace mozilla::gfx;
     286             : using namespace mozilla::gmp;
     287             : using namespace mozilla::hal;
     288             : using namespace mozilla::ipc;
     289             : using namespace mozilla::intl;
     290             : using namespace mozilla::layers;
     291             : using namespace mozilla::layout;
     292             : using namespace mozilla::net;
     293             : using namespace mozilla::jsipc;
     294             : using namespace mozilla::psm;
     295             : using namespace mozilla::widget;
     296             : using mozilla::loader::PScriptCacheParent;
     297             : using mozilla::Telemetry::ProcessID;
     298             : 
     299             : // XXX Workaround for bug 986973 to maintain the existing broken semantics
     300             : template<>
     301             : struct nsIConsoleService::COMTypeInfo<nsConsoleService, void> {
     302             :   static const nsIID kIID;
     303             : };
     304             : const nsIID nsIConsoleService::COMTypeInfo<nsConsoleService, void>::kIID = NS_ICONSOLESERVICE_IID;
     305             : 
     306             : namespace mozilla {
     307             : namespace dom {
     308             : 
     309             : #define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
     310             : #define NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC "ipc:network:set-connectivity"
     311             : 
     312             : // IPC receiver for remote GC/CC logging.
     313             : class CycleCollectWithLogsParent final : public PCycleCollectWithLogsParent
     314             : {
     315             : public:
     316           0 :   ~CycleCollectWithLogsParent()
     317           0 :   {
     318           0 :     MOZ_COUNT_DTOR(CycleCollectWithLogsParent);
     319           0 :   }
     320             : 
     321           0 :   static bool AllocAndSendConstructor(ContentParent* aManager,
     322             :                                       bool aDumpAllTraces,
     323             :                                       nsICycleCollectorLogSink* aSink,
     324             :                                       nsIDumpGCAndCCLogsCallback* aCallback)
     325             :   {
     326             :     CycleCollectWithLogsParent *actor;
     327             :     FILE* gcLog;
     328             :     FILE* ccLog;
     329             :     nsresult rv;
     330             : 
     331           0 :     actor = new CycleCollectWithLogsParent(aSink, aCallback);
     332           0 :     rv = actor->mSink->Open(&gcLog, &ccLog);
     333           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     334           0 :       delete actor;
     335           0 :       return false;
     336             :     }
     337             : 
     338             :     return aManager->
     339           0 :       SendPCycleCollectWithLogsConstructor(actor,
     340             :                                            aDumpAllTraces,
     341           0 :                                            FILEToFileDescriptor(gcLog),
     342           0 :                                            FILEToFileDescriptor(ccLog));
     343             :   }
     344             : 
     345             : private:
     346           0 :   virtual mozilla::ipc::IPCResult RecvCloseGCLog() override
     347             :   {
     348           0 :     Unused << mSink->CloseGCLog();
     349           0 :     return IPC_OK();
     350             :   }
     351             : 
     352           0 :   virtual mozilla::ipc::IPCResult RecvCloseCCLog() override
     353             :   {
     354           0 :     Unused << mSink->CloseCCLog();
     355           0 :     return IPC_OK();
     356             :   }
     357             : 
     358           0 :   virtual mozilla::ipc::IPCResult Recv__delete__() override
     359             :   {
     360             :     // Report completion to mCallback only on successful
     361             :     // completion of the protocol.
     362           0 :     nsCOMPtr<nsIFile> gcLog, ccLog;
     363           0 :     mSink->GetGcLog(getter_AddRefs(gcLog));
     364           0 :     mSink->GetCcLog(getter_AddRefs(ccLog));
     365           0 :     Unused << mCallback->OnDump(gcLog, ccLog, /* parent = */ false);
     366           0 :     return IPC_OK();
     367             :   }
     368             : 
     369           0 :   virtual void ActorDestroy(ActorDestroyReason aReason) override
     370             :   {
     371             :     // If the actor is unexpectedly destroyed, we deliberately
     372             :     // don't call Close[GC]CLog on the sink, because the logs may
     373             :     // be incomplete.  See also the nsCycleCollectorLogSinkToFile
     374             :     // implementaiton of those methods, and its destructor.
     375           0 :   }
     376             : 
     377           0 :   CycleCollectWithLogsParent(nsICycleCollectorLogSink *aSink,
     378             :                              nsIDumpGCAndCCLogsCallback *aCallback)
     379           0 :     : mSink(aSink), mCallback(aCallback)
     380             :   {
     381           0 :     MOZ_COUNT_CTOR(CycleCollectWithLogsParent);
     382           0 :   }
     383             : 
     384             :   nsCOMPtr<nsICycleCollectorLogSink> mSink;
     385             :   nsCOMPtr<nsIDumpGCAndCCLogsCallback> mCallback;
     386             : };
     387             : 
     388             : // A memory reporter for ContentParent objects themselves.
     389           1 : class ContentParentsMemoryReporter final : public nsIMemoryReporter
     390             : {
     391           0 :   ~ContentParentsMemoryReporter() {}
     392             : public:
     393             :   NS_DECL_ISUPPORTS
     394             :   NS_DECL_NSIMEMORYREPORTER
     395             : };
     396             : 
     397          13 : NS_IMPL_ISUPPORTS(ContentParentsMemoryReporter, nsIMemoryReporter)
     398             : 
     399             : NS_IMETHODIMP
     400           0 : ContentParentsMemoryReporter::CollectReports(
     401             :   nsIHandleReportCallback* aHandleReport,
     402             :   nsISupports* aData,
     403             :   bool aAnonymize)
     404             : {
     405           0 :   AutoTArray<ContentParent*, 16> cps;
     406           0 :   ContentParent::GetAllEvenIfDead(cps);
     407             : 
     408           0 :   for (uint32_t i = 0; i < cps.Length(); i++) {
     409           0 :     ContentParent* cp = cps[i];
     410           0 :     MessageChannel* channel = cp->GetIPCChannel();
     411             : 
     412           0 :     nsString friendlyName;
     413           0 :     cp->FriendlyName(friendlyName, aAnonymize);
     414             : 
     415           0 :     cp->AddRef();
     416           0 :     nsrefcnt refcnt = cp->Release();
     417             : 
     418           0 :     const char* channelStr = "no channel";
     419           0 :     uint32_t numQueuedMessages = 0;
     420           0 :     if (channel) {
     421           0 :       if (channel->Unsound_IsClosed()) {
     422           0 :         channelStr = "closed channel";
     423             :       } else {
     424           0 :         channelStr = "open channel";
     425             :       }
     426           0 :       numQueuedMessages = channel->Unsound_NumQueuedMessages();
     427             :     }
     428             : 
     429             :     nsPrintfCString path("queued-ipc-messages/content-parent"
     430             :                          "(%s, pid=%d, %s, 0x%p, refcnt=%" PRIuPTR ")",
     431           0 :                          NS_ConvertUTF16toUTF8(friendlyName).get(),
     432             :                          cp->Pid(), channelStr,
     433           0 :                          static_cast<nsIContentParent*>(cp), refcnt);
     434             : 
     435           0 :     NS_NAMED_LITERAL_CSTRING(desc,
     436             :       "The number of unset IPC messages held in this ContentParent's "
     437             :       "channel.  A large value here might indicate that we're leaking "
     438             :       "messages.  Similarly, a ContentParent object for a process that's no "
     439             :       "longer running could indicate that we're leaking ContentParents.");
     440             : 
     441           0 :     aHandleReport->Callback(/* process */ EmptyCString(), path,
     442             :                             KIND_OTHER, UNITS_COUNT,
     443           0 :                             numQueuedMessages, desc, aData);
     444             :   }
     445             : 
     446           0 :   return NS_OK;
     447             : }
     448             : 
     449             : nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>* ContentParent::sBrowserContentParents;
     450             : 
     451             : namespace {
     452             : 
     453             : class ScriptableCPInfo final : public nsIContentProcessInfo
     454             : {
     455             : public:
     456           2 :   explicit ScriptableCPInfo(ContentParent* aParent)
     457           2 :     : mContentParent(aParent)
     458             :   {
     459           2 :     MOZ_ASSERT(mContentParent);
     460           2 :   }
     461             : 
     462             :   NS_DECL_ISUPPORTS
     463             :   NS_DECL_NSICONTENTPROCESSINFO
     464             : 
     465           0 :   void ProcessDied()
     466             :   {
     467           0 :     mContentParent = nullptr;
     468           0 :   }
     469             : 
     470             : private:
     471           0 :   ~ScriptableCPInfo()
     472           0 :   {
     473           0 :     MOZ_ASSERT(!mContentParent, "must call ProcessDied");
     474           0 :   }
     475             : 
     476             :   ContentParent* mContentParent;
     477             : };
     478             : 
     479           8 : NS_IMPL_ISUPPORTS(ScriptableCPInfo, nsIContentProcessInfo)
     480             : 
     481             : NS_IMETHODIMP
     482           0 : ScriptableCPInfo::GetIsAlive(bool* aIsAlive)
     483             : {
     484           0 :   *aIsAlive = mContentParent != nullptr;
     485           0 :   return NS_OK;
     486             : }
     487             : 
     488             : NS_IMETHODIMP
     489           0 : ScriptableCPInfo::GetProcessId(int32_t* aPID)
     490             : {
     491           0 :   if (!mContentParent) {
     492           0 :     *aPID = -1;
     493           0 :     return NS_ERROR_NOT_INITIALIZED;
     494             :   }
     495             : 
     496           0 :   *aPID = mContentParent->Pid();
     497           0 :   if (*aPID == -1) {
     498           0 :     return NS_ERROR_FAILURE;
     499             :   }
     500             : 
     501           0 :   return NS_OK;
     502             : }
     503             : 
     504             : NS_IMETHODIMP
     505           0 : ScriptableCPInfo::GetOpener(nsIContentProcessInfo** aInfo)
     506             : {
     507           0 :   *aInfo = nullptr;
     508           0 :   if (!mContentParent) {
     509           0 :     return NS_ERROR_NOT_INITIALIZED;
     510             :   }
     511             : 
     512           0 :   if (ContentParent* opener = mContentParent->Opener()) {
     513           0 :     nsCOMPtr<nsIContentProcessInfo> info = opener->ScriptableHelper();
     514           0 :     info.forget(aInfo);
     515             :   }
     516           0 :   return NS_OK;
     517             : }
     518             : 
     519             : NS_IMETHODIMP
     520           0 : ScriptableCPInfo::GetTabCount(int32_t* aTabCount)
     521             : {
     522           0 :   if (!mContentParent) {
     523           0 :     return NS_ERROR_NOT_INITIALIZED;
     524             :   }
     525             : 
     526           0 :   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
     527           0 :   *aTabCount = cpm->GetTabParentCountByProcessId(mContentParent->ChildID());
     528             : 
     529           0 :   return NS_OK;
     530             : }
     531             : 
     532             : NS_IMETHODIMP
     533           0 : ScriptableCPInfo::GetMessageManager(nsIMessageSender** aMessenger)
     534             : {
     535           0 :   *aMessenger = nullptr;
     536           0 :   if (!mContentParent) {
     537           0 :     return NS_ERROR_NOT_INITIALIZED;
     538             :   }
     539             : 
     540           0 :   nsCOMPtr<nsIMessageSender> manager = mContentParent->GetMessageManager();
     541           0 :   manager.forget(aMessenger);
     542           0 :   return NS_OK;
     543             : }
     544             : 
     545             : ProcessID
     546           6 : GetTelemetryProcessID(const nsAString& remoteType)
     547             : {
     548             :   // OOP WebExtensions run in a content process.
     549             :   // For Telemetry though we want to break out collected data from the WebExtensions process into
     550             :   // a separate bucket, to make sure we can analyze it separately and avoid skewing normal content
     551             :   // process metrics.
     552           6 :   return remoteType.EqualsLiteral(EXTENSION_REMOTE_TYPE) ? ProcessID::Extension : ProcessID::Content;
     553             : }
     554             : 
     555             : } // anonymous namespace
     556             : 
     557             : nsDataHashtable<nsUint32HashKey, ContentParent*>* ContentParent::sJSPluginContentParents;
     558             : nsTArray<ContentParent*>* ContentParent::sPrivateContent;
     559           3 : StaticAutoPtr<LinkedList<ContentParent> > ContentParent::sContentParents;
     560             : #if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
     561             : UniquePtr<SandboxBrokerPolicyFactory> ContentParent::sSandboxBrokerPolicyFactory;
     562             : #endif
     563             : uint64_t ContentParent::sNextTabParentId = 0;
     564           3 : nsDataHashtable<nsUint64HashKey, TabParent*> ContentParent::sNextTabParents;
     565             : 
     566             : // This is true when subprocess launching is enabled.  This is the
     567             : // case between StartUp() and ShutDown() or JoinAllSubprocesses().
     568             : static bool sCanLaunchSubprocesses;
     569             : 
     570             : // Set to true if the DISABLE_UNSAFE_CPOW_WARNINGS environment variable is
     571             : // set.
     572             : static bool sDisableUnsafeCPOWWarnings = false;
     573             : 
     574             : // The first content child has ID 1, so the chrome process can have ID 0.
     575             : static uint64_t gContentChildID = 1;
     576             : 
     577             : static const char* sObserverTopics[] = {
     578             :   "xpcom-shutdown",
     579             :   "profile-before-change",
     580             :   NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC,
     581             :   NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC,
     582             :   NS_IPC_CAPTIVE_PORTAL_SET_STATE,
     583             :   "memory-pressure",
     584             :   "child-gc-request",
     585             :   "child-cc-request",
     586             :   "child-mmu-request",
     587             :   "last-pb-context-exited",
     588             :   "file-watcher-update",
     589             : #ifdef ACCESSIBILITY
     590             :   "a11y-init-or-shutdown",
     591             : #endif
     592             :   "cacheservice:empty-cache",
     593             :   "intl:app-locales-changed",
     594             :   "intl:requested-locales-changed",
     595             : };
     596             : 
     597             : // PreallocateProcess is called by the PreallocatedProcessManager.
     598             : // ContentParent then takes this process back within GetNewOrUsedBrowserProcess.
     599             : /*static*/ already_AddRefed<ContentParent>
     600           1 : ContentParent::PreallocateProcess()
     601             : {
     602             :   RefPtr<ContentParent> process =
     603             :     new ContentParent(/* aOpener = */ nullptr,
     604           3 :                       NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE));
     605             : 
     606           1 :   PreallocatedProcessManager::AddBlocker(process);
     607             : 
     608           1 :   if (!process->LaunchSubprocess(PROCESS_PRIORITY_PREALLOC)) {
     609           0 :     return nullptr;
     610             :   }
     611             : 
     612           1 :   process->Init();
     613           1 :   return process.forget();
     614             : }
     615             : 
     616             : /*static*/ void
     617           3 : ContentParent::StartUp()
     618             : {
     619             :   // We could launch sub processes from content process
     620             :   // FIXME Bug 1023701 - Stop using ContentParent static methods in
     621             :   // child process
     622           3 :   sCanLaunchSubprocesses = true;
     623             : 
     624           3 :   if (!XRE_IsParentProcess()) {
     625           2 :     return;
     626             :   }
     627             : 
     628             : #if defined(MOZ_CONTENT_SANDBOX) && defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 19
     629             :   // Require sandboxing on B2G >= KitKat.  This condition must stay
     630             :   // in sync with ContentChild::RecvSetProcessSandbox.
     631             :   if (!SandboxInfo::Get().CanSandboxContent()) {
     632             :     // MOZ_CRASH strings are only for debug builds; make sure the
     633             :     // message is clear on non-debug builds as well:
     634             :     printf_stderr("Sandboxing support is required on this platform.  "
     635             :                   "Recompile kernel with CONFIG_SECCOMP_FILTER=y\n");
     636             :     MOZ_CRASH("Sandboxing support is required on this platform.");
     637             :   }
     638             : #endif
     639             : 
     640             :   // Note: This reporter measures all ContentParents.
     641           1 :   RegisterStrongMemoryReporter(new ContentParentsMemoryReporter());
     642             : 
     643           1 :   mozilla::dom::time::InitializeDateCacheCleaner();
     644             : 
     645           1 :   BackgroundChild::Startup();
     646             : 
     647           1 :   sDisableUnsafeCPOWWarnings = PR_GetEnv("DISABLE_UNSAFE_CPOW_WARNINGS");
     648             : 
     649             : #if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
     650             :   sSandboxBrokerPolicyFactory = MakeUnique<SandboxBrokerPolicyFactory>();
     651             : #endif
     652             : }
     653             : 
     654             : /*static*/ void
     655           0 : ContentParent::ShutDown()
     656             : {
     657             :   // No-op for now.  We rely on normal process shutdown and
     658             :   // ClearOnShutdown() to clean up our state.
     659           0 :   sCanLaunchSubprocesses = false;
     660             : 
     661             : #if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
     662             :   sSandboxBrokerPolicyFactory = nullptr;
     663             : #endif
     664           0 : }
     665             : 
     666             : /*static*/ void
     667           0 : ContentParent::JoinProcessesIOThread(const nsTArray<ContentParent*>* aProcesses,
     668             :                                      Monitor* aMonitor, bool* aDone)
     669             : {
     670           0 :   const nsTArray<ContentParent*>& processes = *aProcesses;
     671           0 :   for (uint32_t i = 0; i < processes.Length(); ++i) {
     672           0 :     if (GeckoChildProcessHost* process = processes[i]->mSubprocess) {
     673           0 :       process->Join();
     674             :     }
     675             :   }
     676             :   {
     677           0 :     MonitorAutoLock lock(*aMonitor);
     678           0 :     *aDone = true;
     679           0 :     lock.Notify();
     680             :   }
     681             :   // Don't touch any arguments to this function from now on.
     682           0 : }
     683             : 
     684             : /*static*/ void
     685           0 : ContentParent::JoinAllSubprocesses()
     686             : {
     687           0 :   MOZ_ASSERT(NS_IsMainThread());
     688             : 
     689           0 :   AutoTArray<ContentParent*, 8> processes;
     690           0 :   GetAll(processes);
     691           0 :   if (processes.IsEmpty()) {
     692           0 :     printf_stderr("There are no live subprocesses.");
     693           0 :     return;
     694             :   }
     695             : 
     696           0 :   printf_stderr("Subprocesses are still alive.  Doing emergency join.\n");
     697             : 
     698           0 :   bool done = false;
     699           0 :   Monitor monitor("mozilla.dom.ContentParent.JoinAllSubprocesses");
     700           0 :   XRE_GetIOMessageLoop()->PostTask(NewRunnableFunction(
     701             :                                      &ContentParent::JoinProcessesIOThread,
     702           0 :                                      &processes, &monitor, &done));
     703             :   {
     704           0 :     MonitorAutoLock lock(monitor);
     705           0 :     while (!done) {
     706           0 :       lock.Wait();
     707             :     }
     708             :   }
     709             : 
     710           0 :   sCanLaunchSubprocesses = false;
     711             : }
     712             : 
     713             : /*static*/ uint32_t
     714           2 : ContentParent::GetPoolSize(const nsAString& aContentProcessType)
     715             : {
     716           2 :   if (!sBrowserContentParents) {
     717           0 :     return 0;
     718             :   }
     719             : 
     720             :   nsTArray<ContentParent*>* parents =
     721           2 :     sBrowserContentParents->Get(aContentProcessType);
     722             : 
     723           2 :   return parents ? parents->Length() : 0;
     724             : }
     725             : 
     726             : 
     727             : /*static*/ nsTArray<ContentParent*>&
     728           1 : ContentParent::GetOrCreatePool(const nsAString& aContentProcessType)
     729             : {
     730           1 :   if (!sBrowserContentParents) {
     731           1 :     sBrowserContentParents =
     732           1 :       new nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>;
     733             :   }
     734             : 
     735           1 :   return *sBrowserContentParents->LookupOrAdd(aContentProcessType);
     736             : }
     737             : 
     738             : /*static*/ uint32_t
     739           3 : ContentParent::GetMaxProcessCount(const nsAString& aContentProcessType)
     740             : {
     741           3 :   if (aContentProcessType.EqualsLiteral("web")) {
     742           3 :     return GetMaxWebProcessCount();
     743             :   }
     744             : 
     745           0 :   nsAutoCString processCountPref("dom.ipc.processCount.");
     746           0 :   processCountPref.Append(NS_ConvertUTF16toUTF8(aContentProcessType));
     747             : 
     748             :   int32_t maxContentParents;
     749           0 :   if (NS_FAILED(Preferences::GetInt(processCountPref.get(), &maxContentParents))) {
     750           0 :     maxContentParents = Preferences::GetInt("dom.ipc.processCount", 1);
     751             :   }
     752             : 
     753           0 :   if (maxContentParents < 1) {
     754           0 :     maxContentParents = 1;
     755             :   }
     756             : 
     757           0 :   return static_cast<uint32_t>(maxContentParents);
     758             : }
     759             : 
     760             : /*static*/ bool
     761           2 : ContentParent::IsMaxProcessCountReached(const nsAString& aContentProcessType)
     762             : {
     763           2 :   return GetPoolSize(aContentProcessType) >= GetMaxProcessCount(aContentProcessType);
     764             : }
     765             : 
     766             : /*static*/ void
     767           0 : ContentParent::ReleaseCachedProcesses()
     768             : {
     769           0 :   if (!GetPoolSize(NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE))) {
     770           0 :     return;
     771             :   }
     772             : 
     773             :   // We might want to extend this for other process types as well in the future...
     774           0 :   nsTArray<ContentParent*>& contentParents = GetOrCreatePool(NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE));
     775           0 :   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
     776           0 :   nsTArray<ContentParent*> toRelease;
     777             : 
     778             :   // Shuting down these processes will change the array so let's use another array for the removal.
     779           0 :   for (auto* cp : contentParents) {
     780           0 :     nsTArray<TabId> tabIds = cpm->GetTabParentsByProcessId(cp->mChildID);
     781           0 :     if (!tabIds.Length()) {
     782           0 :       toRelease.AppendElement(cp);
     783             :     }
     784             :   }
     785             : 
     786           0 :   for (auto* cp : toRelease) {
     787             :     // Start a soft shutdown.
     788           0 :     cp->ShutDownProcess(SEND_SHUTDOWN_MESSAGE);
     789             :     // Make sure we don't select this process for new tabs.
     790           0 :     cp->MarkAsDead();
     791             :     // Make sure that this process is no longer accessible from JS by its message manager.
     792           0 :     cp->ShutDownMessageManager();
     793             :   }
     794             : }
     795             : 
     796             : /*static*/ already_AddRefed<ContentParent>
     797           0 : ContentParent::MinTabSelect(const nsTArray<ContentParent*>& aContentParents,
     798             :                             ContentParent* aOpener, int32_t aMaxContentParents)
     799             : {
     800           0 :   uint32_t maxSelectable = std::min(static_cast<uint32_t>(aContentParents.Length()),
     801           0 :                                     static_cast<uint32_t>(aMaxContentParents));
     802           0 :   uint32_t min = INT_MAX;
     803           0 :   RefPtr<ContentParent> candidate;
     804           0 :   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
     805             : 
     806           0 :   for (uint32_t i = 0; i < maxSelectable; i++) {
     807           0 :     ContentParent* p = aContentParents[i];
     808           0 :     NS_ASSERTION(p->IsAlive(), "Non-alive contentparent in sBrowserContentParents?");
     809           0 :     if (p->mOpener == aOpener) {
     810           0 :       uint32_t tabCount = cpm->GetTabParentCountByProcessId(p->ChildID());
     811           0 :       if (tabCount < min) {
     812           0 :         candidate = p;
     813           0 :         min = tabCount;
     814             :       }
     815             :     }
     816             :   }
     817             : 
     818           0 :   return candidate.forget();
     819             : }
     820             : 
     821             : /*static*/ already_AddRefed<ContentParent>
     822           1 : ContentParent::GetNewOrUsedBrowserProcess(const nsAString& aRemoteType,
     823             :                                           ProcessPriority aPriority,
     824             :                                           ContentParent* aOpener)
     825             : {
     826           1 :   nsTArray<ContentParent*>& contentParents = GetOrCreatePool(aRemoteType);
     827           1 :   uint32_t maxContentParents = GetMaxProcessCount(aRemoteType);
     828             : 
     829           1 :   if (aRemoteType.EqualsLiteral(LARGE_ALLOCATION_REMOTE_TYPE)) {
     830             :     // We never want to re-use Large-Allocation processes.
     831           0 :     if (contentParents.Length() >= maxContentParents) {
     832           0 :       return GetNewOrUsedBrowserProcess(NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE),
     833             :                                         aPriority,
     834           0 :                                         aOpener);
     835             :     }
     836             :   } else {
     837           2 :     nsTArray<nsIContentProcessInfo*> infos(contentParents.Length());
     838           1 :     for (auto* cp : contentParents) {
     839           0 :       infos.AppendElement(cp->mScriptableHelper);
     840             :     }
     841             : 
     842             :     nsCOMPtr<nsIContentProcessProvider> cpp =
     843           2 :       do_GetService("@mozilla.org/ipc/processselector;1");
     844           1 :     nsIContentProcessInfo* openerInfo = aOpener ? aOpener->mScriptableHelper.get() : nullptr;
     845             :     int32_t index;
     846           2 :     if (cpp &&
     847           2 :         NS_SUCCEEDED(cpp->ProvideProcess(aRemoteType, openerInfo,
     848             :                                          infos.Elements(), infos.Length(),
     849             :                                          maxContentParents, &index))) {
     850             :       // If the provider returned an existing ContentParent, use that one.
     851           1 :       if (0 <= index && static_cast<uint32_t>(index) <= maxContentParents) {
     852           0 :         RefPtr<ContentParent> retval = contentParents[index];
     853           0 :         return retval.forget();
     854             :       }
     855             :     } else {
     856             :       // If there was a problem with the JS chooser, fall back to a random
     857             :       // selection.
     858           0 :       NS_WARNING("nsIContentProcessProvider failed to return a process");
     859           0 :       RefPtr<ContentParent> random;
     860           0 :       if (contentParents.Length() >= maxContentParents &&
     861           0 :           (random = MinTabSelect(contentParents, aOpener, maxContentParents))) {
     862           0 :         return random.forget();
     863             :       }
     864             :     }
     865             : 
     866             :     // Try to take the preallocated process only for the default process type.
     867             :     // The preallocated process manager might not had the chance yet to release the process
     868             :     // after a very recent ShutDownProcess, let's make sure we don't try to reuse a process
     869             :     // that is being shut down.
     870           2 :     RefPtr<ContentParent> p;
     871           5 :     if (aRemoteType.EqualsLiteral(DEFAULT_REMOTE_TYPE) &&
     872           5 :         (p = PreallocatedProcessManager::Take()) &&
     873           0 :         !p->mShutdownPending) {
     874             :       // For pre-allocated process we have not set the opener yet.
     875           0 :       p->mOpener = aOpener;
     876           0 :       contentParents.AppendElement(p);
     877           0 :       p->mActivateTS = TimeStamp::Now();
     878           0 :       return p.forget();
     879             :     }
     880             :   }
     881             : 
     882             :   // Create a new process from scratch.
     883           2 :   RefPtr<ContentParent> p = new ContentParent(aOpener, aRemoteType);
     884             : 
     885             :   // Until the new process is ready let's not allow to start up any preallocated processes.
     886           1 :   PreallocatedProcessManager::AddBlocker(p);
     887             : 
     888           1 :   if (!p->LaunchSubprocess(aPriority)) {
     889           0 :     return nullptr;
     890             :   }
     891             : 
     892           1 :   p->Init();
     893             : 
     894           1 :   contentParents.AppendElement(p);
     895           1 :   p->mActivateTS = TimeStamp::Now();
     896           1 :   return p.forget();
     897             : }
     898             : 
     899             : /*static*/ already_AddRefed<ContentParent>
     900           0 : ContentParent::GetNewOrUsedJSPluginProcess(uint32_t aPluginID,
     901             :                                            const hal::ProcessPriority& aPriority)
     902             : {
     903           0 :   RefPtr<ContentParent> p;
     904           0 :   if (sJSPluginContentParents) {
     905           0 :     p = sJSPluginContentParents->Get(aPluginID);
     906             :   } else {
     907           0 :     sJSPluginContentParents =
     908           0 :       new nsDataHashtable<nsUint32HashKey, ContentParent*>();
     909             :   }
     910             : 
     911           0 :   if (p) {
     912           0 :     return p.forget();
     913             :   }
     914             : 
     915           0 :   p = new ContentParent(aPluginID);
     916             : 
     917           0 :   if (!p->LaunchSubprocess(aPriority)) {
     918           0 :     return nullptr;
     919             :   }
     920             : 
     921           0 :   p->Init();
     922             : 
     923           0 :   sJSPluginContentParents->Put(aPluginID, p);
     924             : 
     925           0 :   return p.forget();
     926             : }
     927             : 
     928             : /*static*/ ProcessPriority
     929           1 : ContentParent::GetInitialProcessPriority(Element* aFrameElement)
     930             : {
     931             :   // Frames with mozapptype == critical which are expecting a system message
     932             :   // get FOREGROUND_HIGH priority.
     933             : 
     934           1 :   if (!aFrameElement) {
     935           0 :     return PROCESS_PRIORITY_FOREGROUND;
     936             :   }
     937             : 
     938           2 :   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(aFrameElement);
     939           1 :   if (!browserFrame) {
     940           1 :     return PROCESS_PRIORITY_FOREGROUND;
     941             :   }
     942             : 
     943           0 :   return PROCESS_PRIORITY_FOREGROUND;
     944             : }
     945             : 
     946             : #if defined(XP_WIN)
     947             : extern const wchar_t* kPluginWidgetContentParentProperty;
     948             : 
     949             : /*static*/ void
     950             : ContentParent::SendAsyncUpdate(nsIWidget* aWidget)
     951             : {
     952             :   if (!aWidget || aWidget->Destroyed()) {
     953             :     return;
     954             :   }
     955             :   // Fire off an async request to the plugin to paint its window
     956             :   HWND hwnd = (HWND)aWidget->GetNativeData(NS_NATIVE_WINDOW);
     957             :   NS_ASSERTION(hwnd, "Expected valid hwnd value.");
     958             :   ContentParent* cp = reinterpret_cast<ContentParent*>(
     959             :     ::GetPropW(hwnd, kPluginWidgetContentParentProperty));
     960             :   if (cp && !cp->IsDestroyed()) {
     961             :     Unused << cp->SendUpdateWindow((uintptr_t)hwnd);
     962             :   }
     963             : }
     964             : #endif // defined(XP_WIN)
     965             : 
     966             : mozilla::ipc::IPCResult
     967           0 : ContentParent::RecvCreateChildProcess(const IPCTabContext& aContext,
     968             :                                       const hal::ProcessPriority& aPriority,
     969             :                                       const TabId& aOpenerTabId,
     970             :                                       const TabId& aTabId,
     971             :                                       ContentParentId* aCpId,
     972             :                                       bool* aIsForBrowser)
     973             : {
     974             : #if 0
     975             :   if (!CanOpenBrowser(aContext)) {
     976             :       return false;
     977             :   }
     978             : #endif
     979           0 :   RefPtr<ContentParent> cp;
     980           0 :   MaybeInvalidTabContext tc(aContext);
     981           0 :   if (!tc.IsValid()) {
     982           0 :     NS_ERROR(nsPrintfCString("Received an invalid TabContext from "
     983             :                              "the child process. (%s)",
     984             :                              tc.GetInvalidReason()).get());
     985           0 :     return IPC_FAIL_NO_REASON(this);
     986             :   }
     987             : 
     988           0 :   if (tc.GetTabContext().IsJSPlugin()) {
     989           0 :     cp = GetNewOrUsedJSPluginProcess(tc.GetTabContext().JSPluginId(),
     990           0 :                                      aPriority);
     991             :   }
     992             :   else {
     993           0 :     cp = GetNewOrUsedBrowserProcess(NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE),
     994           0 :                                     aPriority, this);
     995             :   }
     996             : 
     997           0 :   if (!cp) {
     998           0 :     *aCpId = 0;
     999           0 :     *aIsForBrowser = false;
    1000           0 :     return IPC_OK();
    1001             :   }
    1002             : 
    1003           0 :   *aCpId = cp->ChildID();
    1004           0 :   *aIsForBrowser = cp->IsForBrowser();
    1005             : 
    1006           0 :   ContentProcessManager *cpm = ContentProcessManager::GetSingleton();
    1007           0 :   if (cp->IsForJSPlugin()) {
    1008             :     // We group all the iframes for a specific JS plugin into one process, regardless of
    1009             :     // origin. As a consequence that process can't be a child of the content process that
    1010             :     // contains the document with the element loading the plugin. All content processes
    1011             :     // need to be able to communicate with the process for the JS plugin.
    1012           0 :     cpm->RegisterRemoteFrame(aTabId, ChildID(), aOpenerTabId, aContext, cp->ChildID());
    1013           0 :     return IPC_OK();
    1014             :   }
    1015             : 
    1016             :   // cp was already added to the ContentProcessManager, this just sets the parent ID.
    1017           0 :   cpm->AddContentProcess(cp, this->ChildID());
    1018             : 
    1019           0 :   if (cpm->AddGrandchildProcess(this->ChildID(), cp->ChildID()) &&
    1020           0 :       cpm->RegisterRemoteFrame(aTabId, ChildID(), aOpenerTabId, aContext, cp->ChildID())) {
    1021           0 :     return IPC_OK();
    1022             :   }
    1023             : 
    1024           0 :   return IPC_FAIL_NO_REASON(this);
    1025             : }
    1026             : 
    1027             : mozilla::ipc::IPCResult
    1028           0 : ContentParent::RecvBridgeToChildProcess(const ContentParentId& aCpId,
    1029             :                                         Endpoint<PContentBridgeParent>* aEndpoint)
    1030             : {
    1031           0 :   ContentProcessManager *cpm = ContentProcessManager::GetSingleton();
    1032           0 :   ContentParent* cp = cpm->GetContentProcessById(aCpId);
    1033             : 
    1034           0 :   if (cp && cp->CanCommunicateWith(ChildID())) {
    1035           0 :     Endpoint<PContentBridgeParent> parent;
    1036           0 :     Endpoint<PContentBridgeChild> child;
    1037             : 
    1038           0 :     if (NS_FAILED(PContentBridge::CreateEndpoints(OtherPid(), cp->OtherPid(),
    1039             :                                                   &parent, &child))) {
    1040           0 :       return IPC_FAIL(this, "CreateEndpoints failed");
    1041             :     }
    1042             : 
    1043           0 :     *aEndpoint = Move(parent);
    1044             : 
    1045           0 :     if (!cp->SendInitContentBridgeChild(Move(child))) {
    1046           0 :       return IPC_FAIL(this, "SendInitContentBridgeChild failed");
    1047             :     }
    1048             : 
    1049           0 :     return IPC_OK();
    1050             :   }
    1051             : 
    1052             :   // You can't bridge to a process you didn't open!
    1053           0 :   KillHard("BridgeToChildProcess");
    1054           0 :   return IPC_FAIL_NO_REASON(this);
    1055             : }
    1056             : 
    1057           1 : static nsIDocShell* GetOpenerDocShellHelper(Element* aFrameElement)
    1058             : {
    1059             :   // Propagate the private-browsing status of the element's parent
    1060             :   // docshell to the remote docshell, via the chrome flags.
    1061           2 :   nsCOMPtr<Element> frameElement = do_QueryInterface(aFrameElement);
    1062           1 :   MOZ_ASSERT(frameElement);
    1063           1 :   nsPIDOMWindowOuter* win = frameElement->OwnerDoc()->GetWindow();
    1064           1 :   if (!win) {
    1065           0 :     NS_WARNING("Remote frame has no window");
    1066           0 :     return nullptr;
    1067             :   }
    1068           1 :   nsIDocShell* docShell = win->GetDocShell();
    1069           1 :   if (!docShell) {
    1070           0 :     NS_WARNING("Remote frame has no docshell");
    1071           0 :     return nullptr;
    1072             :   }
    1073             : 
    1074           1 :   return docShell;
    1075             : }
    1076             : 
    1077             : mozilla::ipc::IPCResult
    1078           0 : ContentParent::RecvCreateGMPService()
    1079             : {
    1080           0 :   Endpoint<PGMPServiceParent> parent;
    1081           0 :   Endpoint<PGMPServiceChild> child;
    1082             : 
    1083             :   nsresult rv;
    1084           0 :   rv = PGMPService::CreateEndpoints(base::GetCurrentProcId(),
    1085           0 :                                     OtherPid(),
    1086           0 :                                     &parent, &child);
    1087           0 :   if (NS_FAILED(rv)) {
    1088           0 :     MOZ_ASSERT(false, "CreateEndpoints failed");
    1089             :     return IPC_FAIL_NO_REASON(this);
    1090             :   }
    1091             : 
    1092           0 :   if (!GMPServiceParent::Create(Move(parent))) {
    1093           0 :     MOZ_ASSERT(false, "GMPServiceParent::Create failed");
    1094             :     return IPC_FAIL_NO_REASON(this);
    1095             :   }
    1096             : 
    1097           0 :   if (!SendInitGMPService(Move(child))) {
    1098           0 :     MOZ_ASSERT(false, "SendInitGMPService failed");
    1099             :     return IPC_FAIL_NO_REASON(this);
    1100             :   }
    1101             : 
    1102           0 :   return IPC_OK();
    1103             : }
    1104             : 
    1105             : mozilla::ipc::IPCResult
    1106           0 : ContentParent::RecvLoadPlugin(const uint32_t& aPluginId,
    1107             :                               nsresult* aRv,
    1108             :                               uint32_t* aRunID,
    1109             :                               Endpoint<PPluginModuleParent>* aEndpoint)
    1110             : {
    1111           0 :   *aRv = NS_OK;
    1112           0 :   if (!mozilla::plugins::SetupBridge(aPluginId, this, aRv, aRunID, aEndpoint)) {
    1113           0 :     return IPC_FAIL_NO_REASON(this);
    1114             :   }
    1115           0 :   return IPC_OK();
    1116             : }
    1117             : 
    1118             : mozilla::ipc::IPCResult
    1119           0 : ContentParent::RecvUngrabPointer(const uint32_t& aTime)
    1120             : {
    1121             : #if !defined(MOZ_WIDGET_GTK)
    1122             :   NS_RUNTIMEABORT("This message only makes sense on GTK platforms");
    1123             :   return IPC_OK();
    1124             : #else
    1125           0 :   gdk_pointer_ungrab(aTime);
    1126           0 :   return IPC_OK();
    1127             : #endif
    1128             : }
    1129             : 
    1130             : mozilla::ipc::IPCResult
    1131           0 : ContentParent::RecvRemovePermission(const IPC::Principal& aPrincipal,
    1132             :                                     const nsCString& aPermissionType,
    1133             :                                     nsresult* aRv) {
    1134           0 :   *aRv = Permissions::RemovePermission(aPrincipal, aPermissionType.get());
    1135           0 :   return IPC_OK();
    1136             : }
    1137             : 
    1138             : mozilla::ipc::IPCResult
    1139           0 : ContentParent::RecvConnectPluginBridge(const uint32_t& aPluginId,
    1140             :                                        nsresult* aRv,
    1141             :                                        Endpoint<PPluginModuleParent>* aEndpoint)
    1142             : {
    1143           0 :   *aRv = NS_OK;
    1144             :   // We don't need to get the run ID for the plugin, since we already got it
    1145             :   // in the first call to SetupBridge in RecvLoadPlugin, so we pass in a dummy
    1146             :   // pointer and just throw it away.
    1147           0 :   uint32_t dummy = 0;
    1148           0 :   if (!mozilla::plugins::SetupBridge(aPluginId, this, aRv, &dummy, aEndpoint)) {
    1149           0 :     return IPC_FAIL(this, "SetupBridge failed");
    1150             :   }
    1151           0 :   return IPC_OK();
    1152             : }
    1153             : 
    1154             : mozilla::ipc::IPCResult
    1155           0 : ContentParent::RecvGetBlocklistState(const uint32_t& aPluginId,
    1156             :                                      uint32_t* aState)
    1157             : {
    1158           0 :   *aState = nsIBlocklistService::STATE_BLOCKED;
    1159             : 
    1160           0 :   RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
    1161           0 :   if (!pluginHost) {
    1162           0 :     NS_WARNING("Plugin host not found");
    1163           0 :     return IPC_FAIL_NO_REASON(this);
    1164             :   }
    1165           0 :   nsPluginTag* tag =  pluginHost->PluginWithId(aPluginId);
    1166             : 
    1167           0 :   if (!tag) {
    1168             :     // Default state is blocked anyway
    1169           0 :     NS_WARNING("Plugin tag not found. This should never happen, but to avoid a crash we're forcibly blocking it");
    1170           0 :     return IPC_OK();
    1171             :   }
    1172             : 
    1173           0 :   if (NS_FAILED(tag->GetBlocklistState(aState))) {
    1174           0 :     return IPC_FAIL_NO_REASON(this);
    1175             :   }
    1176           0 :   return IPC_OK();
    1177             : }
    1178             : 
    1179             : /*static*/ TabParent*
    1180           1 : ContentParent::CreateBrowser(const TabContext& aContext,
    1181             :                              Element* aFrameElement,
    1182             :                              ContentParent* aOpenerContentParent,
    1183             :                              TabParent* aSameTabGroupAs,
    1184             :                              uint64_t aNextTabParentId)
    1185             : {
    1186           2 :   AUTO_PROFILER_LABEL("ContentParent::CreateBrowser", OTHER);
    1187             : 
    1188           1 :   if (!sCanLaunchSubprocesses) {
    1189           0 :     return nullptr;
    1190             :   }
    1191             : 
    1192           1 :   if (aNextTabParentId) {
    1193           0 :     if (TabParent* parent =
    1194           0 :           sNextTabParents.GetAndRemove(aNextTabParentId).valueOr(nullptr)) {
    1195           0 :       MOZ_ASSERT(!parent->GetOwnerElement(),
    1196             :                  "Shouldn't have an owner elemnt before");
    1197           0 :       parent->SetOwnerElement(aFrameElement);
    1198           0 :       return parent;
    1199             :     }
    1200             :   }
    1201             : 
    1202           1 :   ProcessPriority initialPriority = GetInitialProcessPriority(aFrameElement);
    1203           1 :   bool isInContentProcess = !XRE_IsParentProcess();
    1204           1 :   TabId tabId(nsContentUtils::GenerateTabId());
    1205             : 
    1206           1 :   nsIDocShell* docShell = GetOpenerDocShellHelper(aFrameElement);
    1207           1 :   TabId openerTabId;
    1208           1 :   if (docShell) {
    1209           1 :     openerTabId = TabParent::GetTabIdFrom(docShell);
    1210             :   }
    1211             : 
    1212           2 :   nsAutoString remoteType;
    1213           1 :   if (!aFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::RemoteType,
    1214             :                               remoteType)) {
    1215           0 :     remoteType.AssignLiteral(DEFAULT_REMOTE_TYPE);
    1216             :   }
    1217             : 
    1218           2 :   RefPtr<nsIContentParent> constructorSender;
    1219           1 :   if (isInContentProcess) {
    1220           0 :     MOZ_ASSERT(aContext.IsMozBrowserElement() || aContext.IsJSPlugin());
    1221           0 :     constructorSender = CreateContentBridgeParent(aContext, initialPriority,
    1222           0 :                                                   openerTabId, tabId);
    1223             :   } else {
    1224           1 :     if (aOpenerContentParent) {
    1225           0 :       constructorSender = aOpenerContentParent;
    1226             :     } else {
    1227           1 :       if (aContext.IsJSPlugin()) {
    1228             :         constructorSender =
    1229           0 :           GetNewOrUsedJSPluginProcess(aContext.JSPluginId(),
    1230           0 :                                       initialPriority);
    1231             :       } else {
    1232             :         constructorSender =
    1233           1 :           GetNewOrUsedBrowserProcess(remoteType, initialPriority, nullptr);
    1234             :       }
    1235           1 :       if (!constructorSender) {
    1236           0 :         return nullptr;
    1237             :       }
    1238             :     }
    1239           1 :     ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
    1240             :     cpm->RegisterRemoteFrame(tabId,
    1241           2 :                              ContentParentId(0),
    1242             :                              openerTabId,
    1243           2 :                              aContext.AsIPCTabContext(),
    1244           3 :                              constructorSender->ChildID());
    1245             :   }
    1246           1 :   if (constructorSender) {
    1247           1 :     nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
    1248           1 :     docShell->GetTreeOwner(getter_AddRefs(treeOwner));
    1249           1 :     if (!treeOwner) {
    1250           0 :       return nullptr;
    1251             :     }
    1252             : 
    1253           1 :     nsCOMPtr<nsIWebBrowserChrome> wbc = do_GetInterface(treeOwner);
    1254           1 :     if (!wbc) {
    1255           0 :       return nullptr;
    1256             :     }
    1257           1 :     uint32_t chromeFlags = 0;
    1258           1 :     wbc->GetChromeFlags(&chromeFlags);
    1259             : 
    1260           1 :     nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
    1261           1 :     if (loadContext && loadContext->UsePrivateBrowsing()) {
    1262           0 :       chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
    1263             :     }
    1264           1 :     if (docShell->GetAffectPrivateSessionLifetime()) {
    1265           1 :       chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME;
    1266             :     }
    1267             : 
    1268           1 :     if (tabId == 0) {
    1269           0 :       return nullptr;
    1270             :     }
    1271             :     RefPtr<TabParent> tp(new TabParent(constructorSender, tabId,
    1272           2 :                                        aContext, chromeFlags));
    1273           1 :     tp->SetInitedByParent();
    1274             : 
    1275             :     PBrowserParent* browser =
    1276           1 :     constructorSender->SendPBrowserConstructor(
    1277             :       // DeallocPBrowserParent() releases this ref.
    1278           2 :       tp.forget().take(), tabId,
    1279           2 :       aSameTabGroupAs ? aSameTabGroupAs->GetTabId() : TabId(0),
    1280           2 :       aContext.AsIPCTabContext(),
    1281             :       chromeFlags,
    1282           2 :       constructorSender->ChildID(),
    1283           3 :       constructorSender->IsForBrowser());
    1284             : 
    1285           1 :     if (remoteType.EqualsLiteral(LARGE_ALLOCATION_REMOTE_TYPE)) {
    1286             :       // Tell the TabChild object that it was created due to a Large-Allocation
    1287             :       // request.
    1288           0 :       Unused << browser->SendAwaitLargeAlloc();
    1289             :     }
    1290             : 
    1291           1 :     if (browser) {
    1292           2 :       RefPtr<TabParent> constructedTabParent = TabParent::GetFrom(browser);
    1293           1 :       constructedTabParent->SetOwnerElement(aFrameElement);
    1294           1 :       return constructedTabParent;
    1295             :     }
    1296             :   }
    1297           0 :   return nullptr;
    1298             : }
    1299             : 
    1300             : /*static*/ ContentBridgeParent*
    1301           0 : ContentParent::CreateContentBridgeParent(const TabContext& aContext,
    1302             :                                          const hal::ProcessPriority& aPriority,
    1303             :                                          const TabId& aOpenerTabId,
    1304             :                                          const TabId& aTabId)
    1305             : {
    1306           0 :   MOZ_ASSERT(aTabId);
    1307             : 
    1308           0 :   ContentChild* child = ContentChild::GetSingleton();
    1309           0 :   ContentParentId cpId;
    1310             :   bool isForBrowser;
    1311           0 :   if (!child->SendCreateChildProcess(aContext.AsIPCTabContext(),
    1312             :                                      aPriority,
    1313             :                                      aOpenerTabId,
    1314             :                                      aTabId,
    1315             :                                      &cpId,
    1316             :                                      &isForBrowser)) {
    1317           0 :     return nullptr;
    1318             :   }
    1319           0 :   if (cpId == 0) {
    1320           0 :     return nullptr;
    1321             :   }
    1322           0 :   Endpoint<PContentBridgeParent> endpoint;
    1323           0 :   if (!child->SendBridgeToChildProcess(cpId, &endpoint)) {
    1324           0 :     return nullptr;
    1325             :   }
    1326           0 :   ContentBridgeParent* parent = ContentBridgeParent::Create(Move(endpoint));
    1327           0 :   parent->SetChildID(cpId);
    1328           0 :   parent->SetIsForBrowser(isForBrowser);
    1329           0 :   parent->SetIsForJSPlugin(aContext.IsJSPlugin());
    1330           0 :   return parent;
    1331             : }
    1332             : 
    1333             : void
    1334         109 : ContentParent::GetAll(nsTArray<ContentParent*>& aArray)
    1335             : {
    1336         109 :   aArray.Clear();
    1337             : 
    1338         113 :   for (auto* cp : AllProcesses(eLive)) {
    1339           4 :     aArray.AppendElement(cp);
    1340             :   }
    1341         109 : }
    1342             : 
    1343             : void
    1344           0 : ContentParent::GetAllEvenIfDead(nsTArray<ContentParent*>& aArray)
    1345             : {
    1346           0 :   aArray.Clear();
    1347             : 
    1348           0 :   for (auto* cp : AllProcesses(eAll)) {
    1349           0 :     aArray.AppendElement(cp);
    1350             :   }
    1351           0 : }
    1352             : 
    1353             : const nsAString&
    1354           3 : ContentParent::GetRemoteType() const
    1355             : {
    1356           3 :   return mRemoteType;
    1357             : }
    1358             : 
    1359             : void
    1360           2 : ContentParent::Init()
    1361             : {
    1362           4 :   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
    1363           2 :   if (obs) {
    1364           2 :     size_t length = ArrayLength(sObserverTopics);
    1365          32 :     for (size_t i = 0; i < length; ++i) {
    1366          30 :       obs->AddObserver(this, sObserverTopics[i], false);
    1367             :     }
    1368             :   }
    1369           2 :   Preferences::AddStrongObserver(this, "");
    1370           2 :   if (obs) {
    1371           4 :     nsAutoString cpId;
    1372           2 :     cpId.AppendInt(static_cast<uint64_t>(this->ChildID()));
    1373           2 :     obs->NotifyObservers(static_cast<nsIObserver*>(this), "ipc:content-created", cpId.get());
    1374             :   }
    1375             : 
    1376             : #ifdef ACCESSIBILITY
    1377             :   // If accessibility is running in chrome process then start it in content
    1378             :   // process.
    1379           2 :   if (nsIPresShell::IsAccessibilityActive()) {
    1380             : #if defined(XP_WIN)
    1381             : #if defined(RELEASE_OR_BETA)
    1382             :     // On Windows we currently only enable a11y in the content process
    1383             :     // for testing purposes.
    1384             :     if (Preferences::GetBool(kForceEnableE10sPref, false))
    1385             : #endif
    1386             :       Unused << SendActivateA11y(::GetCurrentThreadId(),
    1387             :                                  a11y::AccessibleWrap::GetContentProcessIdFor(ChildID()));
    1388             : #else
    1389           0 :     Unused << SendActivateA11y(0, 0);
    1390             : #endif
    1391             :   }
    1392             : #endif
    1393             : 
    1394             : #ifdef MOZ_GECKO_PROFILER
    1395           2 :   Unused << SendInitProfiler(ProfilerParent::CreateForProcess(OtherPid()));
    1396             : #endif
    1397             : 
    1398             :   // Ensure that the default set of permissions are avaliable in the content
    1399             :   // process before we try to load any URIs in it.
    1400           2 :   EnsurePermissionsByKey(EmptyCString());
    1401             : 
    1402           4 :   RefPtr<GeckoMediaPluginServiceParent> gmps(GeckoMediaPluginServiceParent::GetSingleton());
    1403           2 :   gmps->UpdateContentProcessGMPCapabilities();
    1404             : 
    1405           2 :   mScriptableHelper = new ScriptableCPInfo(this);
    1406           2 : }
    1407             : 
    1408             : namespace {
    1409             : 
    1410             : class RemoteWindowContext final : public nsIRemoteWindowContext
    1411             :                                 , public nsIInterfaceRequestor
    1412             : {
    1413             : public:
    1414           0 :   explicit RemoteWindowContext(TabParent* aTabParent)
    1415           0 :   : mTabParent(aTabParent)
    1416             :   {
    1417           0 :   }
    1418             : 
    1419             :   NS_DECL_ISUPPORTS
    1420             :   NS_DECL_NSIINTERFACEREQUESTOR
    1421             :   NS_DECL_NSIREMOTEWINDOWCONTEXT
    1422             : 
    1423             : private:
    1424             :   ~RemoteWindowContext();
    1425             :   RefPtr<TabParent> mTabParent;
    1426             : };
    1427             : 
    1428           0 : NS_IMPL_ISUPPORTS(RemoteWindowContext, nsIRemoteWindowContext, nsIInterfaceRequestor)
    1429             : 
    1430           0 : RemoteWindowContext::~RemoteWindowContext()
    1431             : {
    1432           0 : }
    1433             : 
    1434             : NS_IMETHODIMP
    1435           0 : RemoteWindowContext::GetInterface(const nsIID& aIID, void** aSink)
    1436             : {
    1437           0 :   return QueryInterface(aIID, aSink);
    1438             : }
    1439             : 
    1440             : NS_IMETHODIMP
    1441           0 : RemoteWindowContext::OpenURI(nsIURI* aURI)
    1442             : {
    1443           0 :   mTabParent->LoadURL(aURI);
    1444           0 :   return NS_OK;
    1445             : }
    1446             : 
    1447             : } // namespace
    1448             : 
    1449             : void
    1450           0 : ContentParent::ShutDownProcess(ShutDownMethod aMethod)
    1451             : {
    1452           0 :   if (mScriptableHelper) {
    1453           0 :     static_cast<ScriptableCPInfo*>(mScriptableHelper.get())->ProcessDied();
    1454           0 :     mScriptableHelper = nullptr;
    1455             :   }
    1456             : 
    1457             :   // Shutting down by sending a shutdown message works differently than the
    1458             :   // other methods. We first call Shutdown() in the child. After the child is
    1459             :   // ready, it calls FinishShutdown() on us. Then we close the channel.
    1460           0 :   if (aMethod == SEND_SHUTDOWN_MESSAGE) {
    1461           0 :     if (mIPCOpen && !mShutdownPending && SendShutdown()) {
    1462           0 :       mShutdownPending = true;
    1463             :       // Start the force-kill timer if we haven't already.
    1464           0 :       StartForceKillTimer();
    1465             :     }
    1466             : 
    1467             :     // If call was not successful, the channel must have been broken
    1468             :     // somehow, and we will clean up the error in ActorDestroy.
    1469           0 :     return;
    1470             :   }
    1471             : 
    1472             :   using mozilla::dom::quota::QuotaManagerService;
    1473             : 
    1474           0 :   if (QuotaManagerService* quotaManagerService = QuotaManagerService::Get()) {
    1475           0 :     quotaManagerService->AbortOperationsForProcess(mChildID);
    1476             :   }
    1477             : 
    1478             :   // If Close() fails with an error, we'll end up back in this function, but
    1479             :   // with aMethod = CLOSE_CHANNEL_WITH_ERROR.
    1480             : 
    1481           0 :   if (aMethod == CLOSE_CHANNEL && !mCalledClose) {
    1482             :     // Close() can only be called once: It kicks off the destruction
    1483             :     // sequence.
    1484           0 :     mCalledClose = true;
    1485           0 :     Close();
    1486             :   }
    1487             : 
    1488             :   const ManagedContainer<POfflineCacheUpdateParent>& ocuParents =
    1489           0 :     ManagedPOfflineCacheUpdateParent();
    1490           0 :   for (auto iter = ocuParents.ConstIter(); !iter.Done(); iter.Next()) {
    1491             :     RefPtr<mozilla::docshell::OfflineCacheUpdateParent> ocuParent =
    1492           0 :       static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(iter.Get()->GetKey());
    1493           0 :     ocuParent->StopSendingMessagesToChild();
    1494             :   }
    1495             : 
    1496             :   // NB: must MarkAsDead() here so that this isn't accidentally
    1497             :   // returned from Get*() while in the midst of shutdown.
    1498           0 :   MarkAsDead();
    1499             : 
    1500             :   // A ContentParent object might not get freed until after XPCOM shutdown has
    1501             :   // shut down the cycle collector.  But by then it's too late to release any
    1502             :   // CC'ed objects, so we need to null them out here, while we still can.  See
    1503             :   // bug 899761.
    1504           0 :   ShutDownMessageManager();
    1505             : }
    1506             : 
    1507             : mozilla::ipc::IPCResult
    1508           0 : ContentParent::RecvFinishShutdown()
    1509             : {
    1510             :   // At this point, we already called ShutDownProcess once with
    1511             :   // SEND_SHUTDOWN_MESSAGE. To actually close the channel, we call
    1512             :   // ShutDownProcess again with CLOSE_CHANNEL.
    1513           0 :   MOZ_ASSERT(mShutdownPending);
    1514           0 :   ShutDownProcess(CLOSE_CHANNEL);
    1515           0 :   return IPC_OK();
    1516             : }
    1517             : 
    1518             : void
    1519           0 : ContentParent::ShutDownMessageManager()
    1520             : {
    1521           0 :   if (!mMessageManager) {
    1522           0 :   return;
    1523             :   }
    1524             : 
    1525           0 :   mMessageManager->ReceiveMessage(
    1526           0 :       static_cast<nsIContentFrameMessageManager*>(mMessageManager.get()), nullptr,
    1527           0 :       CHILD_PROCESS_SHUTDOWN_MESSAGE, false,
    1528           0 :       nullptr, nullptr, nullptr, nullptr);
    1529             : 
    1530           0 :   mMessageManager->Disconnect();
    1531           0 :   mMessageManager = nullptr;
    1532             : }
    1533             : 
    1534             : void
    1535           0 : ContentParent::RemoveFromList()
    1536             : {
    1537           0 :   if (IsForJSPlugin()) {
    1538           0 :     if (sJSPluginContentParents) {
    1539           0 :       sJSPluginContentParents->Remove(mJSPluginID);
    1540           0 :       if (!sJSPluginContentParents->Count()) {
    1541           0 :         delete sJSPluginContentParents;
    1542           0 :         sJSPluginContentParents = nullptr;
    1543             :       }
    1544             :     }
    1545           0 :   } else if (sBrowserContentParents) {
    1546           0 :     if (auto entry = sBrowserContentParents->Lookup(mRemoteType)) {
    1547           0 :       nsTArray<ContentParent*>* contentParents = entry.Data();
    1548           0 :       contentParents->RemoveElement(this);
    1549           0 :       if (contentParents->IsEmpty()) {
    1550           0 :         entry.Remove();
    1551             :       }
    1552             :     }
    1553           0 :     if (sBrowserContentParents->IsEmpty()) {
    1554           0 :       delete sBrowserContentParents;
    1555           0 :       sBrowserContentParents = nullptr;
    1556             :     }
    1557             :   }
    1558             : 
    1559           0 :   if (sPrivateContent) {
    1560           0 :     sPrivateContent->RemoveElement(this);
    1561           0 :     if (!sPrivateContent->Length()) {
    1562           0 :       delete sPrivateContent;
    1563           0 :       sPrivateContent = nullptr;
    1564             :     }
    1565             :   }
    1566           0 : }
    1567             : 
    1568             : void
    1569           0 : ContentParent::MarkAsTroubled()
    1570             : {
    1571           0 :   RemoveFromList();
    1572           0 :   mIsAvailable = false;
    1573           0 : }
    1574             : 
    1575             : void
    1576           0 : ContentParent::MarkAsDead()
    1577             : {
    1578           0 :   MarkAsTroubled();
    1579           0 :   mIsAlive = false;
    1580           0 : }
    1581             : 
    1582             : void
    1583           0 : ContentParent::OnChannelError()
    1584             : {
    1585           0 :   RefPtr<ContentParent> content(this);
    1586           0 :   PContentParent::OnChannelError();
    1587           0 : }
    1588             : 
    1589             : void
    1590           0 : ContentParent::OnChannelConnected(int32_t pid)
    1591             : {
    1592           0 :   SetOtherProcessId(pid);
    1593             : 
    1594             : #if defined(ANDROID) || defined(LINUX)
    1595             :   // Check nice preference
    1596           0 :   int32_t nice = Preferences::GetInt("dom.ipc.content.nice", 0);
    1597             : 
    1598             :   // Environment variable overrides preference
    1599           0 :   char* relativeNicenessStr = getenv("MOZ_CHILD_PROCESS_RELATIVE_NICENESS");
    1600           0 :   if (relativeNicenessStr) {
    1601           0 :     nice = atoi(relativeNicenessStr);
    1602             :   }
    1603             : 
    1604             :   /* make the GUI thread have higher priority on single-cpu devices */
    1605           0 :   nsCOMPtr<nsIPropertyBag2> infoService = do_GetService(NS_SYSTEMINFO_CONTRACTID);
    1606           0 :   if (infoService) {
    1607             :     int32_t cpus;
    1608           0 :     nsresult rv = infoService->GetPropertyAsInt32(NS_LITERAL_STRING("cpucount"), &cpus);
    1609           0 :     if (NS_FAILED(rv)) {
    1610           0 :       cpus = 1;
    1611             :     }
    1612           0 :     if (nice != 0 && cpus == 1) {
    1613           0 :       setpriority(PRIO_PROCESS, pid, getpriority(PRIO_PROCESS, pid) + nice);
    1614             :     }
    1615             :   }
    1616             : #endif
    1617           0 : }
    1618             : 
    1619             : void
    1620           0 : ContentParent::ProcessingError(Result aCode, const char* aReason)
    1621             : {
    1622           0 :   if (MsgDropped == aCode) {
    1623           0 :     return;
    1624             :   }
    1625             :   // Other errors are big deals.
    1626           0 :   KillHard(aReason);
    1627             : }
    1628             : 
    1629             : /* static */
    1630             : bool
    1631           0 : ContentParent::AllocateLayerTreeId(TabParent* aTabParent, uint64_t* aId)
    1632             : {
    1633           0 :   return AllocateLayerTreeId(aTabParent->Manager()->AsContentParent(),
    1634           0 :                              aTabParent, aTabParent->GetTabId(), aId);
    1635             : }
    1636             : 
    1637             : /* static */
    1638             : bool
    1639           0 : ContentParent::AllocateLayerTreeId(ContentParent* aContent,
    1640             :                                    TabParent* aTopLevel, const TabId& aTabId,
    1641             :                                    uint64_t* aId)
    1642             : {
    1643           0 :   GPUProcessManager* gpu = GPUProcessManager::Get();
    1644             : 
    1645           0 :   *aId = gpu->AllocateLayerTreeId();
    1646             : 
    1647           0 :   if (!aContent || !aTopLevel) {
    1648           0 :     return false;
    1649             :   }
    1650             : 
    1651           0 :   gpu->MapLayerTreeId(*aId, aContent->OtherPid());
    1652             : 
    1653           0 :   return true;
    1654             : }
    1655             : 
    1656             : mozilla::ipc::IPCResult
    1657           0 : ContentParent::RecvAllocateLayerTreeId(const ContentParentId& aCpId,
    1658             :                                        const TabId& aTabId, uint64_t* aId)
    1659             : {
    1660             :   // Protect against spoofing by a compromised child. aCpId must either
    1661             :   // correspond to the process that this ContentParent represents or be a
    1662             :   // child of it.
    1663           0 :   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
    1664           0 :   RefPtr<ContentParent> contentParent = cpm->GetContentProcessById(aCpId);
    1665           0 :   if (ChildID() != aCpId && !contentParent->CanCommunicateWith(ChildID())) {
    1666           0 :     return IPC_FAIL_NO_REASON(this);
    1667             :   }
    1668             : 
    1669             :   // GetTopLevelTabParentByProcessAndTabId will make sure that aTabId
    1670             :   // lives in the process for aCpId.
    1671             :   RefPtr<TabParent> browserParent =
    1672           0 :     cpm->GetTopLevelTabParentByProcessAndTabId(aCpId, aTabId);
    1673           0 :   MOZ_ASSERT(contentParent && browserParent);
    1674             : 
    1675           0 :   if (!AllocateLayerTreeId(contentParent, browserParent, aTabId, aId)) {
    1676           0 :     return IPC_FAIL_NO_REASON(this);
    1677             :   }
    1678           0 :   return IPC_OK();
    1679             : }
    1680             : 
    1681             : mozilla::ipc::IPCResult
    1682           0 : ContentParent::RecvDeallocateLayerTreeId(const ContentParentId& aCpId,
    1683             :                                          const uint64_t& aId)
    1684             : {
    1685           0 :   GPUProcessManager* gpu = GPUProcessManager::Get();
    1686             : 
    1687           0 :   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
    1688           0 :   RefPtr<ContentParent> contentParent = cpm->GetContentProcessById(aCpId);
    1689           0 :   if (!contentParent->CanCommunicateWith(ChildID())) {
    1690           0 :     return IPC_FAIL(this, "Spoofed DeallocateLayerTreeId call");
    1691             :   }
    1692             : 
    1693           0 :   if (!gpu->IsLayerTreeIdMapped(aId, contentParent->OtherPid())) {
    1694             :     // You can't deallocate layer tree ids that you didn't allocate
    1695           0 :     KillHard("DeallocateLayerTreeId");
    1696             :   }
    1697             : 
    1698           0 :   gpu->UnmapLayerTreeId(aId, contentParent->OtherPid());
    1699             : 
    1700           0 :   return IPC_OK();
    1701             : }
    1702             : 
    1703             : namespace {
    1704             : 
    1705             : void
    1706           0 : DelayedDeleteSubprocess(GeckoChildProcessHost* aSubprocess)
    1707             : {
    1708           0 :   RefPtr<DeleteTask<GeckoChildProcessHost>> task = new DeleteTask<GeckoChildProcessHost>(aSubprocess);
    1709           0 :   XRE_GetIOMessageLoop()->PostTask(task.forget());
    1710           0 : }
    1711             : 
    1712             : // This runnable only exists to delegate ownership of the
    1713             : // ContentParent to this runnable, until it's deleted by the event
    1714             : // system.
    1715           0 : struct DelayedDeleteContentParentTask : public Runnable
    1716             : {
    1717           0 :   explicit DelayedDeleteContentParentTask(ContentParent* aObj)
    1718           0 :     : Runnable("dom::DelayedDeleteContentParentTask")
    1719           0 :     , mObj(aObj)
    1720             :   {
    1721           0 :   }
    1722             : 
    1723             :   // No-op
    1724           0 :   NS_IMETHOD Run() override { return NS_OK; }
    1725             : 
    1726             :   RefPtr<ContentParent> mObj;
    1727             : };
    1728             : 
    1729             : } // namespace
    1730             : 
    1731             : void
    1732           0 : ContentParent::ActorDestroy(ActorDestroyReason why)
    1733             : {
    1734           0 :   if (mForceKillTimer) {
    1735           0 :     mForceKillTimer->Cancel();
    1736           0 :     mForceKillTimer = nullptr;
    1737             :   }
    1738             : 
    1739             :   // Signal shutdown completion regardless of error state, so we can
    1740             :   // finish waiting in the xpcom-shutdown/profile-before-change observer.
    1741           0 :   mIPCOpen = false;
    1742             : 
    1743           0 :   if (mHangMonitorActor) {
    1744           0 :     ProcessHangMonitor::RemoveProcess(mHangMonitorActor);
    1745           0 :     mHangMonitorActor = nullptr;
    1746             :   }
    1747             : 
    1748           0 :   RefPtr<FileSystemSecurity> fss = FileSystemSecurity::Get();
    1749           0 :   if (fss) {
    1750           0 :     fss->Forget(ChildID());
    1751             :   }
    1752             : 
    1753           0 :   if (why == NormalShutdown && !mCalledClose) {
    1754             :     // If we shut down normally but haven't called Close, assume somebody
    1755             :     // else called Close on us. In that case, we still need to call
    1756             :     // ShutDownProcess below to perform other necessary clean up.
    1757           0 :     mCalledClose = true;
    1758             :   }
    1759             : 
    1760             :   // Make sure we always clean up.
    1761           0 :   ShutDownProcess(why == NormalShutdown ? CLOSE_CHANNEL
    1762           0 :                                         : CLOSE_CHANNEL_WITH_ERROR);
    1763             : 
    1764           0 :   RefPtr<ContentParent> kungFuDeathGrip(this);
    1765           0 :   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
    1766           0 :   if (obs) {
    1767           0 :     size_t length = ArrayLength(sObserverTopics);
    1768           0 :     for (size_t i = 0; i < length; ++i) {
    1769           0 :       obs->RemoveObserver(static_cast<nsIObserver*>(this),
    1770           0 :                           sObserverTopics[i]);
    1771             :     }
    1772             :   }
    1773             : 
    1774             :   // remove the global remote preferences observers
    1775           0 :   Preferences::RemoveObserver(this, "");
    1776           0 :   gfxVars::RemoveReceiver(this);
    1777             : 
    1778           0 :   if (GPUProcessManager* gpu = GPUProcessManager::Get()) {
    1779             :     // Note: the manager could have shutdown already.
    1780           0 :     gpu->RemoveListener(this);
    1781             :   }
    1782             : 
    1783           0 :   RecvRemoveGeolocationListener();
    1784             : 
    1785           0 :   mConsoleService = nullptr;
    1786             : 
    1787           0 :   if (obs) {
    1788           0 :     RefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
    1789             : 
    1790           0 :     props->SetPropertyAsUint64(NS_LITERAL_STRING("childID"), mChildID);
    1791             : 
    1792           0 :     if (AbnormalShutdown == why) {
    1793           0 :       Telemetry::Accumulate(Telemetry::SUBPROCESS_ABNORMAL_ABORT,
    1794           0 :                             NS_LITERAL_CSTRING("content"), 1);
    1795             : 
    1796           0 :       props->SetPropertyAsBool(NS_LITERAL_STRING("abnormal"), true);
    1797             : 
    1798             : #ifdef MOZ_CRASHREPORTER
    1799             :       // There's a window in which child processes can crash
    1800             :       // after IPC is established, but before a crash reporter
    1801             :       // is created.
    1802           0 :       if (mCrashReporter) {
    1803             :         // if mCreatedPairedMinidumps is true, we've already generated
    1804             :         // parent/child dumps for desktop crashes.
    1805           0 :         if (!mCreatedPairedMinidumps) {
    1806           0 :           mCrashReporter->GenerateCrashReport(OtherPid());
    1807             :         }
    1808             : 
    1809           0 :         nsAutoString dumpID;
    1810           0 :         if (mCrashReporter->HasMinidump()) {
    1811           0 :           dumpID = mCrashReporter->MinidumpID();
    1812             :         }
    1813           0 :         props->SetPropertyAsAString(NS_LITERAL_STRING("dumpID"), dumpID);
    1814             :       }
    1815             : #endif
    1816             :     }
    1817           0 :     nsAutoString cpId;
    1818           0 :     cpId.AppendInt(static_cast<uint64_t>(this->ChildID()));
    1819           0 :     obs->NotifyObservers((nsIPropertyBag2*) props, "ipc:content-shutdown", cpId.get());
    1820             :   }
    1821             : 
    1822             :   // Remove any and all idle listeners.
    1823             :   nsCOMPtr<nsIIdleService> idleService =
    1824           0 :     do_GetService("@mozilla.org/widget/idleservice;1");
    1825           0 :   MOZ_ASSERT(idleService);
    1826           0 :   RefPtr<ParentIdleListener> listener;
    1827           0 :   for (int32_t i = mIdleListeners.Length() - 1; i >= 0; --i) {
    1828           0 :     listener = static_cast<ParentIdleListener*>(mIdleListeners[i].get());
    1829           0 :     idleService->RemoveIdleObserver(listener, listener->mTime);
    1830             :   }
    1831           0 :   mIdleListeners.Clear();
    1832             : 
    1833             :   MessageLoop::current()->
    1834           0 :     PostTask(NewRunnableFunction(DelayedDeleteSubprocess, mSubprocess));
    1835           0 :   mSubprocess = nullptr;
    1836             : 
    1837             :   // IPDL rules require actors to live on past ActorDestroy, but it
    1838             :   // may be that the kungFuDeathGrip above is the last reference to
    1839             :   // |this|.  If so, when we go out of scope here, we're deleted and
    1840             :   // all hell breaks loose.
    1841             :   //
    1842             :   // This runnable ensures that a reference to |this| lives on at
    1843             :   // least until after the current task finishes running.
    1844           0 :   NS_DispatchToCurrentThread(new DelayedDeleteContentParentTask(this));
    1845             : 
    1846           0 :   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
    1847             :   nsTArray<ContentParentId> childIDArray =
    1848           0 :     cpm->GetAllChildProcessById(this->ChildID());
    1849             : 
    1850             :   // Destroy any processes created by this ContentParent
    1851           0 :   for(uint32_t i = 0; i < childIDArray.Length(); i++) {
    1852           0 :     ContentParent* cp = cpm->GetContentProcessById(childIDArray[i]);
    1853           0 :     MessageLoop::current()->PostTask(
    1854           0 :       NewRunnableMethod<ShutDownMethod>("dom::ContentParent::ShutDownProcess",
    1855             :                                         cp,
    1856             :                                         &ContentParent::ShutDownProcess,
    1857           0 :                                         SEND_SHUTDOWN_MESSAGE));
    1858             :   }
    1859           0 :   cpm->RemoveContentProcess(this->ChildID());
    1860             : 
    1861           0 :   if (mDriverCrashGuard) {
    1862           0 :     mDriverCrashGuard->NotifyCrashed();
    1863             :   }
    1864             : 
    1865             :   // Unregister all the BlobURLs registered by the ContentChild.
    1866           0 :   for (uint32_t i = 0; i < mBlobURLs.Length(); ++i) {
    1867           0 :     nsHostObjectProtocolHandler::RemoveDataEntry(mBlobURLs[i]);
    1868             :   }
    1869             : 
    1870           0 :   mBlobURLs.Clear();
    1871             : 
    1872             : #if defined(XP_WIN32) && defined(ACCESSIBILITY)
    1873             :   a11y::AccessibleWrap::ReleaseContentProcessIdFor(ChildID());
    1874             : #endif
    1875           0 : }
    1876             : 
    1877             : bool
    1878           0 : ContentParent::TryToRecycle()
    1879             : {
    1880             :   // This life time check should be replaced by a memory health check (memory usage + fragmentation).
    1881           0 :   const double kMaxLifeSpan = 5;
    1882           0 :   if (mShutdownPending ||
    1883           0 :       mCalledKillHard ||
    1884           0 :       !IsAvailable() ||
    1885           0 :       !mRemoteType.EqualsLiteral(DEFAULT_REMOTE_TYPE) ||
    1886           0 :       (TimeStamp::Now() - mActivateTS).ToSeconds() > kMaxLifeSpan ||
    1887           0 :       !PreallocatedProcessManager::Provide(this)) {
    1888           0 :     return false;
    1889             :   }
    1890             : 
    1891             :   // The PreallocatedProcessManager took over the ownership let's not keep a reference to it,
    1892             :   // until we don't take it back.
    1893           0 :   RemoveFromList();
    1894           0 :   return true;
    1895             : }
    1896             : 
    1897             : bool
    1898           0 : ContentParent::ShouldKeepProcessAlive() const
    1899             : {
    1900           0 :   if (IsForJSPlugin()) {
    1901           0 :     return true;
    1902             :   }
    1903             : 
    1904           0 :   if (!sBrowserContentParents) {
    1905           0 :     return false;
    1906             :   }
    1907             : 
    1908             :   // If we have already been marked as troubled/dead, don't prevent shutdown.
    1909           0 :   if (!IsAvailable()) {
    1910           0 :     return false;
    1911             :   }
    1912             : 
    1913           0 :   auto contentParents = sBrowserContentParents->Get(mRemoteType);
    1914           0 :   if (!contentParents) {
    1915           0 :     return false;
    1916             :   }
    1917             : 
    1918             :   // We might want to keep alive some content processes alive during test runs,
    1919             :   // for performance reasons. This should never be used in production.
    1920             :   // We don't want to alter behavior if the pref is not set, so default to 0.
    1921           0 :   int32_t processesToKeepAlive = 0;
    1922             : 
    1923           0 :   nsAutoCString keepAlivePref("dom.ipc.keepProcessesAlive.");
    1924           0 :   keepAlivePref.Append(NS_ConvertUTF16toUTF8(mRemoteType));
    1925           0 :   if (NS_FAILED(Preferences::GetInt(keepAlivePref.get(), &processesToKeepAlive))) {
    1926           0 :     return false;
    1927             :   }
    1928             : 
    1929           0 :   int32_t numberOfAliveProcesses = contentParents->Length();
    1930             : 
    1931           0 :   return numberOfAliveProcesses <= processesToKeepAlive;
    1932             : }
    1933             : 
    1934             : void
    1935           0 : ContentParent::NotifyTabDestroying(const TabId& aTabId,
    1936             :                                    const ContentParentId& aCpId)
    1937             : {
    1938           0 :   if (XRE_IsParentProcess()) {
    1939             :     // There can be more than one PBrowser for a given app process
    1940             :     // because of popup windows.  PBrowsers can also destroy
    1941             :     // concurrently.  When all the PBrowsers are destroying, kick off
    1942             :     // another task to ensure the child process *really* shuts down,
    1943             :     // even if the PBrowsers themselves never finish destroying.
    1944           0 :     ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
    1945           0 :     ContentParent* cp = cpm->GetContentProcessById(aCpId);
    1946           0 :     if (!cp) {
    1947           0 :         return;
    1948             :     }
    1949           0 :     ++cp->mNumDestroyingTabs;
    1950           0 :     nsTArray<TabId> tabIds = cpm->GetTabParentsByProcessId(aCpId);
    1951           0 :     if (static_cast<size_t>(cp->mNumDestroyingTabs) != tabIds.Length()) {
    1952           0 :         return;
    1953             :     }
    1954             : 
    1955           0 :     if (cp->ShouldKeepProcessAlive()) {
    1956           0 :       return;
    1957             :     }
    1958             : 
    1959           0 :     if (cp->TryToRecycle()) {
    1960           0 :       return;
    1961             :     }
    1962             : 
    1963             :     // We're dying now, so prevent this content process from being
    1964             :     // recycled during its shutdown procedure.
    1965           0 :     cp->MarkAsDead();
    1966           0 :     cp->StartForceKillTimer();
    1967             :   } else {
    1968           0 :     ContentChild::GetSingleton()->SendNotifyTabDestroying(aTabId, aCpId);
    1969             :   }
    1970             : }
    1971             : 
    1972             : void
    1973           0 : ContentParent::StartForceKillTimer()
    1974             : {
    1975           0 :   if (mForceKillTimer || !mIPCOpen) {
    1976           0 :     return;
    1977             :   }
    1978             : 
    1979           0 :   int32_t timeoutSecs = Preferences::GetInt("dom.ipc.tabs.shutdownTimeoutSecs", 5);
    1980           0 :   if (timeoutSecs > 0) {
    1981           0 :     mForceKillTimer = do_CreateInstance("@mozilla.org/timer;1");
    1982           0 :     MOZ_ASSERT(mForceKillTimer);
    1983           0 :     mForceKillTimer->InitWithNamedFuncCallback(
    1984             :       ContentParent::ForceKillTimerCallback,
    1985             :       this,
    1986           0 :       timeoutSecs * 1000,
    1987             :       nsITimer::TYPE_ONE_SHOT,
    1988           0 :       "dom::ContentParent::StartForceKillTimer");
    1989             :   }
    1990             : }
    1991             : 
    1992             : void
    1993           0 : ContentParent::NotifyTabDestroyed(const TabId& aTabId,
    1994             :                                   bool aNotifiedDestroying)
    1995             : {
    1996           0 :   if (aNotifiedDestroying) {
    1997           0 :     --mNumDestroyingTabs;
    1998             :   }
    1999             : 
    2000             :   nsTArray<PContentPermissionRequestParent*> parentArray =
    2001           0 :     nsContentPermissionUtils::GetContentPermissionRequestParentById(aTabId);
    2002             : 
    2003             :   // Need to close undeleted ContentPermissionRequestParents before tab is closed.
    2004           0 :   for (auto& permissionRequestParent : parentArray) {
    2005           0 :     Unused << PContentPermissionRequestParent::Send__delete__(permissionRequestParent);
    2006             :   }
    2007             : 
    2008             :   // There can be more than one PBrowser for a given app process
    2009             :   // because of popup windows.  When the last one closes, shut
    2010             :   // us down.
    2011           0 :   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
    2012           0 :   nsTArray<TabId> tabIds = cpm->GetTabParentsByProcessId(this->ChildID());
    2013             : 
    2014           0 :   if (tabIds.Length() == 1 && !ShouldKeepProcessAlive() && !TryToRecycle()) {
    2015             :     // In the case of normal shutdown, send a shutdown message to child to
    2016             :     // allow it to perform shutdown tasks.
    2017           0 :     MessageLoop::current()->PostTask(
    2018           0 :       NewRunnableMethod<ShutDownMethod>("dom::ContentParent::ShutDownProcess",
    2019             :                                         this,
    2020             :                                         &ContentParent::ShutDownProcess,
    2021           0 :                                         SEND_SHUTDOWN_MESSAGE));
    2022             :   }
    2023           0 : }
    2024             : 
    2025             : jsipc::CPOWManager*
    2026          21 : ContentParent::GetCPOWManager()
    2027             : {
    2028          21 :   if (PJavaScriptParent* p = LoneManagedOrNullAsserts(ManagedPJavaScriptParent())) {
    2029          20 :     return CPOWManagerFor(p);
    2030             :   }
    2031           1 :   return nullptr;
    2032             : }
    2033             : 
    2034             : TestShellParent*
    2035           0 : ContentParent::CreateTestShell()
    2036             : {
    2037           0 :   return static_cast<TestShellParent*>(SendPTestShellConstructor());
    2038             : }
    2039             : 
    2040             : bool
    2041           0 : ContentParent::DestroyTestShell(TestShellParent* aTestShell)
    2042             : {
    2043           0 :   return PTestShellParent::Send__delete__(aTestShell);
    2044             : }
    2045             : 
    2046             : TestShellParent*
    2047           0 : ContentParent::GetTestShellSingleton()
    2048             : {
    2049           0 :   PTestShellParent* p = LoneManagedOrNullAsserts(ManagedPTestShellParent());
    2050           0 :   return static_cast<TestShellParent*>(p);
    2051             : }
    2052             : 
    2053             : bool
    2054           2 : ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PRIORITY_FOREGROUND */)
    2055             : {
    2056           4 :   AUTO_PROFILER_LABEL("ContentParent::LaunchSubprocess", OTHER);
    2057             : 
    2058           4 :   std::vector<std::string> extraArgs;
    2059           2 :   extraArgs.push_back("-childID");
    2060             :   char idStr[21];
    2061           2 :   SprintfLiteral(idStr, "%" PRId64, static_cast<uint64_t>(mChildID));
    2062           2 :   extraArgs.push_back(idStr);
    2063           2 :   extraArgs.push_back(IsForBrowser() ? "-isForBrowser" : "-notForBrowser");
    2064             : 
    2065             :   char boolBuf[1024];
    2066             :   char intBuf[1024];
    2067             :   char strBuf[1024];
    2068           4 :   nsFixedCString boolPrefs(boolBuf, 1024, 0);
    2069           4 :   nsFixedCString intPrefs(intBuf, 1024, 0);
    2070           4 :   nsFixedCString stringPrefs(strBuf, 1024, 0);
    2071             : 
    2072             :   size_t prefsLen;
    2073           2 :   ContentPrefs::GetContentPrefs(&prefsLen);
    2074             : 
    2075         436 :   for (unsigned int i = 0; i < prefsLen; i++) {
    2076         434 :     MOZ_ASSERT(i == 0 || strcmp(ContentPrefs::GetContentPref(i), ContentPrefs::GetContentPref(i - 1)) > 0);
    2077         434 :     switch (Preferences::GetType(ContentPrefs::GetContentPref(i))) {
    2078             :     case nsIPrefBranch::PREF_INT:
    2079          68 :       intPrefs.Append(nsPrintfCString("%u:%d|", i, Preferences::GetInt(ContentPrefs::GetContentPref(i))));
    2080          68 :       break;
    2081             :     case nsIPrefBranch::PREF_BOOL:
    2082         184 :       boolPrefs.Append(nsPrintfCString("%u:%d|", i, Preferences::GetBool(ContentPrefs::GetContentPref(i))));
    2083         184 :       break;
    2084             :     case nsIPrefBranch::PREF_STRING: {
    2085          16 :       nsAdoptingCString value(Preferences::GetCString(ContentPrefs::GetContentPref(i)));
    2086           8 :       stringPrefs.Append(nsPrintfCString("%u:%d;%s|", i, value.Length(), value.get()));
    2087             : 
    2088             :     }
    2089           8 :       break;
    2090             :     case nsIPrefBranch::PREF_INVALID:
    2091         174 :       break;
    2092             :     default:
    2093           0 :       printf("preference type: %x\n", Preferences::GetType(ContentPrefs::GetContentPref(i)));
    2094           0 :       MOZ_CRASH();
    2095             :     }
    2096             :   }
    2097             : 
    2098           2 :   extraArgs.push_back("-intPrefs");
    2099           2 :   extraArgs.push_back(intPrefs.get());
    2100           2 :   extraArgs.push_back("-boolPrefs");
    2101           2 :   extraArgs.push_back(boolPrefs.get());
    2102           2 :   extraArgs.push_back("-stringPrefs");
    2103           2 :   extraArgs.push_back(stringPrefs.get());
    2104             : 
    2105           2 :   if (gSafeMode) {
    2106           0 :     extraArgs.push_back("-safeMode");
    2107             :   }
    2108             : 
    2109           2 :   if (!mSubprocess->LaunchAndWaitForProcessHandle(extraArgs)) {
    2110           0 :     MarkAsDead();
    2111           0 :     return false;
    2112             :   }
    2113             : 
    2114           2 :   base::ProcessId procId = base::GetProcId(mSubprocess->GetChildProcessHandle());
    2115             : 
    2116           2 :   Open(mSubprocess->GetChannel(), procId);
    2117             : 
    2118             : #ifdef MOZ_CODE_COVERAGE
    2119           2 :   Unused << SendShareCodeCoverageMutex(CodeCoverageHandler::Get()->GetMutexHandle(procId));
    2120             : #endif
    2121             : 
    2122             :   InitInternal(aInitialPriority,
    2123             :                true, /* Setup off-main thread compositing */
    2124           2 :                true  /* Send registered chrome */);
    2125             : 
    2126           2 :   ContentProcessManager::GetSingleton()->AddContentProcess(this);
    2127             : 
    2128           2 :   mHangMonitorActor = ProcessHangMonitor::AddProcess(this);
    2129             : 
    2130             :   // Set a reply timeout for CPOWs.
    2131           2 :   SetReplyTimeoutMs(Preferences::GetInt("dom.ipc.cpow.timeout", 0));
    2132             : 
    2133           2 :   Telemetry::Accumulate(Telemetry::CONTENT_PROCESS_LAUNCH_TIME_MS,
    2134           4 :                         static_cast<uint32_t>((TimeStamp::Now() - mLaunchTS)
    2135           4 :                                               .ToMilliseconds()));
    2136             : 
    2137           4 :   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
    2138           2 :   if (obs) {
    2139           4 :     nsAutoString cpId;
    2140           2 :     cpId.AppendInt(static_cast<uint64_t>(this->ChildID()));
    2141           2 :     obs->NotifyObservers(static_cast<nsIObserver*>(this), "ipc:content-initializing", cpId.get());
    2142             :   }
    2143             : 
    2144           2 :   return true;
    2145             : }
    2146             : 
    2147           2 : ContentParent::ContentParent(ContentParent* aOpener,
    2148             :                              const nsAString& aRemoteType,
    2149           2 :                              int32_t aJSPluginID)
    2150             :   : nsIContentParent()
    2151             :   , mSubprocess(nullptr)
    2152             :   , mLaunchTS(TimeStamp::Now())
    2153             :   , mActivateTS(TimeStamp::Now())
    2154             :   , mOpener(aOpener)
    2155             :   , mRemoteType(aRemoteType)
    2156             :   , mChildID(gContentChildID++)
    2157             :   , mGeolocationWatchID(-1)
    2158             :   , mJSPluginID(aJSPluginID)
    2159             :   , mNumDestroyingTabs(0)
    2160             :   , mIsAvailable(true)
    2161             :   , mIsAlive(true)
    2162           2 :   , mIsForBrowser(!mRemoteType.IsEmpty())
    2163             :   , mCalledClose(false)
    2164             :   , mCalledKillHard(false)
    2165             :   , mCreatedPairedMinidumps(false)
    2166             :   , mShutdownPending(false)
    2167             :   , mIPCOpen(true)
    2168           4 :   , mHangMonitorActor(nullptr)
    2169             : {
    2170             :   // Insert ourselves into the global linked list of ContentParent objects.
    2171           2 :   if (!sContentParents) {
    2172           1 :     sContentParents = new LinkedList<ContentParent>();
    2173             :   }
    2174           2 :   sContentParents->insertBack(this);
    2175             : 
    2176             :   // From this point on, NS_WARNING, NS_ASSERTION, etc. should print out the
    2177             :   // PID along with the warning.
    2178           2 :   nsDebugImpl::SetMultiprocessMode("Parent");
    2179             : 
    2180             : #if defined(XP_WIN) && !defined(MOZ_B2G)
    2181             :   // Request Windows message deferral behavior on our side of the PContent
    2182             :   // channel. Generally only applies to the situation where we get caught in
    2183             :   // a deadlock with the plugin process when sending CPOWs.
    2184             :   GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION);
    2185             : #endif
    2186             : 
    2187           2 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
    2188           2 :   ChildPrivileges privs = mRemoteType.EqualsLiteral(FILE_REMOTE_TYPE)
    2189           2 :                           ? base::PRIVILEGES_FILEREAD
    2190           2 :                           : base::PRIVILEGES_DEFAULT;
    2191           2 :   mSubprocess = new GeckoChildProcessHost(GeckoProcessType_Content, privs);
    2192           2 : }
    2193             : 
    2194           0 : ContentParent::~ContentParent()
    2195             : {
    2196           0 :   if (mForceKillTimer) {
    2197           0 :     mForceKillTimer->Cancel();
    2198             :   }
    2199             : 
    2200           0 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
    2201             : 
    2202             :   // We should be removed from all these lists in ActorDestroy.
    2203           0 :   MOZ_ASSERT(!sPrivateContent || !sPrivateContent->Contains(this));
    2204           0 :   if (IsForJSPlugin()) {
    2205           0 :     MOZ_ASSERT(!sJSPluginContentParents ||
    2206             :                !sJSPluginContentParents->Get(mJSPluginID));
    2207             :   } else {
    2208           0 :     MOZ_ASSERT(!sBrowserContentParents ||
    2209             :                !sBrowserContentParents->Contains(mRemoteType) ||
    2210             :                !sBrowserContentParents->Get(mRemoteType)->Contains(this));
    2211             :   }
    2212           0 : }
    2213             : 
    2214             : void
    2215           2 : ContentParent::InitInternal(ProcessPriority aInitialPriority,
    2216             :                             bool aSetupOffMainThreadCompositing,
    2217             :                             bool aSendRegisteredChrome)
    2218             : {
    2219           2 :   Telemetry::Accumulate(Telemetry::CONTENT_PROCESS_LAUNCH_TIME_MS,
    2220           4 :                         static_cast<uint32_t>((TimeStamp::Now() - mLaunchTS)
    2221           4 :                                               .ToMilliseconds()));
    2222             : 
    2223           4 :   XPCOMInitData xpcomInit;
    2224             : 
    2225           2 :   Preferences::GetPreferences(&xpcomInit.prefs());
    2226           4 :   nsCOMPtr<nsIIOService> io(do_GetIOService());
    2227           2 :   MOZ_ASSERT(io, "No IO service?");
    2228           4 :   DebugOnly<nsresult> rv = io->GetOffline(&xpcomInit.isOffline());
    2229           2 :   MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed getting offline?");
    2230             : 
    2231           2 :   rv = io->GetConnectivity(&xpcomInit.isConnected());
    2232           2 :   MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed getting connectivity?");
    2233             : 
    2234           2 :   xpcomInit.captivePortalState() = nsICaptivePortalService::UNKNOWN;
    2235           4 :   nsCOMPtr<nsICaptivePortalService> cps = do_GetService(NS_CAPTIVEPORTAL_CONTRACTID);
    2236           2 :   if (cps) {
    2237           2 :     cps->GetState(&xpcomInit.captivePortalState());
    2238             :   }
    2239             : 
    2240           2 :   nsIBidiKeyboard* bidi = nsContentUtils::GetBidiKeyboard();
    2241             : 
    2242           2 :   xpcomInit.isLangRTL() = false;
    2243           2 :   xpcomInit.haveBidiKeyboards() = false;
    2244           2 :   if (bidi) {
    2245           2 :     bidi->IsLangRTL(&xpcomInit.isLangRTL());
    2246           2 :     bidi->GetHaveBidiKeyboards(&xpcomInit.haveBidiKeyboards());
    2247             :   }
    2248             : 
    2249           4 :   nsCOMPtr<nsISpellChecker> spellChecker(do_GetService(NS_SPELLCHECKER_CONTRACTID));
    2250           2 :   MOZ_ASSERT(spellChecker, "No spell checker?");
    2251             : 
    2252           2 :   spellChecker->GetDictionaryList(&xpcomInit.dictionaries());
    2253             : 
    2254           2 :   LocaleService::GetInstance()->GetAppLocalesAsLangTags(xpcomInit.appLocales());
    2255           2 :   LocaleService::GetInstance()->GetRequestedLocales(xpcomInit.requestedLocales());
    2256             : 
    2257           4 :   nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1"));
    2258           2 :   MOZ_ASSERT(clipboard, "No clipboard?");
    2259             : 
    2260           2 :   rv = clipboard->SupportsSelectionClipboard(&xpcomInit.clipboardCaps().supportsSelectionClipboard());
    2261           2 :   MOZ_ASSERT(NS_SUCCEEDED(rv));
    2262             : 
    2263           2 :   rv = clipboard->SupportsFindClipboard(&xpcomInit.clipboardCaps().supportsFindClipboard());
    2264           2 :   MOZ_ASSERT(NS_SUCCEEDED(rv));
    2265             : 
    2266             :   // Let's copy the domain policy from the parent to the child (if it's active).
    2267           4 :   StructuredCloneData initialData;
    2268           2 :   nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
    2269           2 :   if (ssm) {
    2270           2 :     ssm->CloneDomainPolicy(&xpcomInit.domainPolicy());
    2271             : 
    2272           2 :     if (nsFrameMessageManager* mm = nsFrameMessageManager::sParentProcessManager) {
    2273           4 :       AutoJSAPI jsapi;
    2274           2 :       if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
    2275           0 :         MOZ_CRASH();
    2276             :       }
    2277           4 :       JS::RootedValue init(jsapi.cx());
    2278           2 :       nsresult result = mm->GetInitialProcessData(jsapi.cx(), &init);
    2279           2 :       if (NS_FAILED(result)) {
    2280           0 :         MOZ_CRASH();
    2281             :       }
    2282             : 
    2283           4 :       ErrorResult rv;
    2284           2 :       initialData.Write(jsapi.cx(), init, rv);
    2285           2 :       if (NS_WARN_IF(rv.Failed())) {
    2286           0 :         rv.SuppressException();
    2287           0 :         MOZ_CRASH();
    2288             :       }
    2289             :     }
    2290             :   }
    2291             :   // This is only implemented (returns a non-empty list) by MacOSX at present.
    2292           2 :   gfxPlatform::GetPlatform()->GetSystemFontFamilyList(&xpcomInit.fontFamilies());
    2293           4 :   nsTArray<LookAndFeelInt> lnfCache = LookAndFeel::GetIntCache();
    2294             : 
    2295             :   // Content processes have no permission to access profile directory, so we
    2296             :   // send the file URL instead.
    2297           2 :   StyleSheet* ucs = nsLayoutStylesheetCache::For(StyleBackendType::Gecko)->UserContentSheet();
    2298           2 :   if (ucs) {
    2299           0 :     SerializeURI(ucs->GetSheetURI(), xpcomInit.userContentSheetURL());
    2300             :   } else {
    2301           2 :     SerializeURI(nullptr, xpcomInit.userContentSheetURL());
    2302             :   }
    2303             : 
    2304             :   // 1. Build ContentDeviceData first, as it may affect some gfxVars.
    2305           2 :   gfxPlatform::GetPlatform()->BuildContentDeviceData(&xpcomInit.contentDeviceData());
    2306             :   // 2. Gather non-default gfxVars.
    2307           2 :   xpcomInit.gfxNonDefaultVarUpdates() = gfxVars::FetchNonDefaultVars();
    2308             :   // 3. Start listening for gfxVars updates, to notify content process later on.
    2309           2 :   gfxVars::AddReceiver(this);
    2310             : 
    2311           4 :   nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
    2312           2 :   if (gfxInfo) {
    2313          46 :     for (int32_t i = 1; i <= nsIGfxInfo::FEATURE_MAX_VALUE; ++i) {
    2314          44 :       int32_t status = 0;
    2315          88 :       nsAutoCString failureId;
    2316          44 :       gfxInfo->GetFeatureStatus(i, failureId, &status);
    2317          88 :       dom::GfxInfoFeatureStatus gfxFeatureStatus;
    2318          44 :       gfxFeatureStatus.feature() = i;
    2319          44 :       gfxFeatureStatus.status() = status;
    2320          44 :       gfxFeatureStatus.failureId() = failureId;
    2321          44 :       xpcomInit.gfxFeatureStatus().AppendElement(gfxFeatureStatus);
    2322             :     }
    2323             :   }
    2324             : 
    2325           2 :   DataStorage::GetAllChildProcessData(xpcomInit.dataStorage());
    2326             : 
    2327             :   // Must send screen info before send initialData
    2328           2 :   ScreenManager& screenManager = ScreenManager::GetSingleton();
    2329           2 :   screenManager.CopyScreensToRemote(this);
    2330             : 
    2331           2 :   Unused << SendSetXPCOMProcessAttributes(xpcomInit, initialData, lnfCache);
    2332             : 
    2333           2 :   if (aSendRegisteredChrome) {
    2334           4 :     nsCOMPtr<nsIChromeRegistry> registrySvc = nsChromeRegistry::GetService();
    2335             :     nsChromeRegistryChrome* chromeRegistry =
    2336           2 :       static_cast<nsChromeRegistryChrome*>(registrySvc.get());
    2337           2 :     chromeRegistry->SendRegisteredChrome(this);
    2338             :   }
    2339             : 
    2340           2 :   if (gAppData) {
    2341           4 :     nsCString version(gAppData->version);
    2342           4 :     nsCString buildID(gAppData->buildID);
    2343           4 :     nsCString name(gAppData->name);
    2344           4 :     nsCString UAName(gAppData->UAName);
    2345           4 :     nsCString ID(gAppData->ID);
    2346           4 :     nsCString vendor(gAppData->vendor);
    2347             : 
    2348             :     // Sending all information to content process.
    2349           2 :     Unused << SendAppInfo(version, buildID, name, UAName, ID, vendor);
    2350             :   }
    2351             : 
    2352             :   // Send the child its remote type. On Mac, this needs to be sent prior
    2353             :   // to the message we send to enable the Sandbox (SendStartProcessSandbox)
    2354             :   // because different remote types require different sandbox privileges.
    2355           2 :   Unused << SendRemoteType(mRemoteType);
    2356             : 
    2357           2 :   ScriptPreloader::InitContentChild(*this);
    2358             : 
    2359             :   // Initialize the message manager (and load delayed scripts) now that we
    2360             :   // have established communications with the child.
    2361           2 :   mMessageManager->InitWithCallback(this);
    2362             : 
    2363             :   // Set the subprocess's priority.  We do this early on because we're likely
    2364             :   // /lowering/ the process's CPU and memory priority, which it has inherited
    2365             :   // from this process.
    2366             :   //
    2367             :   // This call can cause us to send IPC messages to the child process, so it
    2368             :   // must come after the Open() call above.
    2369           2 :   ProcessPriorityManager::SetProcessPriority(this, aInitialPriority);
    2370             : 
    2371           2 :   if (aSetupOffMainThreadCompositing) {
    2372             :     // NB: internally, this will send an IPC message to the child
    2373             :     // process to get it to create the CompositorBridgeChild.  This
    2374             :     // message goes through the regular IPC queue for this
    2375             :     // channel, so delivery will happen-before any other messages
    2376             :     // we send.  The CompositorBridgeChild must be created before any
    2377             :     // PBrowsers are created, because they rely on the Compositor
    2378             :     // already being around.  (Creation is async, so can't happen
    2379             :     // on demand.)
    2380           2 :     bool useOffMainThreadCompositing = !!CompositorThreadHolder::Loop();
    2381           2 :     if (useOffMainThreadCompositing) {
    2382           2 :       GPUProcessManager* gpm = GPUProcessManager::Get();
    2383             : 
    2384           4 :       Endpoint<PCompositorManagerChild> compositor;
    2385           4 :       Endpoint<PImageBridgeChild> imageBridge;
    2386           4 :       Endpoint<PVRManagerChild> vrBridge;
    2387           4 :       Endpoint<PVideoDecoderManagerChild> videoManager;
    2388           4 :       AutoTArray<uint32_t, 3> namespaces;
    2389             : 
    2390           6 :       DebugOnly<bool> opened = gpm->CreateContentBridges(
    2391           2 :         OtherPid(),
    2392             :         &compositor,
    2393             :         &imageBridge,
    2394             :         &vrBridge,
    2395             :         &videoManager,
    2396           4 :         &namespaces);
    2397           2 :       MOZ_ASSERT(opened);
    2398             : 
    2399           2 :       Unused << SendInitRendering(
    2400           2 :         Move(compositor),
    2401           2 :         Move(imageBridge),
    2402           2 :         Move(vrBridge),
    2403           2 :         Move(videoManager),
    2404             :         namespaces);
    2405             : 
    2406           2 :       gpm->AddListener(this);
    2407             :     }
    2408             :   }
    2409             : 
    2410           2 :   nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
    2411           2 :   if (sheetService) {
    2412             :     // This looks like a lot of work, but in a normal browser session we just
    2413             :     // send two loads.
    2414             :     //
    2415             :     // The URIs of the Gecko and Servo sheets should be the same, so it
    2416             :     // shouldn't matter which we look at.  (The Servo sheets don't exist
    2417             :     // in non-MOZ-STYLO builds, though, so look at the Gecko ones.)
    2418             : 
    2419           6 :     for (StyleSheet* sheet :
    2420           4 :            *sheetService->AgentStyleSheets(StyleBackendType::Gecko)) {
    2421           4 :       URIParams uri;
    2422           2 :       SerializeURI(sheet->GetSheetURI(), uri);
    2423           2 :       Unused << SendLoadAndRegisterSheet(uri, nsIStyleSheetService::AGENT_SHEET);
    2424             :     }
    2425             : 
    2426           2 :     for (StyleSheet* sheet :
    2427           2 :            *sheetService->UserStyleSheets(StyleBackendType::Gecko)) {
    2428           0 :       URIParams uri;
    2429           0 :       SerializeURI(sheet->GetSheetURI(), uri);
    2430           0 :       Unused << SendLoadAndRegisterSheet(uri, nsIStyleSheetService::USER_SHEET);
    2431             :     }
    2432             : 
    2433           2 :     for (StyleSheet* sheet :
    2434           2 :            *sheetService->AuthorStyleSheets(StyleBackendType::Gecko)) {
    2435           0 :       URIParams uri;
    2436           0 :       SerializeURI(sheet->GetSheetURI(), uri);
    2437           0 :       Unused << SendLoadAndRegisterSheet(uri, nsIStyleSheetService::AUTHOR_SHEET);
    2438             :     }
    2439             :   }
    2440             : 
    2441             : #ifdef MOZ_CONTENT_SANDBOX
    2442             :   bool shouldSandbox = true;
    2443             :   MaybeFileDesc brokerFd = void_t();
    2444             :   // XXX: Checking the pref here makes it possible to enable/disable sandboxing
    2445             :   // during an active session. Currently the pref is only used for testing
    2446             :   // purpose. If the decision is made to permanently rely on the pref, this
    2447             :   // should be changed so that it is required to restart firefox for the change
    2448             :   // of value to take effect.
    2449             :   shouldSandbox = (GetEffectiveContentSandboxLevel() > 0) &&
    2450             :     !PR_GetEnv("MOZ_DISABLE_CONTENT_SANDBOX");
    2451             : 
    2452             : #ifdef XP_LINUX
    2453             :   if (shouldSandbox) {
    2454             :     MOZ_ASSERT(!mSandboxBroker);
    2455             :     UniquePtr<SandboxBroker::Policy> policy =
    2456             :       sSandboxBrokerPolicyFactory->GetContentPolicy(Pid());
    2457             :     if (policy) {
    2458             :       brokerFd = FileDescriptor();
    2459             :       mSandboxBroker = SandboxBroker::Create(Move(policy), Pid(), brokerFd);
    2460             :       if (!mSandboxBroker) {
    2461             :         KillHard("SandboxBroker::Create failed");
    2462             :         return;
    2463             :       }
    2464             :       MOZ_ASSERT(static_cast<const FileDescriptor&>(brokerFd).IsValid());
    2465             :     }
    2466             :   }
    2467             : #endif
    2468             :   if (shouldSandbox && !SendSetProcessSandbox(brokerFd)) {
    2469             :     KillHard("SandboxInitFailed");
    2470             :   }
    2471             : #endif
    2472             : #if defined(XP_WIN)
    2473             :   // Send the info needed to join the browser process's audio session.
    2474             :   nsID id;
    2475             :   nsString sessionName;
    2476             :   nsString iconPath;
    2477             :   if (NS_SUCCEEDED(mozilla::widget::GetAudioSessionData(id, sessionName,
    2478             :                                                         iconPath))) {
    2479             :     Unused << SendSetAudioSessionData(id, sessionName, iconPath);
    2480             :   }
    2481             : #endif
    2482             : 
    2483             :   {
    2484           4 :     RefPtr<ServiceWorkerRegistrar> swr = ServiceWorkerRegistrar::Get();
    2485           2 :     MOZ_ASSERT(swr);
    2486             : 
    2487           4 :     nsTArray<ServiceWorkerRegistrationData> registrations;
    2488           2 :     swr->GetRegistrations(registrations);
    2489             : 
    2490             :     // Send down to the content process the permissions for each of the
    2491             :     // registered service worker scopes.
    2492           2 :     for (auto& registration : registrations) {
    2493           0 :       nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(registration.principal());
    2494           0 :       if (principal) {
    2495           0 :         TransmitPermissionsForPrincipal(principal);
    2496             :       }
    2497             :     }
    2498             : 
    2499           2 :     Unused << SendInitServiceWorkers(ServiceWorkerConfiguration(registrations));
    2500             :   }
    2501             : 
    2502             :   {
    2503           4 :     nsTArray<BlobURLRegistrationData> registrations;
    2504           2 :     if (nsHostObjectProtocolHandler::GetAllBlobURLEntries(registrations,
    2505             :                                                           this)) {
    2506           2 :       Unused << SendInitBlobURLs(registrations);
    2507             :     }
    2508             :   }
    2509             : 
    2510             :   // Start up nsPluginHost and run FindPlugins to cache the plugin list.
    2511             :   // If this isn't our first content process, just send over cached list.
    2512           4 :   RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
    2513           2 :   pluginHost->SendPluginsToContent();
    2514           2 : }
    2515             : 
    2516             : bool
    2517           0 : ContentParent::IsAlive() const
    2518             : {
    2519           0 :   return mIsAlive;
    2520             : }
    2521             : 
    2522             : int32_t
    2523           0 : ContentParent::Pid() const
    2524             : {
    2525           0 :   if (!mSubprocess || !mSubprocess->GetChildProcessHandle()) {
    2526           0 :     return -1;
    2527             :   }
    2528           0 :   return base::GetProcId(mSubprocess->GetChildProcessHandle());
    2529             : }
    2530             : 
    2531             : mozilla::ipc::IPCResult
    2532           0 : ContentParent::RecvGetGfxVars(InfallibleTArray<GfxVarUpdate>* aVars)
    2533             : {
    2534             :   // Ensure gfxVars is initialized (for xpcshell tests).
    2535           0 :   gfxVars::Initialize();
    2536             : 
    2537           0 :   *aVars = gfxVars::FetchNonDefaultVars();
    2538             : 
    2539             :   // Now that content has initialized gfxVars, we can start listening for
    2540             :   // updates.
    2541           0 :   gfxVars::AddReceiver(this);
    2542           0 :   return IPC_OK();
    2543             : }
    2544             : 
    2545             : void
    2546           0 : ContentParent::OnCompositorUnexpectedShutdown()
    2547             : {
    2548           0 :   GPUProcessManager* gpm = GPUProcessManager::Get();
    2549             : 
    2550           0 :   Endpoint<PCompositorManagerChild> compositor;
    2551           0 :   Endpoint<PImageBridgeChild> imageBridge;
    2552           0 :   Endpoint<PVRManagerChild> vrBridge;
    2553           0 :   Endpoint<PVideoDecoderManagerChild> videoManager;
    2554           0 :   AutoTArray<uint32_t, 3> namespaces;
    2555             : 
    2556           0 :   DebugOnly<bool> opened = gpm->CreateContentBridges(
    2557           0 :     OtherPid(),
    2558             :     &compositor,
    2559             :     &imageBridge,
    2560             :     &vrBridge,
    2561             :     &videoManager,
    2562           0 :     &namespaces);
    2563           0 :   MOZ_ASSERT(opened);
    2564             : 
    2565           0 :   Unused << SendReinitRendering(
    2566           0 :     Move(compositor),
    2567           0 :     Move(imageBridge),
    2568           0 :     Move(vrBridge),
    2569           0 :     Move(videoManager),
    2570             :     namespaces);
    2571           0 : }
    2572             : 
    2573             : void
    2574           0 : ContentParent::OnCompositorDeviceReset()
    2575             : {
    2576           0 :   Unused << SendReinitRenderingForDeviceReset();
    2577           0 : }
    2578             : 
    2579             : void
    2580           0 : ContentParent::OnVarChanged(const GfxVarUpdate& aVar)
    2581             : {
    2582           0 :   if (!mIPCOpen) {
    2583           0 :     return;
    2584             :   }
    2585           0 :   Unused << SendVarUpdate(aVar);
    2586             : }
    2587             : 
    2588             : mozilla::ipc::IPCResult
    2589           0 : ContentParent::RecvReadFontList(InfallibleTArray<FontListEntry>* retValue)
    2590             : {
    2591             : #ifdef ANDROID
    2592             :   gfxAndroidPlatform::GetPlatform()->GetSystemFontList(retValue);
    2593             : #endif
    2594           0 :   return IPC_OK();
    2595             : }
    2596             : 
    2597             : mozilla::ipc::IPCResult
    2598           0 : ContentParent::RecvSetClipboard(const IPCDataTransfer& aDataTransfer,
    2599             :                                 const bool& aIsPrivateData,
    2600             :                                 const IPC::Principal& aRequestingPrincipal,
    2601             :                                 const int32_t& aWhichClipboard)
    2602             : {
    2603             :   nsresult rv;
    2604           0 :   nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
    2605           0 :   NS_ENSURE_SUCCESS(rv, IPC_OK());
    2606             : 
    2607             :   nsCOMPtr<nsITransferable> trans =
    2608           0 :     do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
    2609           0 :   NS_ENSURE_SUCCESS(rv, IPC_OK());
    2610           0 :   trans->Init(nullptr);
    2611             : 
    2612           0 :   rv = nsContentUtils::IPCTransferableToTransferable(aDataTransfer,
    2613             :                                                      aIsPrivateData,
    2614             :                                                      aRequestingPrincipal,
    2615             :                                                      trans, this, nullptr);
    2616           0 :   NS_ENSURE_SUCCESS(rv, IPC_OK());
    2617             : 
    2618           0 :   clipboard->SetData(trans, nullptr, aWhichClipboard);
    2619           0 :   return IPC_OK();
    2620             : }
    2621             : 
    2622             : mozilla::ipc::IPCResult
    2623           0 : ContentParent::RecvGetClipboard(nsTArray<nsCString>&& aTypes,
    2624             :                                 const int32_t& aWhichClipboard,
    2625             :                                 IPCDataTransfer* aDataTransfer)
    2626             : {
    2627             :   nsresult rv;
    2628           0 :   nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
    2629           0 :   NS_ENSURE_SUCCESS(rv, IPC_OK());
    2630             : 
    2631           0 :   nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
    2632           0 :   NS_ENSURE_SUCCESS(rv, IPC_OK());
    2633           0 :   trans->Init(nullptr);
    2634             : 
    2635           0 :   for (uint32_t t = 0; t < aTypes.Length(); t++) {
    2636           0 :     trans->AddDataFlavor(aTypes[t].get());
    2637             :   }
    2638             : 
    2639           0 :   clipboard->GetData(trans, aWhichClipboard);
    2640           0 :   nsContentUtils::TransferableToIPCTransferable(trans, aDataTransfer,
    2641           0 :                                                 true, nullptr, this);
    2642           0 :   return IPC_OK();
    2643             : }
    2644             : 
    2645             : mozilla::ipc::IPCResult
    2646           0 : ContentParent::RecvEmptyClipboard(const int32_t& aWhichClipboard)
    2647             : {
    2648             :   nsresult rv;
    2649           0 :   nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
    2650           0 :   NS_ENSURE_SUCCESS(rv, IPC_OK());
    2651             : 
    2652           0 :   clipboard->EmptyClipboard(aWhichClipboard);
    2653             : 
    2654           0 :   return IPC_OK();
    2655             : }
    2656             : 
    2657             : mozilla::ipc::IPCResult
    2658           0 : ContentParent::RecvClipboardHasType(nsTArray<nsCString>&& aTypes,
    2659             :                                     const int32_t& aWhichClipboard,
    2660             :                                     bool* aHasType)
    2661             : {
    2662             :   nsresult rv;
    2663           0 :   nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
    2664           0 :   NS_ENSURE_SUCCESS(rv, IPC_OK());
    2665             : 
    2666           0 :   const char** typesChrs = new const char *[aTypes.Length()];
    2667           0 :   for (uint32_t t = 0; t < aTypes.Length(); t++) {
    2668           0 :     typesChrs[t] = aTypes[t].get();
    2669             :   }
    2670             : 
    2671           0 :   clipboard->HasDataMatchingFlavors(typesChrs, aTypes.Length(),
    2672           0 :                                     aWhichClipboard, aHasType);
    2673             : 
    2674           0 :   delete [] typesChrs;
    2675           0 :   return IPC_OK();
    2676             : }
    2677             : 
    2678             : mozilla::ipc::IPCResult
    2679           0 : ContentParent::RecvGetSystemColors(const uint32_t& colorsCount,
    2680             :                                    InfallibleTArray<uint32_t>* colors)
    2681             : {
    2682             : #ifdef MOZ_WIDGET_ANDROID
    2683             :   NS_ASSERTION(AndroidBridge::Bridge() != nullptr, "AndroidBridge is not available");
    2684             :   if (AndroidBridge::Bridge() == nullptr) {
    2685             :     // Do not fail - the colors won't be right, but it's not critical
    2686             :     return IPC_OK();
    2687             :   }
    2688             : 
    2689             :   colors->AppendElements(colorsCount);
    2690             : 
    2691             :   // The array elements correspond to the members of AndroidSystemColors structure,
    2692             :   // so just pass the pointer to the elements buffer
    2693             :   AndroidBridge::Bridge()->GetSystemColors((AndroidSystemColors*)colors->Elements());
    2694             : #endif
    2695           0 :   return IPC_OK();
    2696             : }
    2697             : 
    2698             : mozilla::ipc::IPCResult
    2699           0 : ContentParent::RecvGetIconForExtension(const nsCString& aFileExt,
    2700             :                                        const uint32_t& aIconSize,
    2701             :                                        InfallibleTArray<uint8_t>* bits)
    2702             : {
    2703             : #ifdef MOZ_WIDGET_ANDROID
    2704             :   NS_ASSERTION(AndroidBridge::Bridge() != nullptr, "AndroidBridge is not available");
    2705             :   if (AndroidBridge::Bridge() == nullptr) {
    2706             :     // Do not fail - just no icon will be shown
    2707             :     return IPC_OK();
    2708             :   }
    2709             : 
    2710             :   bits->AppendElements(aIconSize * aIconSize * 4);
    2711             : 
    2712             :   AndroidBridge::Bridge()->GetIconForExtension(aFileExt, aIconSize, bits->Elements());
    2713             : #endif
    2714           0 :   return IPC_OK();
    2715             : }
    2716             : 
    2717             : mozilla::ipc::IPCResult
    2718           0 : ContentParent::RecvGetShowPasswordSetting(bool* showPassword)
    2719             : {
    2720             :   // default behavior is to show the last password character
    2721           0 :   *showPassword = true;
    2722             : #ifdef MOZ_WIDGET_ANDROID
    2723             :   NS_ASSERTION(AndroidBridge::Bridge() != nullptr, "AndroidBridge is not available");
    2724             : 
    2725             :   *showPassword = java::GeckoAppShell::GetShowPasswordSetting();
    2726             : #endif
    2727           0 :   return IPC_OK();
    2728             : }
    2729             : 
    2730             : mozilla::ipc::IPCResult
    2731           1 : ContentParent::RecvFirstIdle()
    2732             : {
    2733             :   // When the ContentChild goes idle, it sends us a FirstIdle message
    2734             :   // which we use as a good time to signal the PreallocatedProcessManager
    2735             :   // that it can start allocating processes from now on.
    2736           1 :   PreallocatedProcessManager::RemoveBlocker(this);
    2737           1 :   return IPC_OK();
    2738             : }
    2739             : 
    2740             : // We want ContentParent to show up in CC logs for debugging purposes, but we
    2741             : // don't actually cycle collect it.
    2742           0 : NS_IMPL_CYCLE_COLLECTION_0(ContentParent)
    2743             : 
    2744          89 : NS_IMPL_CYCLE_COLLECTING_ADDREF(ContentParent)
    2745          51 : NS_IMPL_CYCLE_COLLECTING_RELEASE(ContentParent)
    2746             : 
    2747          29 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ContentParent)
    2748          27 :   NS_INTERFACE_MAP_ENTRY(nsIContentParent)
    2749          27 :   NS_INTERFACE_MAP_ENTRY(nsIObserver)
    2750           2 :   NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionCallback)
    2751           2 :   NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionErrorCallback)
    2752           2 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
    2753           0 : NS_INTERFACE_MAP_END
    2754             : 
    2755             : NS_IMETHODIMP
    2756          23 : ContentParent::Observe(nsISupports* aSubject,
    2757             :                        const char* aTopic,
    2758             :                        const char16_t* aData)
    2759             : {
    2760          46 :   if (mSubprocess && (!strcmp(aTopic, "profile-before-change") ||
    2761          23 :                       !strcmp(aTopic, "xpcom-shutdown"))) {
    2762             :     // Okay to call ShutDownProcess multiple times.
    2763           0 :     ShutDownProcess(SEND_SHUTDOWN_MESSAGE);
    2764             : 
    2765             :     // Wait for shutdown to complete, so that we receive any shutdown
    2766             :     // data (e.g. telemetry) from the child before we quit.
    2767             :     // This loop terminate prematurely based on mForceKillTimer.
    2768           0 :     SpinEventLoopUntil([&]() { return !mIPCOpen || mCalledKillHard; });
    2769           0 :     NS_ASSERTION(!mSubprocess, "Close should have nulled mSubprocess");
    2770             :   }
    2771             : 
    2772          23 :   if (!mIsAlive || !mSubprocess)
    2773           0 :     return NS_OK;
    2774             : 
    2775             :   // listening for memory pressure event
    2776          69 :   if (!strcmp(aTopic, "memory-pressure") &&
    2777          23 :       !StringEndsWith(nsDependentString(aData),
    2778          23 :                       NS_LITERAL_STRING("-no-forward"))) {
    2779           0 :       Unused << SendFlushMemory(nsDependentString(aData));
    2780             :   }
    2781             :   // listening for remotePrefs...
    2782          23 :   else if (!strcmp(aTopic, "nsPref:changed")) {
    2783             :     // We know prefs are ASCII here.
    2784          46 :     NS_LossyConvertUTF16toASCII strData(aData);
    2785             : 
    2786          46 :     PrefSetting pref(strData, null_t(), null_t());
    2787          23 :     Preferences::GetPreference(&pref);
    2788          23 :     if (!SendPreferenceUpdate(pref)) {
    2789           0 :       return NS_ERROR_NOT_AVAILABLE;
    2790             :     }
    2791             :   }
    2792           0 :   else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC)) {
    2793           0 :     NS_ConvertUTF16toUTF8 dataStr(aData);
    2794           0 :     const char *offline = dataStr.get();
    2795           0 :     if (!SendSetOffline(!strcmp(offline, "true") ? true : false)) {
    2796           0 :       return NS_ERROR_NOT_AVAILABLE;
    2797             :     }
    2798             :   }
    2799           0 :   else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC)) {
    2800           0 :     if (!SendSetConnectivity(NS_LITERAL_STRING("true").Equals(aData))) {
    2801           0 :       return NS_ERROR_NOT_AVAILABLE;
    2802             :     }
    2803           0 :   } else if (!strcmp(aTopic, NS_IPC_CAPTIVE_PORTAL_SET_STATE)) {
    2804           0 :     nsCOMPtr<nsICaptivePortalService> cps = do_QueryInterface(aSubject);
    2805           0 :     MOZ_ASSERT(cps, "Should QI to a captive portal service");
    2806           0 :     if (!cps) {
    2807           0 :       return NS_ERROR_FAILURE;
    2808             :     }
    2809             :     int32_t state;
    2810           0 :     cps->GetState(&state);
    2811           0 :     if (!SendSetCaptivePortalState(state)) {
    2812           0 :       return NS_ERROR_NOT_AVAILABLE;
    2813             :     }
    2814             :   }
    2815             :   // listening for alert notifications
    2816           0 :   else if (!strcmp(aTopic, "alertfinished") ||
    2817           0 :        !strcmp(aTopic, "alertclickcallback") ||
    2818           0 :        !strcmp(aTopic, "alertshow") ||
    2819           0 :        !strcmp(aTopic, "alertdisablecallback") ||
    2820           0 :        !strcmp(aTopic, "alertsettingscallback")) {
    2821           0 :     if (!SendNotifyAlertsObserver(nsDependentCString(aTopic),
    2822           0 :                                   nsDependentString(aData)))
    2823           0 :       return NS_ERROR_NOT_AVAILABLE;
    2824             :   }
    2825           0 :   else if (!strcmp(aTopic, "child-gc-request")){
    2826           0 :     Unused << SendGarbageCollect();
    2827             :   }
    2828           0 :   else if (!strcmp(aTopic, "child-cc-request")){
    2829           0 :     Unused << SendCycleCollect();
    2830             :   }
    2831           0 :   else if (!strcmp(aTopic, "child-mmu-request")){
    2832           0 :     Unused << SendMinimizeMemoryUsage();
    2833             :   }
    2834           0 :   else if (!strcmp(aTopic, "last-pb-context-exited")) {
    2835           0 :     Unused << SendLastPrivateDocShellDestroyed();
    2836             :   }
    2837             : #ifdef ACCESSIBILITY
    2838           0 :   else if (aData && !strcmp(aTopic, "a11y-init-or-shutdown")) {
    2839           0 :     if (*aData == '1') {
    2840             :       // Make sure accessibility is running in content process when
    2841             :       // accessibility gets initiated in chrome process.
    2842             : #if defined(XP_WIN)
    2843             : #if defined(RELEASE_OR_BETA)
    2844             :       // On Windows we currently only enable a11y in the content process
    2845             :       // for testing purposes.
    2846             :       if (Preferences::GetBool(kForceEnableE10sPref, false))
    2847             : #endif
    2848             :         Unused << SendActivateA11y(::GetCurrentThreadId(),
    2849             :                                    a11y::AccessibleWrap::GetContentProcessIdFor(ChildID()));
    2850             : #else
    2851           0 :       Unused << SendActivateA11y(0, 0);
    2852             : #endif
    2853             :     } else {
    2854             :       // If possible, shut down accessibility in content process when
    2855             :       // accessibility gets shutdown in chrome process.
    2856           0 :       Unused << SendShutdownA11y();
    2857             :     }
    2858             :   }
    2859             : #endif
    2860           0 :   else if (!strcmp(aTopic, "cacheservice:empty-cache")) {
    2861           0 :     Unused << SendNotifyEmptyHTTPCache();
    2862             :   }
    2863           0 :   else if (!strcmp(aTopic, "intl:app-locales-changed")) {
    2864           0 :     nsTArray<nsCString> appLocales;
    2865           0 :     LocaleService::GetInstance()->GetAppLocalesAsLangTags(appLocales);
    2866           0 :     Unused << SendUpdateAppLocales(appLocales);
    2867             :   }
    2868           0 :   else if (!strcmp(aTopic, "intl:requested-locales-changed")) {
    2869           0 :     nsTArray<nsCString> requestedLocales;
    2870           0 :     LocaleService::GetInstance()->GetRequestedLocales(requestedLocales);
    2871           0 :     Unused << SendUpdateRequestedLocales(requestedLocales);
    2872             :   }
    2873          23 :   return NS_OK;
    2874             : }
    2875             : 
    2876             : mozilla::ipc::IPCResult
    2877           2 : ContentParent::RecvInitBackground(Endpoint<PBackgroundParent>&& aEndpoint)
    2878             : {
    2879           2 :   if (!BackgroundParent::Alloc(this, Move(aEndpoint))) {
    2880           0 :     return IPC_FAIL(this, "BackgroundParent::Alloc failed");
    2881             :   }
    2882             : 
    2883           2 :   return IPC_OK();
    2884             : }
    2885             : 
    2886             : mozilla::jsipc::PJavaScriptParent *
    2887           1 : ContentParent::AllocPJavaScriptParent()
    2888             : {
    2889           1 :   MOZ_ASSERT(ManagedPJavaScriptParent().IsEmpty());
    2890           1 :   return nsIContentParent::AllocPJavaScriptParent();
    2891             : }
    2892             : 
    2893             : bool
    2894           0 : ContentParent::DeallocPJavaScriptParent(PJavaScriptParent *parent)
    2895             : {
    2896           0 :   return nsIContentParent::DeallocPJavaScriptParent(parent);
    2897             : }
    2898             : 
    2899             : PBrowserParent*
    2900           0 : ContentParent::AllocPBrowserParent(const TabId& aTabId,
    2901             :                                    const TabId& aSameTabGroupAs,
    2902             :                                    const IPCTabContext& aContext,
    2903             :                                    const uint32_t& aChromeFlags,
    2904             :                                    const ContentParentId& aCpId,
    2905             :                                    const bool& aIsForBrowser)
    2906             : {
    2907           0 :   return nsIContentParent::AllocPBrowserParent(aTabId,
    2908             :                                                aSameTabGroupAs,
    2909             :                                                aContext,
    2910             :                                                aChromeFlags,
    2911             :                                                aCpId,
    2912           0 :                                                aIsForBrowser);
    2913             : }
    2914             : 
    2915             : bool
    2916           0 : ContentParent::DeallocPBrowserParent(PBrowserParent* frame)
    2917             : {
    2918           0 :   return nsIContentParent::DeallocPBrowserParent(frame);
    2919             : }
    2920             : 
    2921             : PIPCBlobInputStreamParent*
    2922           0 : ContentParent::AllocPIPCBlobInputStreamParent(const nsID& aID,
    2923             :                                               const uint64_t& aSize)
    2924             : {
    2925           0 :   return nsIContentParent::AllocPIPCBlobInputStreamParent(aID, aSize);
    2926             : }
    2927             : 
    2928             : bool
    2929           0 : ContentParent::DeallocPIPCBlobInputStreamParent(PIPCBlobInputStreamParent* aActor)
    2930             : {
    2931           0 :   return nsIContentParent::DeallocPIPCBlobInputStreamParent(aActor);
    2932             : }
    2933             : 
    2934             : mozilla::PRemoteSpellcheckEngineParent *
    2935           0 : ContentParent::AllocPRemoteSpellcheckEngineParent()
    2936             : {
    2937           0 :   mozilla::RemoteSpellcheckEngineParent *parent = new mozilla::RemoteSpellcheckEngineParent();
    2938           0 :   return parent;
    2939             : }
    2940             : 
    2941             : bool
    2942           0 : ContentParent::DeallocPRemoteSpellcheckEngineParent(PRemoteSpellcheckEngineParent *parent)
    2943             : {
    2944           0 :   delete parent;
    2945           0 :   return true;
    2946             : }
    2947             : 
    2948             : /* static */ void
    2949           0 : ContentParent::ForceKillTimerCallback(nsITimer* aTimer, void* aClosure)
    2950             : {
    2951             :   // We don't want to time out the content process during XPCShell tests. This
    2952             :   // is the easiest way to ensure that.
    2953           0 :   if (PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR")) {
    2954           0 :     return;
    2955             :   }
    2956             : 
    2957           0 :   auto self = static_cast<ContentParent*>(aClosure);
    2958           0 :   self->KillHard("ShutDownKill");
    2959             : }
    2960             : 
    2961             : // WARNING: aReason appears in telemetry, so any new value passed in requires
    2962             : // data review.
    2963             : void
    2964           0 : ContentParent::KillHard(const char* aReason)
    2965             : {
    2966           0 :   AUTO_PROFILER_LABEL("ContentParent::KillHard", OTHER);
    2967             : 
    2968             :   // On Windows, calling KillHard multiple times causes problems - the
    2969             :   // process handle becomes invalid on the first call, causing a second call
    2970             :   // to crash our process - more details in bug 890840.
    2971           0 :   if (mCalledKillHard) {
    2972           0 :     return;
    2973             :   }
    2974           0 :   mCalledKillHard = true;
    2975           0 :   mForceKillTimer = nullptr;
    2976             : 
    2977             : #if defined(MOZ_CRASHREPORTER) && !defined(MOZ_B2G)
    2978             :   // We're about to kill the child process associated with this content.
    2979             :   // Something has gone wrong to get us here, so we generate a minidump
    2980             :   // of the parent and child for submission to the crash server.
    2981           0 :   if (mCrashReporter) {
    2982             :     // GeneratePairedMinidump creates two minidumps for us - the main
    2983             :     // one is for the content process we're about to kill, and the other
    2984             :     // one is for the main browser process. That second one is the extra
    2985             :     // minidump tagging along, so we have to tell the crash reporter that
    2986             :     // it exists and is being appended.
    2987           0 :     nsAutoCString additionalDumps("browser");
    2988           0 :     mCrashReporter->AddNote(
    2989           0 :       NS_LITERAL_CSTRING("additional_minidumps"),
    2990           0 :       additionalDumps);
    2991           0 :     nsDependentCString reason(aReason);
    2992           0 :     mCrashReporter->AddNote(
    2993           0 :       NS_LITERAL_CSTRING("ipc_channel_error"),
    2994           0 :       reason);
    2995             : 
    2996           0 :     Telemetry::Accumulate(Telemetry::SUBPROCESS_KILL_HARD, reason, 1);
    2997             : 
    2998           0 :     RefPtr<ContentParent> self = this;
    2999           0 :     std::function<void(bool)> callback = [self](bool aResult) {
    3000           0 :       self->OnGenerateMinidumpComplete(aResult);
    3001           0 :     };
    3002             :     // Generate the report and insert into the queue for submittal.
    3003           0 :     mCrashReporter->GenerateMinidumpAndPair(Process(),
    3004             :                                             nullptr,
    3005           0 :                                             NS_LITERAL_CSTRING("browser"),
    3006           0 :                                             Move(callback),
    3007           0 :                                             true);
    3008           0 :     return;
    3009             :   }
    3010             : #endif
    3011           0 :   OnGenerateMinidumpComplete(false);
    3012             : }
    3013             : 
    3014             : void
    3015           0 : ContentParent::OnGenerateMinidumpComplete(bool aDumpResult)
    3016             : {
    3017             : #if defined(MOZ_CRASHREPORTER) && !defined(MOZ_B2G)
    3018           0 :   if (mCrashReporter && aDumpResult) {
    3019             :     // CrashReporterHost::GenerateMinidumpAndPair() is successful.
    3020           0 :     mCreatedPairedMinidumps = mCrashReporter->FinalizeCrashReport();
    3021             :   }
    3022             : #endif
    3023             : 
    3024             :   Unused << aDumpResult; // Don't care about result if no minidump was requested.
    3025             : 
    3026             :   ProcessHandle otherProcessHandle;
    3027           0 :   if (!base::OpenProcessHandle(OtherPid(), &otherProcessHandle)) {
    3028           0 :     NS_ERROR("Failed to open child process when attempting kill.");
    3029           0 :     return;
    3030             :   }
    3031             : 
    3032           0 :   if (!KillProcess(otherProcessHandle, base::PROCESS_END_KILLED_BY_USER,
    3033             :            false)) {
    3034           0 :     NS_WARNING("failed to kill subprocess!");
    3035             :   }
    3036             : 
    3037           0 :   if (mSubprocess) {
    3038           0 :     mSubprocess->SetAlreadyDead();
    3039             :   }
    3040             : 
    3041             :   // EnsureProcessTerminated has responsibilty for closing otherProcessHandle.
    3042           0 :   XRE_GetIOMessageLoop()->PostTask(
    3043           0 :     NewRunnableFunction(&ProcessWatcher::EnsureProcessTerminated,
    3044           0 :                         otherProcessHandle, /*force=*/true));
    3045             : }
    3046             : 
    3047             : void
    3048           0 : ContentParent::FriendlyName(nsAString& aName, bool aAnonymize)
    3049             : {
    3050           0 :   aName.Truncate();
    3051           0 :   if (mIsForBrowser) {
    3052           0 :     aName.AssignLiteral("Browser");
    3053           0 :   } else if (aAnonymize) {
    3054           0 :     aName.AssignLiteral("<anonymized-name>");
    3055             :   } else {
    3056           0 :     aName.AssignLiteral("???");
    3057             :   }
    3058           0 : }
    3059             : 
    3060             : mozilla::ipc::IPCResult
    3061           1 : ContentParent::RecvInitCrashReporter(Shmem&& aShmem, const NativeThreadId& aThreadId)
    3062             : {
    3063             : #ifdef MOZ_CRASHREPORTER
    3064           2 :   mCrashReporter = MakeUnique<CrashReporterHost>(
    3065             :     GeckoProcessType_Content,
    3066             :     aShmem,
    3067           1 :     aThreadId);
    3068             : #endif
    3069           1 :   return IPC_OK();
    3070             : }
    3071             : 
    3072             : hal_sandbox::PHalParent*
    3073           1 : ContentParent::AllocPHalParent()
    3074             : {
    3075           1 :   return hal_sandbox::CreateHalParent();
    3076             : }
    3077             : 
    3078             : bool
    3079           0 : ContentParent::DeallocPHalParent(hal_sandbox::PHalParent* aHal)
    3080             : {
    3081           0 :   delete aHal;
    3082           0 :   return true;
    3083             : }
    3084             : 
    3085             : devtools::PHeapSnapshotTempFileHelperParent*
    3086           0 : ContentParent::AllocPHeapSnapshotTempFileHelperParent()
    3087             : {
    3088           0 :   return devtools::HeapSnapshotTempFileHelperParent::Create();
    3089             : }
    3090             : 
    3091             : bool
    3092           0 : ContentParent::DeallocPHeapSnapshotTempFileHelperParent(
    3093             :   devtools::PHeapSnapshotTempFileHelperParent* aHeapSnapshotHelper)
    3094             : {
    3095           0 :   delete aHeapSnapshotHelper;
    3096           0 :   return true;
    3097             : }
    3098             : 
    3099             : bool
    3100           0 : ContentParent::SendRequestMemoryReport(const uint32_t& aGeneration,
    3101             :                                        const bool& aAnonymize,
    3102             :                                        const bool& aMinimizeMemoryUsage,
    3103             :                                        const MaybeFileDesc& aDMDFile)
    3104             : {
    3105             :   // This automatically cancels the previous request.
    3106           0 :   mMemoryReportRequest = MakeUnique<MemoryReportRequestHost>(aGeneration);
    3107           0 :   Unused << PContentParent::SendRequestMemoryReport(
    3108             :     aGeneration,
    3109             :     aAnonymize,
    3110             :     aMinimizeMemoryUsage,
    3111             :     aDMDFile);
    3112           0 :   return IPC_OK();
    3113             : }
    3114             : 
    3115             : mozilla::ipc::IPCResult
    3116           0 : ContentParent::RecvAddMemoryReport(const MemoryReport& aReport)
    3117             : {
    3118           0 :   if (mMemoryReportRequest) {
    3119           0 :     mMemoryReportRequest->RecvReport(aReport);
    3120             :   }
    3121           0 :   return IPC_OK();
    3122             : }
    3123             : 
    3124             : mozilla::ipc::IPCResult
    3125           0 : ContentParent::RecvFinishMemoryReport(const uint32_t& aGeneration)
    3126             : {
    3127           0 :   if (mMemoryReportRequest) {
    3128           0 :     mMemoryReportRequest->Finish(aGeneration);
    3129           0 :     mMemoryReportRequest = nullptr;
    3130             :   }
    3131           0 :   return IPC_OK();
    3132             : }
    3133             : 
    3134             : PCycleCollectWithLogsParent*
    3135           0 : ContentParent::AllocPCycleCollectWithLogsParent(const bool& aDumpAllTraces,
    3136             :                                                 const FileDescriptor& aGCLog,
    3137             :                                                 const FileDescriptor& aCCLog)
    3138             : {
    3139           0 :   MOZ_CRASH("Don't call this; use ContentParent::CycleCollectWithLogs");
    3140             : }
    3141             : 
    3142             : bool
    3143           0 : ContentParent::DeallocPCycleCollectWithLogsParent(PCycleCollectWithLogsParent* aActor)
    3144             : {
    3145           0 :   delete aActor;
    3146           0 :   return true;
    3147             : }
    3148             : 
    3149             : bool
    3150           0 : ContentParent::CycleCollectWithLogs(bool aDumpAllTraces,
    3151             :                                     nsICycleCollectorLogSink* aSink,
    3152             :                                     nsIDumpGCAndCCLogsCallback* aCallback)
    3153             : {
    3154           0 :   return CycleCollectWithLogsParent::AllocAndSendConstructor(this,
    3155             :                                                              aDumpAllTraces,
    3156             :                                                              aSink,
    3157           0 :                                                              aCallback);
    3158             : }
    3159             : 
    3160             : PTestShellParent*
    3161           0 : ContentParent::AllocPTestShellParent()
    3162             : {
    3163           0 :   return new TestShellParent();
    3164             : }
    3165             : 
    3166             : bool
    3167           0 : ContentParent::DeallocPTestShellParent(PTestShellParent* shell)
    3168             : {
    3169           0 :   delete shell;
    3170           0 :   return true;
    3171             : }
    3172             : 
    3173             : PScriptCacheParent*
    3174           2 : ContentParent::AllocPScriptCacheParent(const FileDescOrError& cacheFile, const bool& wantCacheData)
    3175             : {
    3176           2 :   return new loader::ScriptCacheParent(wantCacheData);
    3177             : }
    3178             : 
    3179             : bool
    3180           1 : ContentParent::DeallocPScriptCacheParent(PScriptCacheParent* cache)
    3181             : {
    3182           1 :   delete static_cast<loader::ScriptCacheParent*>(cache);
    3183           1 :   return true;
    3184             : }
    3185             : 
    3186             : PNeckoParent*
    3187           1 : ContentParent::AllocPNeckoParent()
    3188             : {
    3189           1 :   return new NeckoParent();
    3190             : }
    3191             : 
    3192             : bool
    3193           0 : ContentParent::DeallocPNeckoParent(PNeckoParent* necko)
    3194             : {
    3195           0 :   delete necko;
    3196           0 :   return true;
    3197             : }
    3198             : 
    3199             : PPrintingParent*
    3200           1 : ContentParent::AllocPPrintingParent()
    3201             : {
    3202             : #ifdef NS_PRINTING
    3203           1 :   MOZ_ASSERT(!mPrintingParent,
    3204             :              "Only one PrintingParent should be created per process.");
    3205             : 
    3206             :   // Create the printing singleton for this process.
    3207           1 :   mPrintingParent = new PrintingParent();
    3208           1 :   return mPrintingParent.get();
    3209             : #else
    3210             :   MOZ_ASSERT_UNREACHABLE("Should never be created if no printing.");
    3211             :   return nullptr;
    3212             : #endif
    3213             : }
    3214             : 
    3215             : bool
    3216           0 : ContentParent::DeallocPPrintingParent(PPrintingParent* printing)
    3217             : {
    3218             : #ifdef NS_PRINTING
    3219           0 :   MOZ_ASSERT(mPrintingParent == printing,
    3220             :              "Only one PrintingParent should have been created per process.");
    3221             : 
    3222           0 :   mPrintingParent = nullptr;
    3223             : #else
    3224             :   MOZ_ASSERT_UNREACHABLE("Should never have been created if no printing.");
    3225             : #endif
    3226           0 :   return true;
    3227             : }
    3228             : 
    3229             : #ifdef NS_PRINTING
    3230             : already_AddRefed<embedding::PrintingParent>
    3231           0 : ContentParent::GetPrintingParent()
    3232             : {
    3233           0 :   MOZ_ASSERT(mPrintingParent);
    3234             : 
    3235           0 :   RefPtr<embedding::PrintingParent> printingParent = mPrintingParent;
    3236           0 :   return printingParent.forget();
    3237             : }
    3238             : #endif
    3239             : 
    3240             : PChildToParentStreamParent*
    3241           0 : ContentParent::AllocPChildToParentStreamParent()
    3242             : {
    3243           0 :   return nsIContentParent::AllocPChildToParentStreamParent();
    3244             : }
    3245             : 
    3246             : bool
    3247           0 : ContentParent::DeallocPChildToParentStreamParent(PChildToParentStreamParent* aActor)
    3248             : {
    3249           0 :   return nsIContentParent::DeallocPChildToParentStreamParent(aActor);
    3250             : }
    3251             : 
    3252             : PParentToChildStreamParent*
    3253           0 : ContentParent::SendPParentToChildStreamConstructor(PParentToChildStreamParent* aActor)
    3254             : {
    3255           0 :   return PContentParent::SendPParentToChildStreamConstructor(aActor);
    3256             : }
    3257             : 
    3258             : PParentToChildStreamParent*
    3259           0 : ContentParent::AllocPParentToChildStreamParent()
    3260             : {
    3261           0 :   return nsIContentParent::AllocPParentToChildStreamParent();
    3262             : }
    3263             : 
    3264             : bool
    3265           0 : ContentParent::DeallocPParentToChildStreamParent(PParentToChildStreamParent* aActor)
    3266             : {
    3267           0 :   return nsIContentParent::DeallocPParentToChildStreamParent(aActor);
    3268             : }
    3269             : 
    3270             : PPSMContentDownloaderParent*
    3271           0 : ContentParent::AllocPPSMContentDownloaderParent(const uint32_t& aCertType)
    3272             : {
    3273             :   RefPtr<PSMContentDownloaderParent> downloader =
    3274           0 :     new PSMContentDownloaderParent(aCertType);
    3275           0 :   return downloader.forget().take();
    3276             : }
    3277             : 
    3278             : bool
    3279           0 : ContentParent::DeallocPPSMContentDownloaderParent(PPSMContentDownloaderParent* aListener)
    3280             : {
    3281           0 :   auto* listener = static_cast<PSMContentDownloaderParent*>(aListener);
    3282           0 :   RefPtr<PSMContentDownloaderParent> downloader = dont_AddRef(listener);
    3283           0 :   return true;
    3284             : }
    3285             : 
    3286             : PExternalHelperAppParent*
    3287           0 : ContentParent::AllocPExternalHelperAppParent(const OptionalURIParams& uri,
    3288             :                                              const nsCString& aMimeContentType,
    3289             :                                              const nsCString& aContentDisposition,
    3290             :                                              const uint32_t& aContentDispositionHint,
    3291             :                                              const nsString& aContentDispositionFilename,
    3292             :                                              const bool& aForceSave,
    3293             :                                              const int64_t& aContentLength,
    3294             :                                              const bool& aWasFileChannel,
    3295             :                                              const OptionalURIParams& aReferrer,
    3296             :                                              PBrowserParent* aBrowser)
    3297             : {
    3298             :   ExternalHelperAppParent *parent =
    3299           0 :     new ExternalHelperAppParent(uri, aContentLength, aWasFileChannel);
    3300           0 :   parent->AddRef();
    3301             :   parent->Init(this,
    3302             :                aMimeContentType,
    3303             :                aContentDisposition,
    3304             :                aContentDispositionHint,
    3305             :                aContentDispositionFilename,
    3306             :                aForceSave,
    3307             :                aReferrer,
    3308           0 :                aBrowser);
    3309           0 :   return parent;
    3310             : }
    3311             : 
    3312             : bool
    3313           0 : ContentParent::DeallocPExternalHelperAppParent(PExternalHelperAppParent* aService)
    3314             : {
    3315           0 :   ExternalHelperAppParent *parent = static_cast<ExternalHelperAppParent *>(aService);
    3316           0 :   parent->Release();
    3317           0 :   return true;
    3318             : }
    3319             : 
    3320             : PHandlerServiceParent*
    3321           0 : ContentParent::AllocPHandlerServiceParent()
    3322             : {
    3323           0 :   HandlerServiceParent* actor = new HandlerServiceParent();
    3324           0 :   actor->AddRef();
    3325           0 :   return actor;
    3326             : }
    3327             : 
    3328             : bool
    3329           0 : ContentParent::DeallocPHandlerServiceParent(PHandlerServiceParent* aHandlerServiceParent)
    3330             : {
    3331           0 :   static_cast<HandlerServiceParent*>(aHandlerServiceParent)->Release();
    3332           0 :   return true;
    3333             : }
    3334             : 
    3335             : media::PMediaParent*
    3336           0 : ContentParent::AllocPMediaParent()
    3337             : {
    3338           0 :   return media::AllocPMediaParent();
    3339             : }
    3340             : 
    3341             : bool
    3342           0 : ContentParent::DeallocPMediaParent(media::PMediaParent *aActor)
    3343             : {
    3344           0 :   return media::DeallocPMediaParent(aActor);
    3345             : }
    3346             : 
    3347             : PStorageParent*
    3348           1 : ContentParent::AllocPStorageParent()
    3349             : {
    3350           1 :   return new StorageDBParent();
    3351             : }
    3352             : 
    3353             : bool
    3354           0 : ContentParent::DeallocPStorageParent(PStorageParent* aActor)
    3355             : {
    3356           0 :   StorageDBParent* child = static_cast<StorageDBParent*>(aActor);
    3357           0 :   child->ReleaseIPDLReference();
    3358           0 :   return true;
    3359             : }
    3360             : 
    3361             : PPresentationParent*
    3362           0 : ContentParent::AllocPPresentationParent()
    3363             : {
    3364           0 :   RefPtr<PresentationParent> actor = new PresentationParent();
    3365           0 :   return actor.forget().take();
    3366             : }
    3367             : 
    3368             : bool
    3369           0 : ContentParent::DeallocPPresentationParent(PPresentationParent* aActor)
    3370             : {
    3371             :   RefPtr<PresentationParent> actor =
    3372           0 :   dont_AddRef(static_cast<PresentationParent*>(aActor));
    3373           0 :   return true;
    3374             : }
    3375             : 
    3376             : mozilla::ipc::IPCResult
    3377           0 : ContentParent::RecvPPresentationConstructor(PPresentationParent* aActor)
    3378             : {
    3379           0 :   if (!static_cast<PresentationParent*>(aActor)->Init(mChildID)) {
    3380           0 :     return IPC_FAIL_NO_REASON(this);
    3381             :   }
    3382           0 :   return IPC_OK();
    3383             : }
    3384             : 
    3385             : PFlyWebPublishedServerParent*
    3386           0 : ContentParent::AllocPFlyWebPublishedServerParent(const nsString& name,
    3387             :                                                  const FlyWebPublishOptions& params)
    3388             : {
    3389             :   RefPtr<FlyWebPublishedServerParent> actor =
    3390           0 :     new FlyWebPublishedServerParent(name, params);
    3391           0 :   return actor.forget().take();
    3392             : }
    3393             : 
    3394             : bool
    3395           0 : ContentParent::DeallocPFlyWebPublishedServerParent(PFlyWebPublishedServerParent* aActor)
    3396             : {
    3397             :   RefPtr<FlyWebPublishedServerParent> actor =
    3398           0 :     dont_AddRef(static_cast<FlyWebPublishedServerParent*>(aActor));
    3399           0 :   return true;
    3400             : }
    3401             : 
    3402             : PSpeechSynthesisParent*
    3403           0 : ContentParent::AllocPSpeechSynthesisParent()
    3404             : {
    3405             : #ifdef MOZ_WEBSPEECH
    3406           0 :   return new mozilla::dom::SpeechSynthesisParent();
    3407             : #else
    3408             :   return nullptr;
    3409             : #endif
    3410             : }
    3411             : 
    3412             : bool
    3413           0 : ContentParent::DeallocPSpeechSynthesisParent(PSpeechSynthesisParent* aActor)
    3414             : {
    3415             : #ifdef MOZ_WEBSPEECH
    3416           0 :   delete aActor;
    3417           0 :   return true;
    3418             : #else
    3419             :   return false;
    3420             : #endif
    3421             : }
    3422             : 
    3423             : mozilla::ipc::IPCResult
    3424           0 : ContentParent::RecvPSpeechSynthesisConstructor(PSpeechSynthesisParent* aActor)
    3425             : {
    3426             : #ifdef MOZ_WEBSPEECH
    3427           0 :   if (!static_cast<SpeechSynthesisParent*>(aActor)->SendInit()) {
    3428           0 :     return IPC_FAIL_NO_REASON(this);
    3429             :   }
    3430           0 :   return IPC_OK();
    3431             : #else
    3432             :   return IPC_FAIL_NO_REASON(this);
    3433             : #endif
    3434             : }
    3435             : 
    3436             : mozilla::ipc::IPCResult
    3437           0 : ContentParent::RecvStartVisitedQuery(const URIParams& aURI)
    3438             : {
    3439           0 :   nsCOMPtr<nsIURI> newURI = DeserializeURI(aURI);
    3440           0 :   if (!newURI) {
    3441           0 :   return IPC_FAIL_NO_REASON(this);
    3442             :   }
    3443           0 :   nsCOMPtr<IHistory> history = services::GetHistoryService();
    3444           0 :   if (history) {
    3445           0 :   history->RegisterVisitedCallback(newURI, nullptr);
    3446             :   }
    3447           0 :   return IPC_OK();
    3448             : }
    3449             : 
    3450             : 
    3451             : mozilla::ipc::IPCResult
    3452           1 : ContentParent::RecvVisitURI(const URIParams& uri,
    3453             :                             const OptionalURIParams& referrer,
    3454             :                             const uint32_t& flags)
    3455             : {
    3456           2 :   nsCOMPtr<nsIURI> ourURI = DeserializeURI(uri);
    3457           1 :   if (!ourURI) {
    3458           0 :     return IPC_FAIL_NO_REASON(this);
    3459             :   }
    3460           2 :   nsCOMPtr<nsIURI> ourReferrer = DeserializeURI(referrer);
    3461           2 :   nsCOMPtr<IHistory> history = services::GetHistoryService();
    3462           1 :   if (history) {
    3463           1 :     history->VisitURI(ourURI, ourReferrer, flags);
    3464             :   }
    3465           1 :   return IPC_OK();
    3466             : }
    3467             : 
    3468             : 
    3469             : mozilla::ipc::IPCResult
    3470           1 : ContentParent::RecvSetURITitle(const URIParams& uri,
    3471             :                                const nsString& title)
    3472             : {
    3473           2 :   nsCOMPtr<nsIURI> ourURI = DeserializeURI(uri);
    3474           1 :   if (!ourURI) {
    3475           0 :     return IPC_FAIL_NO_REASON(this);
    3476             :   }
    3477           2 :   nsCOMPtr<IHistory> history = services::GetHistoryService();
    3478           1 :   if (history) {
    3479           1 :     history->SetURITitle(ourURI, title);
    3480             :   }
    3481           1 :   return IPC_OK();
    3482             : }
    3483             : 
    3484             : mozilla::ipc::IPCResult
    3485           0 : ContentParent::RecvNSSU2FTokenIsCompatibleVersion(const nsString& aVersion,
    3486             :                                                   bool* aIsCompatible)
    3487             : {
    3488           0 :   MOZ_ASSERT(aIsCompatible);
    3489             : 
    3490           0 :   nsCOMPtr<nsINSSU2FToken> nssToken(do_GetService(NS_NSSU2FTOKEN_CONTRACTID));
    3491           0 :   if (NS_WARN_IF(!nssToken)) {
    3492           0 :     return IPC_FAIL_NO_REASON(this);
    3493             :   }
    3494             : 
    3495           0 :   nsresult rv = nssToken->IsCompatibleVersion(aVersion, aIsCompatible);
    3496           0 :   if (NS_FAILED(rv)) {
    3497           0 :     return IPC_FAIL_NO_REASON(this);
    3498             :   }
    3499           0 :   return IPC_OK();
    3500             : }
    3501             : 
    3502             : mozilla::ipc::IPCResult
    3503           0 : ContentParent::RecvNSSU2FTokenIsRegistered(nsTArray<uint8_t>&& aKeyHandle,
    3504             :                                            nsTArray<uint8_t>&& aApplication,
    3505             :                                            bool* aIsValidKeyHandle)
    3506             : {
    3507           0 :   MOZ_ASSERT(aIsValidKeyHandle);
    3508             : 
    3509           0 :   nsCOMPtr<nsINSSU2FToken> nssToken(do_GetService(NS_NSSU2FTOKEN_CONTRACTID));
    3510           0 :   if (NS_WARN_IF(!nssToken)) {
    3511           0 :     return IPC_FAIL_NO_REASON(this);
    3512             :   }
    3513             : 
    3514           0 :   nsresult rv = nssToken->IsRegistered(aKeyHandle.Elements(), aKeyHandle.Length(),
    3515           0 :                                        aApplication.Elements(), aApplication.Length(),
    3516           0 :                                        aIsValidKeyHandle);
    3517           0 :   if (NS_FAILED(rv)) {
    3518           0 :     return IPC_FAIL_NO_REASON(this);
    3519             :   }
    3520           0 :   return IPC_OK();
    3521             : }
    3522             : 
    3523             : mozilla::ipc::IPCResult
    3524           0 : ContentParent::RecvNSSU2FTokenRegister(nsTArray<uint8_t>&& aApplication,
    3525             :                                        nsTArray<uint8_t>&& aChallenge,
    3526             :                                        nsTArray<uint8_t>* aRegistration)
    3527             : {
    3528           0 :   MOZ_ASSERT(aRegistration);
    3529             : 
    3530           0 :   nsCOMPtr<nsINSSU2FToken> nssToken(do_GetService(NS_NSSU2FTOKEN_CONTRACTID));
    3531           0 :   if (NS_WARN_IF(!nssToken)) {
    3532           0 :     return IPC_FAIL_NO_REASON(this);
    3533             :   }
    3534             :   uint8_t* buffer;
    3535             :   uint32_t bufferlen;
    3536           0 :   nsresult rv = nssToken->Register(aApplication.Elements(), aApplication.Length(),
    3537           0 :                                    aChallenge.Elements(), aChallenge.Length(),
    3538           0 :                                    &buffer, &bufferlen);
    3539           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    3540           0 :     return IPC_FAIL_NO_REASON(this);
    3541             :   }
    3542             : 
    3543           0 :   MOZ_ASSERT(buffer);
    3544           0 :   aRegistration->ReplaceElementsAt(0, aRegistration->Length(), buffer, bufferlen);
    3545           0 :   free(buffer);
    3546           0 :   if (NS_FAILED(rv)) {
    3547           0 :     return IPC_FAIL_NO_REASON(this);
    3548             :   }
    3549           0 :   return IPC_OK();
    3550             : }
    3551             : 
    3552             : mozilla::ipc::IPCResult
    3553           0 : ContentParent::RecvNSSU2FTokenSign(nsTArray<uint8_t>&& aApplication,
    3554             :                                    nsTArray<uint8_t>&& aChallenge,
    3555             :                                    nsTArray<uint8_t>&& aKeyHandle,
    3556             :                                    nsTArray<uint8_t>* aSignature)
    3557             : {
    3558           0 :   MOZ_ASSERT(aSignature);
    3559             : 
    3560           0 :   nsCOMPtr<nsINSSU2FToken> nssToken(do_GetService(NS_NSSU2FTOKEN_CONTRACTID));
    3561           0 :   if (NS_WARN_IF(!nssToken)) {
    3562           0 :     return IPC_FAIL_NO_REASON(this);
    3563             :   }
    3564             :   uint8_t* buffer;
    3565             :   uint32_t bufferlen;
    3566           0 :   nsresult rv = nssToken->Sign(aApplication.Elements(), aApplication.Length(),
    3567           0 :                                aChallenge.Elements(), aChallenge.Length(),
    3568           0 :                                aKeyHandle.Elements(), aKeyHandle.Length(),
    3569           0 :                                &buffer, &bufferlen);
    3570           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    3571           0 :     return IPC_FAIL_NO_REASON(this);
    3572             :   }
    3573             : 
    3574           0 :   MOZ_ASSERT(buffer);
    3575           0 :   aSignature->ReplaceElementsAt(0, aSignature->Length(), buffer, bufferlen);
    3576           0 :   free(buffer);
    3577           0 :   if (NS_FAILED(rv)) {
    3578           0 :     return IPC_FAIL_NO_REASON(this);
    3579             :   }
    3580           0 :   return IPC_OK();
    3581             : }
    3582             : 
    3583             : mozilla::ipc::IPCResult
    3584           0 : ContentParent::RecvIsSecureURI(const uint32_t& aType,
    3585             :                                const URIParams& aURI,
    3586             :                                const uint32_t& aFlags,
    3587             :                                const OriginAttributes& aOriginAttributes,
    3588             :                                bool* aIsSecureURI)
    3589             : {
    3590           0 :   nsCOMPtr<nsISiteSecurityService> sss(do_GetService(NS_SSSERVICE_CONTRACTID));
    3591           0 :   if (!sss) {
    3592           0 :     return IPC_FAIL_NO_REASON(this);
    3593             :   }
    3594           0 :   nsCOMPtr<nsIURI> ourURI = DeserializeURI(aURI);
    3595           0 :   if (!ourURI) {
    3596           0 :     return IPC_FAIL_NO_REASON(this);
    3597             :   }
    3598           0 :   nsresult rv = sss->IsSecureURI(aType, ourURI, aFlags, aOriginAttributes, nullptr,
    3599           0 :                                  nullptr, aIsSecureURI);
    3600           0 :   if (NS_FAILED(rv)) {
    3601           0 :     return IPC_FAIL_NO_REASON(this);
    3602             :   }
    3603           0 :   return IPC_OK();
    3604             : }
    3605             : 
    3606             : mozilla::ipc::IPCResult
    3607           0 : ContentParent::RecvAccumulateMixedContentHSTS(const URIParams& aURI, const bool& aActive, const bool& aHSTSPriming,
    3608             :                                               const OriginAttributes& aOriginAttributes)
    3609             : {
    3610           0 :   nsCOMPtr<nsIURI> ourURI = DeserializeURI(aURI);
    3611           0 :   if (!ourURI) {
    3612           0 :     return IPC_FAIL_NO_REASON(this);
    3613             :   }
    3614           0 :   nsMixedContentBlocker::AccumulateMixedContentHSTS(ourURI, aActive, aHSTSPriming, aOriginAttributes);
    3615           0 :   return IPC_OK();
    3616             : }
    3617             : 
    3618             : mozilla::ipc::IPCResult
    3619           0 : ContentParent::RecvLoadURIExternal(const URIParams& uri,
    3620             :                                    PBrowserParent* windowContext)
    3621             : {
    3622           0 :   nsCOMPtr<nsIExternalProtocolService> extProtService(do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
    3623           0 :   if (!extProtService) {
    3624           0 :     return IPC_OK();
    3625             :   }
    3626           0 :   nsCOMPtr<nsIURI> ourURI = DeserializeURI(uri);
    3627           0 :   if (!ourURI) {
    3628           0 :     return IPC_FAIL_NO_REASON(this);
    3629             :   }
    3630             : 
    3631             :   RefPtr<RemoteWindowContext> context =
    3632           0 :     new RemoteWindowContext(static_cast<TabParent*>(windowContext));
    3633           0 :   extProtService->LoadURI(ourURI, context);
    3634           0 :   return IPC_OK();
    3635             : }
    3636             : 
    3637             : mozilla::ipc::IPCResult
    3638           0 : ContentParent::RecvExtProtocolChannelConnectParent(const uint32_t& registrarId)
    3639             : {
    3640             :   nsresult rv;
    3641             : 
    3642             :   // First get the real channel created before redirect on the parent.
    3643           0 :   nsCOMPtr<nsIChannel> channel;
    3644           0 :   rv = NS_LinkRedirectChannels(registrarId, nullptr, getter_AddRefs(channel));
    3645           0 :   NS_ENSURE_SUCCESS(rv, IPC_OK());
    3646             : 
    3647           0 :   nsCOMPtr<nsIParentChannel> parent = do_QueryInterface(channel, &rv);
    3648           0 :   NS_ENSURE_SUCCESS(rv, IPC_OK());
    3649             : 
    3650             :   // The channel itself is its own (faked) parent, link it.
    3651           0 :   rv = NS_LinkRedirectChannels(registrarId, parent, getter_AddRefs(channel));
    3652           0 :   NS_ENSURE_SUCCESS(rv, IPC_OK());
    3653             : 
    3654             :   // Signal the parent channel that it's a redirect-to parent.  This will
    3655             :   // make AsyncOpen on it do nothing (what we want).
    3656             :   // Yes, this is a bit of a hack, but I don't think it's necessary to invent
    3657             :   // a new interface just to set this flag on the channel.
    3658           0 :   parent->SetParentListener(nullptr);
    3659             : 
    3660           0 :   return IPC_OK();
    3661             : }
    3662             : 
    3663             : bool
    3664           0 : ContentParent::HasNotificationPermission(const IPC::Principal& aPrincipal)
    3665             : {
    3666           0 :   return true;
    3667             : }
    3668             : 
    3669             : mozilla::ipc::IPCResult
    3670           0 : ContentParent::RecvShowAlert(const AlertNotificationType& aAlert)
    3671             : {
    3672           0 :   nsCOMPtr<nsIAlertNotification> alert(dont_AddRef(aAlert));
    3673           0 :   if (NS_WARN_IF(!alert)) {
    3674           0 :     return IPC_OK();
    3675             :   }
    3676             : 
    3677           0 :   nsCOMPtr<nsIPrincipal> principal;
    3678           0 :   nsresult rv = alert->GetPrincipal(getter_AddRefs(principal));
    3679           0 :   if (NS_WARN_IF(NS_FAILED(rv)) ||
    3680           0 :       !HasNotificationPermission(IPC::Principal(principal))) {
    3681             : 
    3682           0 :       return IPC_OK();
    3683             :   }
    3684             : 
    3685           0 :   nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_ALERTSERVICE_CONTRACTID));
    3686           0 :   if (sysAlerts) {
    3687           0 :       sysAlerts->ShowAlert(alert, this);
    3688             :   }
    3689           0 :   return IPC_OK();
    3690             : }
    3691             : 
    3692             : mozilla::ipc::IPCResult
    3693           0 : ContentParent::RecvCloseAlert(const nsString& aName,
    3694             :                               const IPC::Principal& aPrincipal)
    3695             : {
    3696           0 :   if (!HasNotificationPermission(aPrincipal)) {
    3697           0 :     return IPC_OK();
    3698             :   }
    3699             : 
    3700           0 :   nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_ALERTSERVICE_CONTRACTID));
    3701           0 :   if (sysAlerts) {
    3702           0 :     sysAlerts->CloseAlert(aName, aPrincipal);
    3703             :   }
    3704             : 
    3705           0 :   return IPC_OK();
    3706             : }
    3707             : 
    3708             : mozilla::ipc::IPCResult
    3709           0 : ContentParent::RecvDisableNotifications(const IPC::Principal& aPrincipal)
    3710             : {
    3711           0 :   if (HasNotificationPermission(aPrincipal)) {
    3712           0 :     Unused << Notification::RemovePermission(aPrincipal);
    3713             :   }
    3714           0 :   return IPC_OK();
    3715             : }
    3716             : 
    3717             : mozilla::ipc::IPCResult
    3718           0 : ContentParent::RecvOpenNotificationSettings(const IPC::Principal& aPrincipal)
    3719             : {
    3720           0 :   if (HasNotificationPermission(aPrincipal)) {
    3721           0 :     Unused << Notification::OpenSettings(aPrincipal);
    3722             :   }
    3723           0 :   return IPC_OK();
    3724             : }
    3725             : 
    3726             : mozilla::ipc::IPCResult
    3727           0 : ContentParent::RecvSyncMessage(const nsString& aMsg,
    3728             :                                const ClonedMessageData& aData,
    3729             :                                InfallibleTArray<CpowEntry>&& aCpows,
    3730             :                                const IPC::Principal& aPrincipal,
    3731             :                                nsTArray<StructuredCloneData>* aRetvals)
    3732             : {
    3733           0 :   return nsIContentParent::RecvSyncMessage(aMsg, aData, Move(aCpows),
    3734           0 :                                            aPrincipal, aRetvals);
    3735             : }
    3736             : 
    3737             : mozilla::ipc::IPCResult
    3738           0 : ContentParent::RecvRpcMessage(const nsString& aMsg,
    3739             :                               const ClonedMessageData& aData,
    3740             :                               InfallibleTArray<CpowEntry>&& aCpows,
    3741             :                               const IPC::Principal& aPrincipal,
    3742             :                               nsTArray<StructuredCloneData>* aRetvals)
    3743             : {
    3744           0 :   return nsIContentParent::RecvRpcMessage(aMsg, aData, Move(aCpows), aPrincipal,
    3745           0 :                                           aRetvals);
    3746             : }
    3747             : 
    3748             : mozilla::ipc::IPCResult
    3749           3 : ContentParent::RecvAsyncMessage(const nsString& aMsg,
    3750             :                                 InfallibleTArray<CpowEntry>&& aCpows,
    3751             :                                 const IPC::Principal& aPrincipal,
    3752             :                                 const ClonedMessageData& aData)
    3753             : {
    3754           3 :   return nsIContentParent::RecvAsyncMessage(aMsg, Move(aCpows), aPrincipal,
    3755           3 :                                             aData);
    3756             : }
    3757             : 
    3758             : static int32_t
    3759           0 : AddGeolocationListener(nsIDOMGeoPositionCallback* watcher,
    3760             :                        nsIDOMGeoPositionErrorCallback* errorCallBack,
    3761             :                        bool highAccuracy)
    3762             : {
    3763           0 :   nsCOMPtr<nsIDOMGeoGeolocation> geo = do_GetService("@mozilla.org/geolocation;1");
    3764           0 :   if (!geo) {
    3765           0 :     return -1;
    3766             :   }
    3767             : 
    3768           0 :   UniquePtr<PositionOptions> options = MakeUnique<PositionOptions>();
    3769           0 :   options->mTimeout = 0;
    3770           0 :   options->mMaximumAge = 0;
    3771           0 :   options->mEnableHighAccuracy = highAccuracy;
    3772           0 :   int32_t retval = 1;
    3773           0 :   geo->WatchPosition(watcher, errorCallBack, Move(options), &retval);
    3774           0 :   return retval;
    3775             : }
    3776             : 
    3777             : mozilla::ipc::IPCResult
    3778           0 : ContentParent::RecvAddGeolocationListener(const IPC::Principal& aPrincipal,
    3779             :                                           const bool& aHighAccuracy)
    3780             : {
    3781             :   // To ensure no geolocation updates are skipped, we always force the
    3782             :   // creation of a new listener.
    3783           0 :   RecvRemoveGeolocationListener();
    3784           0 :   mGeolocationWatchID = AddGeolocationListener(this, this, aHighAccuracy);
    3785           0 :   return IPC_OK();
    3786             : }
    3787             : 
    3788             : mozilla::ipc::IPCResult
    3789           0 : ContentParent::RecvRemoveGeolocationListener()
    3790             : {
    3791           0 :   if (mGeolocationWatchID != -1) {
    3792           0 :     nsCOMPtr<nsIDOMGeoGeolocation> geo = do_GetService("@mozilla.org/geolocation;1");
    3793           0 :     if (!geo) {
    3794           0 :       return IPC_OK();
    3795             :     }
    3796           0 :     geo->ClearWatch(mGeolocationWatchID);
    3797           0 :     mGeolocationWatchID = -1;
    3798             :   }
    3799           0 :   return IPC_OK();
    3800             : }
    3801             : 
    3802             : mozilla::ipc::IPCResult
    3803           0 : ContentParent::RecvSetGeolocationHigherAccuracy(const bool& aEnable)
    3804             : {
    3805             :   // This should never be called without a listener already present,
    3806             :   // so this check allows us to forgo securing privileges.
    3807           0 :   if (mGeolocationWatchID != -1) {
    3808           0 :     RecvRemoveGeolocationListener();
    3809           0 :     mGeolocationWatchID = AddGeolocationListener(this, this, aEnable);
    3810             :   }
    3811           0 :   return IPC_OK();
    3812             : }
    3813             : 
    3814             : NS_IMETHODIMP
    3815           0 : ContentParent::HandleEvent(nsIDOMGeoPosition* postion)
    3816             : {
    3817           0 :   Unused << SendGeolocationUpdate(GeoPosition(postion));
    3818           0 :   return NS_OK;
    3819             : }
    3820             : 
    3821             : NS_IMETHODIMP
    3822           0 : ContentParent::HandleEvent(nsIDOMGeoPositionError* postionError)
    3823             : {
    3824             :   int16_t errorCode;
    3825             :   nsresult rv;
    3826           0 :   rv = postionError->GetCode(&errorCode);
    3827           0 :   NS_ENSURE_SUCCESS(rv,rv);
    3828           0 :   Unused << SendGeolocationError(errorCode);
    3829           0 :   return NS_OK;
    3830             : }
    3831             : 
    3832             : nsConsoleService *
    3833           0 : ContentParent::GetConsoleService()
    3834             : {
    3835           0 :   if (mConsoleService) {
    3836           0 :     return mConsoleService.get();
    3837             :   }
    3838             : 
    3839             :   // XXXkhuey everything about this is terrible.
    3840             :   // Get the ConsoleService by CID rather than ContractID, so that we
    3841             :   // can cast the returned pointer to an nsConsoleService (rather than
    3842             :   // just an nsIConsoleService). This allows us to call the non-idl function
    3843             :   // nsConsoleService::LogMessageWithMode.
    3844           0 :   NS_DEFINE_CID(consoleServiceCID, NS_CONSOLESERVICE_CID);
    3845           0 :   nsCOMPtr<nsIConsoleService> consoleService(do_GetService(consoleServiceCID));
    3846           0 :   mConsoleService = static_cast<nsConsoleService*>(consoleService.get());
    3847           0 :   return mConsoleService.get();
    3848             : }
    3849             : 
    3850             : mozilla::ipc::IPCResult
    3851           0 : ContentParent::RecvConsoleMessage(const nsString& aMessage)
    3852             : {
    3853           0 :   RefPtr<nsConsoleService> consoleService = GetConsoleService();
    3854           0 :   if (!consoleService) {
    3855           0 :     return IPC_OK();
    3856             :   }
    3857             : 
    3858           0 :   RefPtr<nsConsoleMessage> msg(new nsConsoleMessage(aMessage.get()));
    3859           0 :   consoleService->LogMessageWithMode(msg, nsConsoleService::SuppressLog);
    3860           0 :   return IPC_OK();
    3861             : }
    3862             : 
    3863             : mozilla::ipc::IPCResult
    3864           0 : ContentParent::RecvScriptError(const nsString& aMessage,
    3865             :                                const nsString& aSourceName,
    3866             :                                const nsString& aSourceLine,
    3867             :                                const uint32_t& aLineNumber,
    3868             :                                const uint32_t& aColNumber,
    3869             :                                const uint32_t& aFlags,
    3870             :                                const nsCString& aCategory)
    3871             : {
    3872           0 :   RefPtr<nsConsoleService> consoleService = GetConsoleService();
    3873           0 :   if (!consoleService) {
    3874           0 :     return IPC_OK();
    3875             :   }
    3876             : 
    3877           0 :   nsCOMPtr<nsIScriptError> msg(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
    3878           0 :   nsresult rv = msg->Init(aMessage, aSourceName, aSourceLine,
    3879           0 :                           aLineNumber, aColNumber, aFlags, aCategory.get());
    3880           0 :   if (NS_FAILED(rv))
    3881           0 :     return IPC_OK();
    3882             : 
    3883           0 :   consoleService->LogMessageWithMode(msg, nsConsoleService::SuppressLog);
    3884           0 :   return IPC_OK();
    3885             : }
    3886             : 
    3887             : mozilla::ipc::IPCResult
    3888           0 : ContentParent::RecvPrivateDocShellsExist(const bool& aExist)
    3889             : {
    3890           0 :   if (!sPrivateContent)
    3891           0 :     sPrivateContent = new nsTArray<ContentParent*>();
    3892           0 :   if (aExist) {
    3893           0 :     sPrivateContent->AppendElement(this);
    3894             :   } else {
    3895           0 :     sPrivateContent->RemoveElement(this);
    3896             : 
    3897             :     // Only fire the notification if we have private and non-private
    3898             :     // windows: if privatebrowsing.autostart is true, all windows are
    3899             :     // private.
    3900           0 :     if (!sPrivateContent->Length() &&
    3901           0 :       !Preferences::GetBool("browser.privatebrowsing.autostart")) {
    3902           0 :       nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
    3903           0 :       obs->NotifyObservers(nullptr, "last-pb-context-exited", nullptr);
    3904           0 :       delete sPrivateContent;
    3905           0 :       sPrivateContent = nullptr;
    3906             :     }
    3907             :   }
    3908           0 :   return IPC_OK();
    3909             : }
    3910             : 
    3911             : bool
    3912          18 : ContentParent::DoLoadMessageManagerScript(const nsAString& aURL,
    3913             :                                           bool aRunInGlobalScope)
    3914             : {
    3915          18 :   MOZ_ASSERT(!aRunInGlobalScope);
    3916          18 :   return SendLoadProcessScript(nsString(aURL));
    3917             : }
    3918             : 
    3919             : nsresult
    3920           2 : ContentParent::DoSendAsyncMessage(JSContext* aCx,
    3921             :                                   const nsAString& aMessage,
    3922             :                                   StructuredCloneData& aHelper,
    3923             :                                   JS::Handle<JSObject *> aCpows,
    3924             :                                   nsIPrincipal* aPrincipal)
    3925             : {
    3926           4 :   ClonedMessageData data;
    3927           2 :   if (!BuildClonedMessageDataForParent(this, aHelper, data)) {
    3928           0 :     return NS_ERROR_DOM_DATA_CLONE_ERR;
    3929             :   }
    3930           4 :   InfallibleTArray<CpowEntry> cpows;
    3931           2 :   jsipc::CPOWManager* mgr = GetCPOWManager();
    3932           2 :   if (aCpows && (!mgr || !mgr->Wrap(aCx, aCpows, &cpows))) {
    3933           0 :     return NS_ERROR_UNEXPECTED;
    3934             :   }
    3935           2 :   if (!SendAsyncMessage(nsString(aMessage), cpows, Principal(aPrincipal), data)) {
    3936           0 :     return NS_ERROR_UNEXPECTED;
    3937             :   }
    3938           2 :   return NS_OK;
    3939             : }
    3940             : 
    3941             : PIPCBlobInputStreamParent*
    3942           0 : ContentParent::SendPIPCBlobInputStreamConstructor(PIPCBlobInputStreamParent* aActor,
    3943             :                                                   const nsID& aID,
    3944             :                                                   const uint64_t& aSize)
    3945             : {
    3946           0 :   return PContentParent::SendPIPCBlobInputStreamConstructor(aActor, aID, aSize);
    3947             : }
    3948             : 
    3949             : PBrowserParent*
    3950           1 : ContentParent::SendPBrowserConstructor(PBrowserParent* aActor,
    3951             :                                        const TabId& aTabId,
    3952             :                                        const TabId& aSameTabGroupAs,
    3953             :                                        const IPCTabContext& aContext,
    3954             :                                        const uint32_t& aChromeFlags,
    3955             :                                        const ContentParentId& aCpId,
    3956             :                                        const bool& aIsForBrowser)
    3957             : {
    3958           1 :   return PContentParent::SendPBrowserConstructor(aActor,
    3959             :                                                  aTabId,
    3960             :                                                  aSameTabGroupAs,
    3961             :                                                  aContext,
    3962             :                                                  aChromeFlags,
    3963             :                                                  aCpId,
    3964           1 :                                                  aIsForBrowser);
    3965             : }
    3966             : 
    3967             : mozilla::ipc::IPCResult
    3968           0 : ContentParent::RecvKeywordToURI(const nsCString& aKeyword,
    3969             :                                 nsString* aProviderName,
    3970             :                                 OptionalIPCStream* aPostData,
    3971             :                                 OptionalURIParams* aURI)
    3972             : {
    3973           0 :   *aPostData = void_t();
    3974           0 :   *aURI = void_t();
    3975             : 
    3976           0 :   nsCOMPtr<nsIURIFixup> fixup = do_GetService(NS_URIFIXUP_CONTRACTID);
    3977           0 :   if (!fixup) {
    3978           0 :     return IPC_OK();
    3979             :   }
    3980             : 
    3981           0 :   nsCOMPtr<nsIInputStream> postData;
    3982           0 :   nsCOMPtr<nsIURIFixupInfo> info;
    3983             : 
    3984           0 :   if (NS_FAILED(fixup->KeywordToURI(aKeyword, getter_AddRefs(postData),
    3985             :                                     getter_AddRefs(info)))) {
    3986           0 :     return IPC_OK();
    3987             :   }
    3988           0 :   info->GetKeywordProviderName(*aProviderName);
    3989             : 
    3990           0 :   AutoIPCStream autoStream;
    3991           0 :   if (NS_WARN_IF(!autoStream.Serialize(postData, this))) {
    3992           0 :     NS_ENSURE_SUCCESS(NS_ERROR_FAILURE, IPC_FAIL_NO_REASON(this));
    3993             :   }
    3994             : 
    3995           0 :   *aPostData = autoStream.TakeOptionalValue();
    3996             : 
    3997           0 :   nsCOMPtr<nsIURI> uri;
    3998           0 :   info->GetPreferredURI(getter_AddRefs(uri));
    3999           0 :   SerializeURI(uri, *aURI);
    4000           0 :   return IPC_OK();
    4001             : }
    4002             : 
    4003             : mozilla::ipc::IPCResult
    4004           0 : ContentParent::RecvNotifyKeywordSearchLoading(const nsString &aProvider,
    4005             :                                               const nsString &aKeyword)
    4006             : {
    4007             : #ifdef MOZ_TOOLKIT_SEARCH
    4008           0 :   nsCOMPtr<nsIBrowserSearchService> searchSvc = do_GetService("@mozilla.org/browser/search-service;1");
    4009           0 :   if (searchSvc) {
    4010           0 :     nsCOMPtr<nsISearchEngine> searchEngine;
    4011           0 :     searchSvc->GetEngineByName(aProvider, getter_AddRefs(searchEngine));
    4012           0 :     if (searchEngine) {
    4013           0 :       nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
    4014           0 :       if (obsSvc) {
    4015             :         // Note that "keyword-search" refers to a search via the url
    4016             :         // bar, not a bookmarks keyword search.
    4017           0 :         obsSvc->NotifyObservers(searchEngine, "keyword-search", aKeyword.get());
    4018             :       }
    4019             :     }
    4020             :   }
    4021             : #endif
    4022           0 :   return IPC_OK();
    4023             : }
    4024             : 
    4025             : mozilla::ipc::IPCResult
    4026           0 : ContentParent::RecvCopyFavicon(const URIParams& aOldURI,
    4027             :                                const URIParams& aNewURI,
    4028             :                                const IPC::Principal& aLoadingPrincipal,
    4029             :                                const bool& aInPrivateBrowsing)
    4030             : {
    4031           0 :   nsCOMPtr<nsIURI> oldURI = DeserializeURI(aOldURI);
    4032           0 :   if (!oldURI) {
    4033           0 :     return IPC_OK();
    4034             :   }
    4035           0 :   nsCOMPtr<nsIURI> newURI = DeserializeURI(aNewURI);
    4036           0 :   if (!newURI) {
    4037           0 :     return IPC_OK();
    4038             :   }
    4039             : 
    4040           0 :   nsDocShell::CopyFavicon(oldURI, newURI, aLoadingPrincipal, aInPrivateBrowsing);
    4041           0 :   return IPC_OK();
    4042             : }
    4043             : 
    4044             : bool
    4045           0 : ContentParent::ShouldContinueFromReplyTimeout()
    4046             : {
    4047           0 :   RefPtr<ProcessHangMonitor> monitor = ProcessHangMonitor::Get();
    4048           0 :   return !monitor || !monitor->ShouldTimeOutCPOWs();
    4049             : }
    4050             : 
    4051             : mozilla::ipc::IPCResult
    4052           0 : ContentParent::RecvRecordingDeviceEvents(const nsString& aRecordingStatus,
    4053             :                                          const nsString& aPageURL,
    4054             :                                          const bool& aIsAudio,
    4055             :                                          const bool& aIsVideo)
    4056             : {
    4057           0 :   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
    4058           0 :   if (obs) {
    4059             :     // recording-device-ipc-events needs to gather more information from content process
    4060           0 :     RefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
    4061           0 :     props->SetPropertyAsUint64(NS_LITERAL_STRING("childID"), ChildID());
    4062           0 :     props->SetPropertyAsBool(NS_LITERAL_STRING("isAudio"), aIsAudio);
    4063           0 :     props->SetPropertyAsBool(NS_LITERAL_STRING("isVideo"), aIsVideo);
    4064           0 :     props->SetPropertyAsAString(NS_LITERAL_STRING("requestURL"), aPageURL);
    4065             : 
    4066           0 :     obs->NotifyObservers((nsIPropertyBag2*) props,
    4067             :                          "recording-device-ipc-events",
    4068           0 :                          aRecordingStatus.get());
    4069             :   } else {
    4070           0 :     NS_WARNING("Could not get the Observer service for ContentParent::RecvRecordingDeviceEvents.");
    4071             :   }
    4072           0 :   return IPC_OK();
    4073             : }
    4074             : 
    4075             : mozilla::ipc::IPCResult
    4076           0 : ContentParent::RecvAddIdleObserver(const uint64_t& aObserver,
    4077             :                                    const uint32_t& aIdleTimeInS)
    4078             : {
    4079             :   nsresult rv;
    4080             :   nsCOMPtr<nsIIdleService> idleService =
    4081           0 :     do_GetService("@mozilla.org/widget/idleservice;1", &rv);
    4082           0 :   NS_ENSURE_SUCCESS(rv, IPC_FAIL_NO_REASON(this));
    4083             : 
    4084             :   RefPtr<ParentIdleListener> listener =
    4085           0 :     new ParentIdleListener(this, aObserver, aIdleTimeInS);
    4086           0 :   rv = idleService->AddIdleObserver(listener, aIdleTimeInS);
    4087           0 :   NS_ENSURE_SUCCESS(rv, IPC_FAIL_NO_REASON(this));
    4088           0 :   mIdleListeners.AppendElement(listener);
    4089           0 :   return IPC_OK();
    4090             : }
    4091             : 
    4092             : mozilla::ipc::IPCResult
    4093           0 : ContentParent::RecvRemoveIdleObserver(const uint64_t& aObserver,
    4094             :                                       const uint32_t& aIdleTimeInS)
    4095             : {
    4096           0 :   RefPtr<ParentIdleListener> listener;
    4097           0 :   for (int32_t i = mIdleListeners.Length() - 1; i >= 0; --i) {
    4098           0 :     listener = static_cast<ParentIdleListener*>(mIdleListeners[i].get());
    4099           0 :     if (listener->mObserver == aObserver &&
    4100           0 :       listener->mTime == aIdleTimeInS) {
    4101             :       nsresult rv;
    4102             :       nsCOMPtr<nsIIdleService> idleService =
    4103           0 :         do_GetService("@mozilla.org/widget/idleservice;1", &rv);
    4104           0 :       NS_ENSURE_SUCCESS(rv, IPC_FAIL_NO_REASON(this));
    4105           0 :       idleService->RemoveIdleObserver(listener, aIdleTimeInS);
    4106           0 :       mIdleListeners.RemoveElementAt(i);
    4107           0 :       break;
    4108             :     }
    4109             :   }
    4110           0 :   return IPC_OK();
    4111             : }
    4112             : 
    4113             : mozilla::ipc::IPCResult
    4114           1 : ContentParent::RecvBackUpXResources(const FileDescriptor& aXSocketFd)
    4115             : {
    4116             : #ifndef MOZ_X11
    4117             :   MOZ_CRASH("This message only makes sense on X11 platforms");
    4118             : #else
    4119           1 :   MOZ_ASSERT(0 > mChildXSocketFdDup.get(),
    4120             :              "Already backed up X resources??");
    4121           1 :   if (aXSocketFd.IsValid()) {
    4122           2 :     auto rawFD = aXSocketFd.ClonePlatformHandle();
    4123           1 :     mChildXSocketFdDup.reset(rawFD.release());
    4124             :   }
    4125             : #endif
    4126           1 :   return IPC_OK();
    4127             : }
    4128             : 
    4129           0 : class AnonymousTemporaryFileRequestor final : public Runnable
    4130             : {
    4131             : public:
    4132           0 :   AnonymousTemporaryFileRequestor(ContentParent* aCP, const uint64_t& aID)
    4133           0 :     : Runnable("dom::AnonymousTemporaryFileRequestor")
    4134             :     , mCP(aCP)
    4135           0 :     , mID(aID)
    4136             :     , mRv(NS_OK)
    4137           0 :     , mPRFD(nullptr)
    4138             :   {
    4139           0 :   }
    4140             : 
    4141           0 :   NS_IMETHOD Run() override
    4142             :   {
    4143           0 :     if (NS_IsMainThread()) {
    4144           0 :       FileDescOrError result;
    4145           0 :       if (NS_WARN_IF(NS_FAILED(mRv))) {
    4146             :         // Returning false will kill the child process; instead
    4147             :         // propagate the error and let the child handle it.
    4148           0 :         result = mRv;
    4149             :       } else {
    4150           0 :         result = FileDescriptor(FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(mPRFD)));
    4151             :         // The FileDescriptor object owns a duplicate of the file handle; we
    4152             :         // must close the original (and clean up the NSPR descriptor).
    4153           0 :         PR_Close(mPRFD);
    4154             :       }
    4155           0 :       Unused << mCP->SendProvideAnonymousTemporaryFile(mID, result);
    4156             :       // It's important to release this reference while wr're on the main thread!
    4157           0 :       mCP = nullptr;
    4158             :     } else {
    4159           0 :       mRv = NS_OpenAnonymousTemporaryFile(&mPRFD);
    4160           0 :       NS_DispatchToMainThread(this);
    4161             :     }
    4162           0 :     return NS_OK;
    4163             :   }
    4164             : 
    4165             : private:
    4166             :   RefPtr<ContentParent> mCP;
    4167             :   uint64_t mID;
    4168             :   nsresult mRv;
    4169             :   PRFileDesc* mPRFD;
    4170             : };
    4171             : 
    4172             : mozilla::ipc::IPCResult
    4173           0 : ContentParent::RecvRequestAnonymousTemporaryFile(const uint64_t& aID)
    4174             : {
    4175             :   // Make sure to send a callback to the child if we bail out early.
    4176           0 :   nsresult rv = NS_OK;
    4177           0 :   RefPtr<ContentParent> self(this);
    4178           0 :   auto autoNotifyChildOnError = MakeScopeExit([&]() {
    4179           0 :     if (NS_FAILED(rv)) {
    4180           0 :       FileDescOrError result(rv);
    4181           0 :       Unused << self->SendProvideAnonymousTemporaryFile(aID, result);
    4182             :     }
    4183           0 :   });
    4184             : 
    4185             :   // We use a helper runnable to open the anonymous temporary file on the IO
    4186             :   // thread.  The same runnable will call us back on the main thread when the
    4187             :   // file has been opened.
    4188             :   nsCOMPtr<nsIEventTarget> target
    4189           0 :     = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
    4190           0 :   if (!target) {
    4191           0 :     return IPC_OK();
    4192             :   }
    4193             : 
    4194           0 :   rv = target->Dispatch(new AnonymousTemporaryFileRequestor(this, aID),
    4195             :                         NS_DISPATCH_NORMAL);
    4196           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    4197           0 :     return IPC_OK();
    4198             :   }
    4199             : 
    4200           0 :   rv = NS_OK;
    4201           0 :   return IPC_OK();
    4202             : }
    4203             : 
    4204             : static NS_DEFINE_CID(kFormProcessorCID, NS_FORMPROCESSOR_CID);
    4205             : 
    4206             : mozilla::ipc::IPCResult
    4207           0 : ContentParent::RecvKeygenProcessValue(const nsString& oldValue,
    4208             :                                       const nsString& challenge,
    4209             :                                       const nsString& keytype,
    4210             :                                       const nsString& keyparams,
    4211             :                                       nsString* newValue)
    4212             : {
    4213             :   nsCOMPtr<nsIFormProcessor> formProcessor =
    4214           0 :     do_GetService(kFormProcessorCID);
    4215           0 :   if (!formProcessor) {
    4216           0 :     newValue->Truncate();
    4217           0 :     return IPC_OK();
    4218             :   }
    4219             : 
    4220           0 :   formProcessor->ProcessValueIPC(oldValue, challenge, keytype, keyparams,
    4221           0 :                                  *newValue);
    4222           0 :   return IPC_OK();
    4223             : }
    4224             : 
    4225             : mozilla::ipc::IPCResult
    4226           0 : ContentParent::RecvKeygenProvideContent(nsString* aAttribute,
    4227             :                                         nsTArray<nsString>* aContent)
    4228             : {
    4229             :   nsCOMPtr<nsIFormProcessor> formProcessor =
    4230           0 :     do_GetService(kFormProcessorCID);
    4231           0 :   if (!formProcessor) {
    4232           0 :     return IPC_OK();
    4233             :   }
    4234             : 
    4235           0 :   formProcessor->ProvideContent(NS_LITERAL_STRING("SELECT"), *aContent,
    4236           0 :                                 *aAttribute);
    4237           0 :   return IPC_OK();
    4238             : }
    4239             : 
    4240             : PFileDescriptorSetParent*
    4241           0 : ContentParent::SendPFileDescriptorSetConstructor(const FileDescriptor& aFD)
    4242             : {
    4243           0 :   return PContentParent::SendPFileDescriptorSetConstructor(aFD);
    4244             : }
    4245             : 
    4246             : PFileDescriptorSetParent*
    4247           0 : ContentParent::AllocPFileDescriptorSetParent(const FileDescriptor& aFD)
    4248             : {
    4249           0 :   return nsIContentParent::AllocPFileDescriptorSetParent(aFD);
    4250             : }
    4251             : 
    4252             : bool
    4253           0 : ContentParent::DeallocPFileDescriptorSetParent(PFileDescriptorSetParent* aActor)
    4254             : {
    4255           0 :   return nsIContentParent::DeallocPFileDescriptorSetParent(aActor);
    4256             : }
    4257             : 
    4258             : bool
    4259           0 : ContentParent::IgnoreIPCPrincipal()
    4260             : {
    4261             :   static bool sDidAddVarCache = false;
    4262             :   static bool sIgnoreIPCPrincipal = false;
    4263           0 :   if (!sDidAddVarCache) {
    4264           0 :     sDidAddVarCache = true;
    4265             :     Preferences::AddBoolVarCache(&sIgnoreIPCPrincipal,
    4266           0 :                                  "dom.testing.ignore_ipc_principal", false);
    4267             :   }
    4268           0 :   return sIgnoreIPCPrincipal;
    4269             : }
    4270             : 
    4271             : void
    4272           0 : ContentParent::NotifyUpdatedDictionaries()
    4273             : {
    4274           0 :   nsCOMPtr<nsISpellChecker> spellChecker(do_GetService(NS_SPELLCHECKER_CONTRACTID));
    4275           0 :   MOZ_ASSERT(spellChecker, "No spell checker?");
    4276             : 
    4277           0 :   InfallibleTArray<nsString> dictionaries;
    4278           0 :   spellChecker->GetDictionaryList(&dictionaries);
    4279             : 
    4280           0 :   for (auto* cp : AllProcesses(eLive)) {
    4281           0 :     Unused << cp->SendUpdateDictionaryList(dictionaries);
    4282             :   }
    4283           0 : }
    4284             : 
    4285             : /*static*/ void
    4286           0 : ContentParent::UnregisterRemoteFrame(const TabId& aTabId,
    4287             :                                const ContentParentId& aCpId,
    4288             :                                bool aMarkedDestroying)
    4289             : {
    4290           0 :   if (XRE_IsParentProcess()) {
    4291           0 :     ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
    4292           0 :     ContentParent* cp = cpm->GetContentProcessById(aCpId);
    4293             : 
    4294           0 :     cp->NotifyTabDestroyed(aTabId, aMarkedDestroying);
    4295             : 
    4296           0 :     ContentProcessManager::GetSingleton()->UnregisterRemoteFrame(aCpId, aTabId);
    4297             :   } else {
    4298           0 :     ContentChild::GetSingleton()->SendUnregisterRemoteFrame(aTabId, aCpId,
    4299           0 :                                                       aMarkedDestroying);
    4300             :   }
    4301           0 : }
    4302             : 
    4303             : mozilla::ipc::IPCResult
    4304           0 : ContentParent::RecvUnregisterRemoteFrame(const TabId& aTabId,
    4305             :                                    const ContentParentId& aCpId,
    4306             :                                    const bool& aMarkedDestroying)
    4307             : {
    4308           0 :   UnregisterRemoteFrame(aTabId, aCpId, aMarkedDestroying);
    4309           0 :   return IPC_OK();
    4310             : }
    4311             : 
    4312             : mozilla::ipc::IPCResult
    4313           0 : ContentParent::RecvNotifyTabDestroying(const TabId& aTabId,
    4314             :                                        const ContentParentId& aCpId)
    4315             : {
    4316           0 :   NotifyTabDestroying(aTabId, aCpId);
    4317           0 :   return IPC_OK();
    4318             : }
    4319             : 
    4320             : nsTArray<TabContext>
    4321           0 : ContentParent::GetManagedTabContext()
    4322             : {
    4323             :   return Move(ContentProcessManager::GetSingleton()->
    4324           0 :           GetTabContextByContentProcess(this->ChildID()));
    4325             : }
    4326             : 
    4327             : mozilla::docshell::POfflineCacheUpdateParent*
    4328           0 : ContentParent::AllocPOfflineCacheUpdateParent(const URIParams& aManifestURI,
    4329             :                                               const URIParams& aDocumentURI,
    4330             :                                               const PrincipalInfo& aLoadingPrincipalInfo,
    4331             :                                               const bool& aStickDocument)
    4332             : {
    4333             :   RefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
    4334           0 :         new mozilla::docshell::OfflineCacheUpdateParent();
    4335             :   // Use this reference as the IPDL reference.
    4336           0 :   return update.forget().take();
    4337             : }
    4338             : 
    4339             : mozilla::ipc::IPCResult
    4340           0 : ContentParent::RecvPOfflineCacheUpdateConstructor(POfflineCacheUpdateParent* aActor,
    4341             :                                                   const URIParams& aManifestURI,
    4342             :                                                   const URIParams& aDocumentURI,
    4343             :                                                   const PrincipalInfo& aLoadingPrincipal,
    4344             :                                                   const bool& aStickDocument)
    4345             : {
    4346           0 :   MOZ_ASSERT(aActor);
    4347             : 
    4348             :   RefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
    4349           0 :     static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(aActor);
    4350             : 
    4351           0 :   nsresult rv = update->Schedule(aManifestURI, aDocumentURI, aLoadingPrincipal, aStickDocument);
    4352           0 :   if (NS_FAILED(rv) && IsAlive()) {
    4353             :     // Inform the child of failure.
    4354           0 :     Unused << update->SendFinish(false, false);
    4355             :   }
    4356             : 
    4357           0 :   return IPC_OK();
    4358             : }
    4359             : 
    4360             : bool
    4361           0 : ContentParent::DeallocPOfflineCacheUpdateParent(POfflineCacheUpdateParent* aActor)
    4362             : {
    4363             :   // Reclaim the IPDL reference.
    4364             :   RefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
    4365           0 :     dont_AddRef(static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(aActor));
    4366           0 :   return true;
    4367             : }
    4368             : 
    4369             : PWebrtcGlobalParent *
    4370           0 : ContentParent::AllocPWebrtcGlobalParent()
    4371             : {
    4372             : #ifdef MOZ_WEBRTC
    4373           0 :   return WebrtcGlobalParent::Alloc();
    4374             : #else
    4375             :   return nullptr;
    4376             : #endif
    4377             : }
    4378             : 
    4379             : bool
    4380           0 : ContentParent::DeallocPWebrtcGlobalParent(PWebrtcGlobalParent *aActor)
    4381             : {
    4382             : #ifdef MOZ_WEBRTC
    4383           0 :   WebrtcGlobalParent::Dealloc(static_cast<WebrtcGlobalParent*>(aActor));
    4384           0 :   return true;
    4385             : #else
    4386             :   return false;
    4387             : #endif
    4388             : }
    4389             : 
    4390             : mozilla::ipc::IPCResult
    4391           0 : ContentParent::RecvSetOfflinePermission(const Principal& aPrincipal)
    4392             : {
    4393           0 :   nsIPrincipal* principal = aPrincipal;
    4394           0 :   nsContentUtils::MaybeAllowOfflineAppByDefault(principal);
    4395           0 :   return IPC_OK();
    4396             : }
    4397             : 
    4398             : void
    4399           0 : ContentParent::MaybeInvokeDragSession(TabParent* aParent)
    4400             : {
    4401             :   nsCOMPtr<nsIDragService> dragService =
    4402           0 :     do_GetService("@mozilla.org/widget/dragservice;1");
    4403           0 :   if (dragService && dragService->MaybeAddChildProcess(this)) {
    4404             :     // We need to send transferable data to child process.
    4405           0 :     nsCOMPtr<nsIDragSession> session;
    4406           0 :     dragService->GetCurrentSession(getter_AddRefs(session));
    4407           0 :     if (session) {
    4408           0 :       nsTArray<IPCDataTransfer> dataTransfers;
    4409           0 :       nsCOMPtr<nsIDOMDataTransfer> domTransfer;
    4410           0 :       session->GetDataTransfer(getter_AddRefs(domTransfer));
    4411           0 :       nsCOMPtr<DataTransfer> transfer = do_QueryInterface(domTransfer);
    4412           0 :       if (!transfer) {
    4413             :         // Pass eDrop to get DataTransfer with external
    4414             :         // drag formats cached.
    4415           0 :         transfer = new DataTransfer(nullptr, eDrop, true, -1);
    4416           0 :         session->SetDataTransfer(transfer);
    4417             :       }
    4418             :       // Note, even though this fills the DataTransfer object with
    4419             :       // external data, the data is usually transfered over IPC lazily when
    4420             :       // needed.
    4421           0 :       transfer->FillAllExternalData();
    4422           0 :       nsCOMPtr<nsILoadContext> lc = aParent ?
    4423           0 :                                      aParent->GetLoadContext() : nullptr;
    4424             :       nsCOMPtr<nsIArray> transferables =
    4425           0 :         transfer->GetTransferables(lc);
    4426           0 :       nsContentUtils::TransferablesToIPCTransferables(transferables,
    4427             :                                                       dataTransfers,
    4428             :                                                       false,
    4429             :                                                       nullptr,
    4430           0 :                                                       this);
    4431             :       uint32_t action;
    4432           0 :       session->GetDragAction(&action);
    4433           0 :       mozilla::Unused << SendInvokeDragSession(dataTransfers, action);
    4434             :     }
    4435             :   }
    4436           0 : }
    4437             : 
    4438             : mozilla::ipc::IPCResult
    4439           0 : ContentParent::RecvUpdateDropEffect(const uint32_t& aDragAction,
    4440             :                                     const uint32_t& aDropEffect)
    4441             : {
    4442           0 :   nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
    4443           0 :   if (dragSession) {
    4444           0 :     dragSession->SetDragAction(aDragAction);
    4445           0 :     nsCOMPtr<nsIDOMDataTransfer> dt;
    4446           0 :     dragSession->GetDataTransfer(getter_AddRefs(dt));
    4447           0 :     if (dt) {
    4448           0 :       dt->SetDropEffectInt(aDropEffect);
    4449             :     }
    4450           0 :     dragSession->UpdateDragEffect();
    4451             :   }
    4452           0 :   return IPC_OK();
    4453             : }
    4454             : 
    4455             : PContentPermissionRequestParent*
    4456           0 : ContentParent::AllocPContentPermissionRequestParent(const InfallibleTArray<PermissionRequest>& aRequests,
    4457             :                                                     const IPC::Principal& aPrincipal,
    4458             :                                                     const TabId& aTabId)
    4459             : {
    4460           0 :   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
    4461             :   RefPtr<TabParent> tp =
    4462           0 :     cpm->GetTopLevelTabParentByProcessAndTabId(this->ChildID(), aTabId);
    4463           0 :   if (!tp) {
    4464           0 :     return nullptr;
    4465             :   }
    4466             : 
    4467           0 :   return nsContentPermissionUtils::CreateContentPermissionRequestParent(aRequests,
    4468             :                                                                         tp->GetOwnerElement(),
    4469             :                                                                         aPrincipal,
    4470           0 :                                                                         aTabId);
    4471             : }
    4472             : 
    4473             : bool
    4474           0 : ContentParent::DeallocPContentPermissionRequestParent(PContentPermissionRequestParent* actor)
    4475             : {
    4476           0 :   nsContentPermissionUtils::NotifyRemoveContentPermissionRequestParent(actor);
    4477           0 :   delete actor;
    4478           0 :   return true;
    4479             : }
    4480             : 
    4481             : PWebBrowserPersistDocumentParent*
    4482           0 : ContentParent::AllocPWebBrowserPersistDocumentParent(PBrowserParent* aBrowser,
    4483             :                                                      const uint64_t& aOuterWindowID)
    4484             : {
    4485           0 :   return new WebBrowserPersistDocumentParent();
    4486             : }
    4487             : 
    4488             : bool
    4489           0 : ContentParent::DeallocPWebBrowserPersistDocumentParent(PWebBrowserPersistDocumentParent* aActor)
    4490             : {
    4491           0 :   delete aActor;
    4492           0 :   return true;
    4493             : }
    4494             : 
    4495             : mozilla::ipc::IPCResult
    4496           0 : ContentParent::CommonCreateWindow(PBrowserParent* aThisTab,
    4497             :                                   bool aSetOpener,
    4498             :                                   const uint32_t& aChromeFlags,
    4499             :                                   const bool& aCalledFromJS,
    4500             :                                   const bool& aPositionSpecified,
    4501             :                                   const bool& aSizeSpecified,
    4502             :                                   nsIURI* aURIToLoad,
    4503             :                                   const nsCString& aFeatures,
    4504             :                                   const nsCString& aBaseURI,
    4505             :                                   const float& aFullZoom,
    4506             :                                   uint64_t aNextTabParentId,
    4507             :                                   const nsString& aName,
    4508             :                                   nsresult& aResult,
    4509             :                                   nsCOMPtr<nsITabParent>& aNewTabParent,
    4510             :                                   bool* aWindowIsNew,
    4511             :                                   nsIPrincipal* aTriggeringPrincipal)
    4512             : 
    4513             : {
    4514             :   // The content process should never be in charge of computing whether or
    4515             :   // not a window should be private or remote - the parent will do that.
    4516             :   const uint32_t badFlags = nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW |
    4517             :                             nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW |
    4518             :                             nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME |
    4519           0 :                             nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
    4520           0 :   if (!!(aChromeFlags & badFlags)) {
    4521           0 :     return IPC_FAIL(this, "Forbidden aChromeFlags passed");
    4522             :   }
    4523             : 
    4524           0 :   TabParent* thisTabParent = TabParent::GetFrom(aThisTab);
    4525           0 :   nsCOMPtr<nsIContent> frame;
    4526           0 :   if (thisTabParent) {
    4527           0 :     frame = do_QueryInterface(thisTabParent->GetOwnerElement());
    4528             : 
    4529           0 :     if (NS_WARN_IF(thisTabParent->IsMozBrowser())) {
    4530           0 :       return IPC_FAIL(this, "aThisTab is not a MozBrowser");
    4531             :     }
    4532             :   }
    4533             : 
    4534           0 :   nsCOMPtr<nsPIDOMWindowOuter> outerWin;
    4535           0 :   if (frame) {
    4536           0 :     outerWin = frame->OwnerDoc()->GetWindow();
    4537             : 
    4538             :     // If our chrome window is in the process of closing, don't try to open a
    4539             :     // new tab in it.
    4540           0 :     if (outerWin && outerWin->Closed()) {
    4541           0 :       outerWin = nullptr;
    4542             :     }
    4543             :   }
    4544             : 
    4545           0 :   nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
    4546           0 :   if (thisTabParent) {
    4547           0 :     browserDOMWin = thisTabParent->GetBrowserDOMWindow();
    4548             :   }
    4549             : 
    4550             :   // If we haven't found a chrome window to open in, just use the most recently
    4551             :   // opened one.
    4552           0 :   if (!outerWin) {
    4553           0 :     outerWin = nsContentUtils::GetMostRecentNonPBWindow();
    4554           0 :     if (NS_WARN_IF(!outerWin)) {
    4555           0 :       aResult = NS_ERROR_FAILURE;
    4556           0 :       return IPC_OK();
    4557             :     }
    4558             : 
    4559           0 :     nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(outerWin);
    4560           0 :     if (rootChromeWin) {
    4561           0 :       rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
    4562             :     }
    4563             :   }
    4564             : 
    4565           0 :   int32_t openLocation = nsWindowWatcher::GetWindowOpenLocation(
    4566           0 :     outerWin, aChromeFlags, aCalledFromJS, aPositionSpecified, aSizeSpecified);
    4567             : 
    4568           0 :   MOZ_ASSERT(openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB ||
    4569             :              openLocation == nsIBrowserDOMWindow::OPEN_NEWWINDOW);
    4570             : 
    4571             :   // Read the origin attributes for the tab from the opener tabParent.
    4572           0 :   OriginAttributes openerOriginAttributes;
    4573           0 :   if (thisTabParent) {
    4574           0 :     nsCOMPtr<nsILoadContext> loadContext = thisTabParent->GetLoadContext();
    4575           0 :     loadContext->GetOriginAttributes(openerOriginAttributes);
    4576           0 :   } else if (Preferences::GetBool("browser.privatebrowsing.autostart")) {
    4577           0 :     openerOriginAttributes.mPrivateBrowsingId = 1;
    4578             :   }
    4579             : 
    4580           0 :   if (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) {
    4581           0 :     if (NS_WARN_IF(!browserDOMWin)) {
    4582           0 :       aResult = NS_ERROR_ABORT;
    4583           0 :       return IPC_OK();
    4584             :     }
    4585             : 
    4586             :     nsCOMPtr<nsIOpenURIInFrameParams> params =
    4587           0 :       new nsOpenURIInFrameParams(openerOriginAttributes);
    4588           0 :     params->SetReferrer(NS_ConvertUTF8toUTF16(aBaseURI));
    4589           0 :     MOZ_ASSERT(aTriggeringPrincipal, "need a valid triggeringPrincipal");
    4590           0 :     params->SetTriggeringPrincipal(aTriggeringPrincipal);
    4591             : 
    4592           0 :     nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
    4593           0 :     aResult = browserDOMWin->OpenURIInFrame(aURIToLoad, params, openLocation,
    4594             :                                             nsIBrowserDOMWindow::OPEN_NEW,
    4595             :                                             aNextTabParentId, aName,
    4596           0 :                                             getter_AddRefs(frameLoaderOwner));
    4597           0 :     if (NS_SUCCEEDED(aResult) && frameLoaderOwner) {
    4598           0 :       RefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
    4599           0 :       if (frameLoader) {
    4600           0 :         frameLoader->GetTabParent(getter_AddRefs(aNewTabParent));
    4601             :       }
    4602             :     } else {
    4603           0 :       *aWindowIsNew = false;
    4604             :     }
    4605             : 
    4606           0 :     return IPC_OK();
    4607             :   }
    4608             : 
    4609             :   nsCOMPtr<nsPIWindowWatcher> pwwatch =
    4610           0 :     do_GetService(NS_WINDOWWATCHER_CONTRACTID, &aResult);
    4611           0 :   if (NS_WARN_IF(NS_FAILED(aResult))) {
    4612           0 :     return IPC_OK();
    4613             :   }
    4614             : 
    4615           0 :   aResult = pwwatch->OpenWindowWithTabParent(thisTabParent,
    4616           0 :                                              aFeatures, aCalledFromJS, aFullZoom,
    4617             :                                              aNextTabParentId,
    4618           0 :                                              !aSetOpener,
    4619           0 :                                              getter_AddRefs(aNewTabParent));
    4620           0 :   if (NS_WARN_IF(NS_FAILED(aResult))) {
    4621           0 :     return IPC_OK();
    4622             :   }
    4623             : 
    4624           0 :   MOZ_ASSERT(aNewTabParent);
    4625             :   // If we were passed a name for the window which would override the default,
    4626             :   // we should send it down to the new tab.
    4627           0 :   if (nsContentUtils::IsOverridingWindowName(aName)) {
    4628           0 :     Unused << TabParent::GetFrom(aNewTabParent)->SendSetWindowName(aName);
    4629             :   }
    4630             : 
    4631             :   // Don't send down the OriginAttributes if the content process is handling
    4632             :   // setting up the window for us. We only want to send them in the async case.
    4633             :   //
    4634             :   // If we send it down in the non-async case, then we might set the
    4635             :   // OriginAttributes after the document has already navigated.
    4636           0 :   if (!aSetOpener) {
    4637           0 :     Unused << TabParent::GetFrom(aNewTabParent)
    4638           0 :       ->SendSetOriginAttributes(openerOriginAttributes);
    4639             :   }
    4640             : 
    4641           0 :   if (aURIToLoad) {
    4642           0 :     nsCOMPtr<mozIDOMWindowProxy> openerWindow;
    4643           0 :     if (aSetOpener && thisTabParent) {
    4644           0 :       openerWindow = thisTabParent->GetParentWindowOuter();
    4645             :     }
    4646             :     nsCOMPtr<nsIBrowserDOMWindow> newBrowserDOMWin =
    4647           0 :       TabParent::GetFrom(aNewTabParent)->GetBrowserDOMWindow();
    4648           0 :     if (NS_WARN_IF(!newBrowserDOMWin)) {
    4649           0 :       aResult = NS_ERROR_ABORT;
    4650           0 :       return IPC_OK();
    4651             :     }
    4652           0 :     nsCOMPtr<mozIDOMWindowProxy> win;
    4653           0 :     aResult = newBrowserDOMWin->OpenURI(aURIToLoad, openerWindow,
    4654             :                                         nsIBrowserDOMWindow::OPEN_CURRENTWINDOW,
    4655             :                                         nsIBrowserDOMWindow::OPEN_NEW,
    4656             :                                         aTriggeringPrincipal,
    4657           0 :                                         getter_AddRefs(win));
    4658             :   }
    4659             : 
    4660           0 :   return IPC_OK();
    4661             : }
    4662             : 
    4663             : mozilla::ipc::IPCResult
    4664           0 : ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
    4665             :                                 PBrowserParent* aNewTab,
    4666             :                                 PRenderFrameParent* aRenderFrame,
    4667             :                                 const uint32_t& aChromeFlags,
    4668             :                                 const bool& aCalledFromJS,
    4669             :                                 const bool& aPositionSpecified,
    4670             :                                 const bool& aSizeSpecified,
    4671             :                                 const nsCString& aFeatures,
    4672             :                                 const nsCString& aBaseURI,
    4673             :                                 const float& aFullZoom,
    4674             :                                 const IPC::Principal& aTriggeringPrincipal,
    4675             :                                 CreateWindowResolver&& aResolve)
    4676             : {
    4677           0 :   nsresult rv = NS_OK;
    4678           0 :   CreatedWindowInfo cwi;
    4679             : 
    4680             :   // We always expect to open a new window here. If we don't, it's an error.
    4681           0 :   cwi.windowOpened() = true;
    4682           0 :   cwi.layersId() = 0;
    4683           0 :   cwi.maxTouchPoints() = 0;
    4684             : 
    4685             :   // Make sure to resolve the resolver when this function exits, even if we
    4686             :   // failed to generate a valid response.
    4687           0 :   auto resolveOnExit = MakeScopeExit([&] {
    4688             :     // Copy over the nsresult, and then resolve.
    4689           0 :     cwi.rv() = rv;
    4690           0 :     aResolve(cwi);
    4691           0 :   });
    4692             : 
    4693           0 :   TabParent* newTab = TabParent::GetFrom(aNewTab);
    4694           0 :   MOZ_ASSERT(newTab);
    4695             : 
    4696           0 :   auto destroyNewTabOnError = MakeScopeExit([&] {
    4697             :     // We always expect to open a new window here. If we don't, it's an error.
    4698           0 :     if (!cwi.windowOpened() || NS_FAILED(rv)) {
    4699           0 :       if (newTab) {
    4700           0 :         newTab->Destroy();
    4701             :       }
    4702             :     }
    4703           0 :   });
    4704             : 
    4705             :   // Content has requested that we open this new content window, so
    4706             :   // we must have an opener.
    4707           0 :   newTab->SetHasContentOpener(true);
    4708             : 
    4709           0 :   TabParent::AutoUseNewTab aunt(newTab, &cwi.urlToLoad());
    4710           0 :   const uint64_t nextTabParentId = ++sNextTabParentId;
    4711           0 :   sNextTabParents.Put(nextTabParentId, newTab);
    4712             : 
    4713           0 :   nsCOMPtr<nsITabParent> newRemoteTab;
    4714             :   mozilla::ipc::IPCResult ipcResult =
    4715             :     CommonCreateWindow(aThisTab, /* aSetOpener = */ true, aChromeFlags,
    4716             :                        aCalledFromJS, aPositionSpecified, aSizeSpecified,
    4717             :                        nullptr, aFeatures, aBaseURI, aFullZoom,
    4718             :                        nextTabParentId, NullString(), rv,
    4719           0 :                        newRemoteTab, &cwi.windowOpened(),
    4720           0 :                        aTriggeringPrincipal);
    4721           0 :   if (!ipcResult) {
    4722           0 :     return ipcResult;
    4723             :   }
    4724             : 
    4725           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    4726           0 :     return IPC_OK();
    4727             :   }
    4728             : 
    4729           0 :   if (sNextTabParents.GetAndRemove(nextTabParentId).valueOr(nullptr)) {
    4730           0 :     cwi.windowOpened() = false;
    4731             :   }
    4732           0 :   MOZ_ASSERT(TabParent::GetFrom(newRemoteTab) == newTab);
    4733             : 
    4734           0 :   newTab->SwapFrameScriptsFrom(cwi.frameScripts());
    4735             : 
    4736           0 :   RenderFrameParent* rfp = static_cast<RenderFrameParent*>(aRenderFrame);
    4737           0 :   if (!newTab->SetRenderFrame(rfp) ||
    4738           0 :       !newTab->GetRenderFrameInfo(&cwi.textureFactoryIdentifier(), &cwi.layersId())) {
    4739           0 :     rv = NS_ERROR_FAILURE;
    4740             :   }
    4741           0 :   cwi.compositorOptions() = rfp->GetCompositorOptions();
    4742             : 
    4743           0 :   nsCOMPtr<nsIWidget> widget = newTab->GetWidget();
    4744           0 :   if (widget) {
    4745           0 :     cwi.maxTouchPoints() = widget->GetMaxTouchPoints();
    4746           0 :     cwi.dimensions() = newTab->GetDimensionInfo();
    4747             :   }
    4748             : 
    4749           0 :   return IPC_OK();
    4750             : }
    4751             : 
    4752             : mozilla::ipc::IPCResult
    4753           0 : ContentParent::RecvCreateWindowInDifferentProcess(
    4754             :   PBrowserParent* aThisTab,
    4755             :   const uint32_t& aChromeFlags,
    4756             :   const bool& aCalledFromJS,
    4757             :   const bool& aPositionSpecified,
    4758             :   const bool& aSizeSpecified,
    4759             :   const URIParams& aURIToLoad,
    4760             :   const nsCString& aFeatures,
    4761             :   const nsCString& aBaseURI,
    4762             :   const float& aFullZoom,
    4763             :   const nsString& aName,
    4764             :   const IPC::Principal& aTriggeringPrincipal)
    4765             : {
    4766           0 :   nsCOMPtr<nsITabParent> newRemoteTab;
    4767             :   bool windowIsNew;
    4768           0 :   nsCOMPtr<nsIURI> uriToLoad = DeserializeURI(aURIToLoad);
    4769             :   nsresult rv;
    4770             :   mozilla::ipc::IPCResult ipcResult =
    4771             :     CommonCreateWindow(aThisTab, /* aSetOpener = */ false, aChromeFlags,
    4772             :                        aCalledFromJS, aPositionSpecified, aSizeSpecified,
    4773             :                        uriToLoad, aFeatures, aBaseURI, aFullZoom,
    4774             :                        /* aNextTabParentId = */ 0, aName, rv,
    4775           0 :                        newRemoteTab, &windowIsNew, aTriggeringPrincipal);
    4776           0 :   if (!ipcResult) {
    4777           0 :     return ipcResult;
    4778             :   }
    4779             : 
    4780           0 :   if (NS_FAILED(rv)) {
    4781           0 :     NS_WARNING("Call to CommonCreateWindow failed.");
    4782             :   }
    4783             : 
    4784           0 :   return IPC_OK();
    4785             : }
    4786             : 
    4787             : mozilla::ipc::IPCResult
    4788           0 : ContentParent::RecvShutdownProfile(const nsCString& aProfile)
    4789             : {
    4790             : #ifdef MOZ_GECKO_PROFILER
    4791           0 :   nsCOMPtr<nsIProfiler> profiler(do_GetService("@mozilla.org/tools/profiler;1"));
    4792           0 :   profiler->ReceiveShutdownProfile(aProfile);
    4793             : #endif
    4794           0 :   return IPC_OK();
    4795             : }
    4796             : 
    4797             : mozilla::ipc::IPCResult
    4798           0 : ContentParent::RecvGetGraphicsDeviceInitData(ContentDeviceData* aOut)
    4799             : {
    4800           0 :   gfxPlatform::GetPlatform()->BuildContentDeviceData(aOut);
    4801           0 :   return IPC_OK();
    4802             : }
    4803             : 
    4804             : mozilla::ipc::IPCResult
    4805           0 : ContentParent::RecvGraphicsError(const nsCString& aError)
    4806             : {
    4807           0 :   gfx::LogForwarder* lf = gfx::Factory::GetLogForwarder();
    4808           0 :   if (lf) {
    4809           0 :     std::stringstream message;
    4810           0 :     message << "CP+" << aError.get();
    4811           0 :     lf->UpdateStringsVector(message.str());
    4812             :   }
    4813           0 :   return IPC_OK();
    4814             : }
    4815             : 
    4816             : mozilla::ipc::IPCResult
    4817           0 : ContentParent::RecvBeginDriverCrashGuard(const uint32_t& aGuardType, bool* aOutCrashed)
    4818             : {
    4819             :   // Only one driver crash guard should be active at a time, per-process.
    4820           0 :   MOZ_ASSERT(!mDriverCrashGuard);
    4821             : 
    4822           0 :   UniquePtr<gfx::DriverCrashGuard> guard;
    4823           0 :   switch (gfx::CrashGuardType(aGuardType)) {
    4824             :   case gfx::CrashGuardType::D3D11Layers:
    4825           0 :     guard = MakeUnique<gfx::D3D11LayersCrashGuard>(this);
    4826           0 :     break;
    4827             :   case gfx::CrashGuardType::D3D9Video:
    4828           0 :     guard = MakeUnique<gfx::D3D9VideoCrashGuard>(this);
    4829           0 :     break;
    4830             :   case gfx::CrashGuardType::GLContext:
    4831           0 :     guard = MakeUnique<gfx::GLContextCrashGuard>(this);
    4832           0 :     break;
    4833             :   case gfx::CrashGuardType::D3D11Video:
    4834           0 :     guard = MakeUnique<gfx::D3D11VideoCrashGuard>(this);
    4835           0 :     break;
    4836             :   default:
    4837           0 :     MOZ_ASSERT_UNREACHABLE("unknown crash guard type");
    4838             :     return IPC_FAIL_NO_REASON(this);
    4839             :   }
    4840             : 
    4841           0 :   if (guard->Crashed()) {
    4842           0 :     *aOutCrashed = true;
    4843           0 :     return IPC_OK();
    4844             :   }
    4845             : 
    4846           0 :   *aOutCrashed = false;
    4847           0 :   mDriverCrashGuard = Move(guard);
    4848           0 :   return IPC_OK();
    4849             : }
    4850             : 
    4851             : mozilla::ipc::IPCResult
    4852           0 : ContentParent::RecvEndDriverCrashGuard(const uint32_t& aGuardType)
    4853             : {
    4854           0 :   mDriverCrashGuard = nullptr;
    4855           0 :   return IPC_OK();
    4856             : }
    4857             : 
    4858             : mozilla::ipc::IPCResult
    4859           0 : ContentParent::RecvGetAndroidSystemInfo(AndroidSystemInfo* aInfo)
    4860             : {
    4861             : #ifdef MOZ_WIDGET_ANDROID
    4862             :   nsSystemInfo::GetAndroidSystemInfo(aInfo);
    4863             :   return IPC_OK();
    4864             : #else
    4865           0 :   MOZ_CRASH("wrong platform!");
    4866             :   return IPC_FAIL_NO_REASON(this);
    4867             : #endif
    4868             : }
    4869             : 
    4870             : mozilla::ipc::IPCResult
    4871           0 : ContentParent::RecvNotifyBenchmarkResult(const nsString& aCodecName,
    4872             :                                          const uint32_t& aDecodeFPS)
    4873             : 
    4874             : {
    4875           0 :   if (aCodecName.EqualsLiteral("VP9")) {
    4876           0 :     Preferences::SetUint(VP9Benchmark::sBenchmarkFpsPref, aDecodeFPS);
    4877           0 :     Preferences::SetUint(VP9Benchmark::sBenchmarkFpsVersionCheck,
    4878           0 :                          VP9Benchmark::sBenchmarkVersionID);
    4879             :   }
    4880           0 :   return IPC_OK();
    4881             : }
    4882             : 
    4883             : mozilla::ipc::IPCResult
    4884           0 : ContentParent::RecvNotifyPushObservers(const nsCString& aScope,
    4885             :                                        const IPC::Principal& aPrincipal,
    4886             :                                        const nsString& aMessageId)
    4887             : {
    4888           0 :   PushMessageDispatcher dispatcher(aScope, aPrincipal, aMessageId, Nothing());
    4889           0 :   Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
    4890           0 :   return IPC_OK();
    4891             : }
    4892             : 
    4893             : mozilla::ipc::IPCResult
    4894           0 : ContentParent::RecvNotifyPushObserversWithData(const nsCString& aScope,
    4895             :                                                const IPC::Principal& aPrincipal,
    4896             :                                                const nsString& aMessageId,
    4897             :                                                InfallibleTArray<uint8_t>&& aData)
    4898             : {
    4899           0 :   PushMessageDispatcher dispatcher(aScope, aPrincipal, aMessageId, Some(aData));
    4900           0 :   Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
    4901           0 :   return IPC_OK();
    4902             : }
    4903             : 
    4904             : mozilla::ipc::IPCResult
    4905           0 : ContentParent::RecvNotifyPushSubscriptionChangeObservers(const nsCString& aScope,
    4906             :                                                          const IPC::Principal& aPrincipal)
    4907             : {
    4908           0 :   PushSubscriptionChangeDispatcher dispatcher(aScope, aPrincipal);
    4909           0 :   Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
    4910           0 :   return IPC_OK();
    4911             : }
    4912             : 
    4913             : mozilla::ipc::IPCResult
    4914           0 : ContentParent::RecvNotifyPushSubscriptionModifiedObservers(const nsCString& aScope,
    4915             :                                                            const IPC::Principal& aPrincipal)
    4916             : {
    4917           0 :   PushSubscriptionModifiedDispatcher dispatcher(aScope, aPrincipal);
    4918           0 :   Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
    4919           0 :   return IPC_OK();
    4920             : }
    4921             : 
    4922             : mozilla::ipc::IPCResult
    4923           0 : ContentParent::RecvNotifyLowMemory()
    4924             : {
    4925           0 :   MarkAsTroubled();
    4926             : 
    4927           0 :   Telemetry::ScalarAdd(Telemetry::ScalarID::DOM_CONTENTPROCESS_TROUBLED_DUE_TO_MEMORY, 1);
    4928             : 
    4929             : #ifdef MOZ_CRASHREPORTER
    4930           0 :   nsThread::SaveMemoryReportNearOOM(nsThread::ShouldSaveMemoryReport::kForceReport);
    4931             : #endif
    4932             : 
    4933           0 :   return IPC_OK();
    4934             : }
    4935             : 
    4936             : /* static */ void
    4937           0 : ContentParent::BroadcastBlobURLRegistration(const nsACString& aURI,
    4938             :                                             BlobImpl* aBlobImpl,
    4939             :                                             nsIPrincipal* aPrincipal,
    4940             :                                             ContentParent* aIgnoreThisCP)
    4941             : {
    4942           0 :   nsCString uri(aURI);
    4943           0 :   IPC::Principal principal(aPrincipal);
    4944             : 
    4945           0 :   for (auto* cp : AllProcesses(eLive)) {
    4946           0 :     if (cp != aIgnoreThisCP) {
    4947           0 :       IPCBlob ipcBlob;
    4948           0 :       nsresult rv = IPCBlobUtils::Serialize(aBlobImpl, cp, ipcBlob);
    4949           0 :       if (NS_WARN_IF(NS_FAILED(rv))) {
    4950           0 :         break;
    4951             :       }
    4952             : 
    4953           0 :       Unused << cp->SendBlobURLRegistration(uri, ipcBlob, principal);
    4954             :     }
    4955             :   }
    4956           0 : }
    4957             : 
    4958             : /* static */ void
    4959           0 : ContentParent::BroadcastBlobURLUnregistration(const nsACString& aURI,
    4960             :                                               ContentParent* aIgnoreThisCP)
    4961             : {
    4962           0 :   nsCString uri(aURI);
    4963             : 
    4964           0 :   for (auto* cp : AllProcesses(eLive)) {
    4965           0 :     if (cp != aIgnoreThisCP) {
    4966           0 :       Unused << cp->SendBlobURLUnregistration(uri);
    4967             :     }
    4968             :   }
    4969           0 : }
    4970             : 
    4971             : mozilla::ipc::IPCResult
    4972           0 : ContentParent::RecvStoreAndBroadcastBlobURLRegistration(const nsCString& aURI,
    4973             :                                                         const IPCBlob& aBlob,
    4974             :                                                         const Principal& aPrincipal)
    4975             : {
    4976           0 :   RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(aBlob);
    4977           0 :   if (NS_WARN_IF(!blobImpl)) {
    4978           0 :     return IPC_FAIL_NO_REASON(this);
    4979             :   }
    4980             : 
    4981           0 :   if (NS_SUCCEEDED(nsHostObjectProtocolHandler::AddDataEntry(aURI, aPrincipal,
    4982             :                                                              blobImpl))) {
    4983           0 :     BroadcastBlobURLRegistration(aURI, blobImpl, aPrincipal, this);
    4984             : 
    4985             :     // We want to store this blobURL, so we can unregister it if the child
    4986             :     // crashes.
    4987           0 :     mBlobURLs.AppendElement(aURI);
    4988             :   }
    4989             : 
    4990           0 :   BroadcastBlobURLRegistration(aURI, blobImpl, aPrincipal, this);
    4991           0 :   return IPC_OK();
    4992             : }
    4993             : 
    4994             : mozilla::ipc::IPCResult
    4995           0 : ContentParent::RecvUnstoreAndBroadcastBlobURLUnregistration(const nsCString& aURI)
    4996             : {
    4997           0 :   nsHostObjectProtocolHandler::RemoveDataEntry(aURI,
    4998           0 :                                                false /* Don't broadcast */);
    4999           0 :   BroadcastBlobURLUnregistration(aURI, this);
    5000           0 :   mBlobURLs.RemoveElement(aURI);
    5001             : 
    5002           0 :   return IPC_OK();
    5003             : }
    5004             : 
    5005             : mozilla::ipc::IPCResult
    5006           0 : ContentParent::RecvBroadcastLocalStorageChange(const nsString& aDocumentURI,
    5007             :                                                const nsString& aKey,
    5008             :                                                const nsString& aOldValue,
    5009             :                                                const nsString& aNewValue,
    5010             :                                                const Principal& aPrincipal,
    5011             :                                                const bool& aIsPrivate)
    5012             : {
    5013           0 :   for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) {
    5014           0 :     if (cp != this) {
    5015           0 :       Unused << cp->SendDispatchLocalStorageChange(
    5016           0 :         nsString(aDocumentURI), nsString(aKey), nsString(aOldValue),
    5017           0 :         nsString(aNewValue), IPC::Principal(aPrincipal), aIsPrivate);
    5018             :     }
    5019             :   }
    5020             : 
    5021           0 :   return IPC_OK();
    5022             : }
    5023             : 
    5024             : mozilla::ipc::IPCResult
    5025           0 : ContentParent::RecvGetA11yContentId(uint32_t* aContentId)
    5026             : {
    5027             : #if defined(XP_WIN32) && defined(ACCESSIBILITY)
    5028             :   *aContentId = a11y::AccessibleWrap::GetContentProcessIdFor(ChildID());
    5029             :   MOZ_ASSERT(*aContentId);
    5030             :   return IPC_OK();
    5031             : #else
    5032           0 :   return IPC_FAIL_NO_REASON(this);
    5033             : #endif
    5034             : }
    5035             : 
    5036             : mozilla::ipc::IPCResult
    5037           0 : ContentParent::RecvA11yHandlerControl(const uint32_t& aPid,
    5038             :                                       const IHandlerControlHolder& aHandlerControl)
    5039             : {
    5040             : #if defined(XP_WIN32) && defined(ACCESSIBILITY)
    5041             :   MOZ_ASSERT(!aHandlerControl.IsNull());
    5042             :   RefPtr<IHandlerControl> proxy(aHandlerControl.Get());
    5043             :   a11y::AccessibleWrap::SetHandlerControl(aPid, Move(proxy));
    5044             :   return IPC_OK();
    5045             : #else
    5046           0 :   return IPC_FAIL_NO_REASON(this);
    5047             : #endif
    5048             : }
    5049             : 
    5050             : } // namespace dom
    5051             : } // namespace mozilla
    5052             : 
    5053           0 : NS_IMPL_ISUPPORTS(ParentIdleListener, nsIObserver)
    5054             : 
    5055             : NS_IMETHODIMP
    5056           0 : ParentIdleListener::Observe(nsISupports*, const char* aTopic, const char16_t* aData)
    5057             : {
    5058           0 :   mozilla::Unused << mParent->SendNotifyIdleObserver(mObserver,
    5059           0 :                                                      nsDependentCString(aTopic),
    5060           0 :                                                      nsDependentString(aData));
    5061           0 :   return NS_OK;
    5062             : }
    5063             : 
    5064             : bool
    5065           0 : ContentParent::HandleWindowsMessages(const Message& aMsg) const
    5066             : {
    5067           0 :   MOZ_ASSERT(aMsg.is_sync());
    5068             : 
    5069             :   // a11y messages can be triggered by windows messages, which means if we
    5070             :   // allow handling windows messages while we wait for the response to a sync
    5071             :   // a11y message we can reenter the ipc message sending code.
    5072           0 :   if (a11y::PDocAccessible::PDocAccessibleStart < aMsg.type() &&
    5073           0 :       a11y::PDocAccessible::PDocAccessibleEnd > aMsg.type()) {
    5074           0 :     return false;
    5075             :   }
    5076             : 
    5077           0 :   return true;
    5078             : }
    5079             : 
    5080             : mozilla::ipc::IPCResult
    5081           0 : ContentParent::RecvGetFilesRequest(const nsID& aUUID,
    5082             :                                    const nsString& aDirectoryPath,
    5083             :                                    const bool& aRecursiveFlag)
    5084             : {
    5085           0 :   MOZ_ASSERT(!mGetFilesPendingRequests.GetWeak(aUUID));
    5086             : 
    5087           0 :   ErrorResult rv;
    5088             :   RefPtr<GetFilesHelper> helper =
    5089           0 :     GetFilesHelperParent::Create(aUUID, aDirectoryPath, aRecursiveFlag, this,
    5090           0 :                                  rv);
    5091             : 
    5092           0 :   if (NS_WARN_IF(rv.Failed())) {
    5093           0 :     if (!SendGetFilesResponse(aUUID,
    5094           0 :                               GetFilesResponseFailure(rv.StealNSResult()))) {
    5095           0 :       return IPC_FAIL_NO_REASON(this);
    5096             :     }
    5097           0 :     return IPC_OK();
    5098             :   }
    5099             : 
    5100           0 :   mGetFilesPendingRequests.Put(aUUID, helper);
    5101           0 :   return IPC_OK();
    5102             : }
    5103             : 
    5104             : mozilla::ipc::IPCResult
    5105           0 : ContentParent::RecvDeleteGetFilesRequest(const nsID& aUUID)
    5106             : {
    5107           0 :   mGetFilesPendingRequests.Remove(aUUID);
    5108           0 :   return IPC_OK();
    5109             : }
    5110             : 
    5111             : void
    5112           0 : ContentParent::SendGetFilesResponseAndForget(const nsID& aUUID,
    5113             :                                              const GetFilesResponseResult& aResult)
    5114             : {
    5115           0 :   if (mGetFilesPendingRequests.Remove(aUUID)) {
    5116           0 :     Unused << SendGetFilesResponse(aUUID, aResult);
    5117             :   }
    5118           0 : }
    5119             : 
    5120             : void
    5121           2 : ContentParent::ForceTabPaint(TabParent* aTabParent, uint64_t aLayerObserverEpoch)
    5122             : {
    5123           2 :   if (!mHangMonitorActor) {
    5124           0 :     return;
    5125             :   }
    5126           2 :   ProcessHangMonitor::ForcePaint(mHangMonitorActor, aTabParent, aLayerObserverEpoch);
    5127             : }
    5128             : 
    5129             : nsresult
    5130           3 : ContentParent::AboutToLoadHttpFtpWyciwygDocumentForChild(nsIChannel* aChannel)
    5131             : {
    5132           3 :   MOZ_ASSERT(aChannel);
    5133             : 
    5134             :   nsresult rv;
    5135           3 :   if (!aChannel->IsDocument()) {
    5136           2 :     return NS_OK;
    5137             :   }
    5138             : 
    5139             :   // Get the principal for the channel result, so that we can get the permission
    5140             :   // key for the document which will be created from this response.
    5141           1 :   nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
    5142           1 :   if (NS_WARN_IF(!ssm)) {
    5143           0 :     return NS_ERROR_FAILURE;
    5144             :   }
    5145             : 
    5146           2 :   nsCOMPtr<nsIPrincipal> principal;
    5147           1 :   rv = ssm->GetChannelResultPrincipal(aChannel, getter_AddRefs(principal));
    5148           1 :   NS_ENSURE_SUCCESS(rv, rv);
    5149             : 
    5150           1 :   rv = TransmitPermissionsForPrincipal(principal);
    5151           1 :   NS_ENSURE_SUCCESS(rv, rv);
    5152             : 
    5153           1 :   return NS_OK;
    5154             : }
    5155             : 
    5156             : nsresult
    5157           1 : ContentParent::TransmitPermissionsForPrincipal(nsIPrincipal* aPrincipal)
    5158             : {
    5159             : #ifdef MOZ_PERMISSIONS
    5160             :   // Create the key, and send it down to the content process.
    5161             :   nsTArray<nsCString> keys =
    5162           2 :     nsPermissionManager::GetAllKeysForPrincipal(aPrincipal);
    5163           1 :   MOZ_ASSERT(keys.Length() >= 1);
    5164           2 :   for (auto& key : keys) {
    5165           1 :     EnsurePermissionsByKey(key);
    5166             :   }
    5167             : #endif
    5168             : 
    5169           2 :   return NS_OK;
    5170             : }
    5171             : 
    5172             : void
    5173           3 : ContentParent::EnsurePermissionsByKey(const nsCString& aKey)
    5174             : {
    5175             : #ifdef MOZ_PERMISSIONS
    5176             :   // NOTE: Make sure to initialize the permission manager before updating the
    5177             :   // mActivePermissionKeys list. If the permission manager is being initialized
    5178             :   // by this call to GetPermissionManager, and we've added the key to
    5179             :   // mActivePermissionKeys, then the permission manager will send down a
    5180             :   // SendAddPermission before receiving the SendSetPermissionsWithKey message.
    5181             :   nsCOMPtr<nsIPermissionManager> permManager =
    5182           6 :     services::GetPermissionManager();
    5183             : 
    5184           3 :   if (mActivePermissionKeys.Contains(aKey)) {
    5185           0 :     return;
    5186             :   }
    5187           3 :   mActivePermissionKeys.PutEntry(aKey);
    5188             : 
    5189           6 :   nsTArray<IPC::Permission> perms;
    5190           3 :   nsresult rv = permManager->GetPermissionsWithKey(aKey, perms);
    5191           3 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    5192           0 :     return;
    5193             :   }
    5194             : 
    5195           3 :   Unused << SendSetPermissionsWithKey(aKey, perms);
    5196             : #endif
    5197             : }
    5198             : 
    5199             : bool
    5200           0 : ContentParent::NeedsPermissionsUpdate(const nsACString& aPermissionKey) const
    5201             : {
    5202           0 :   return mActivePermissionKeys.Contains(aPermissionKey);
    5203             : }
    5204             : 
    5205             : mozilla::ipc::IPCResult
    5206           2 : ContentParent::RecvAccumulateChildHistograms(
    5207             :                 InfallibleTArray<Accumulation>&& aAccumulations)
    5208             : {
    5209           2 :   TelemetryIPC::AccumulateChildHistograms(GetTelemetryProcessID(mRemoteType), aAccumulations);
    5210           2 :   return IPC_OK();
    5211             : }
    5212             : 
    5213             : mozilla::ipc::IPCResult
    5214           2 : ContentParent::RecvAccumulateChildKeyedHistograms(
    5215             :                 InfallibleTArray<KeyedAccumulation>&& aAccumulations)
    5216             : {
    5217           2 :   TelemetryIPC::AccumulateChildKeyedHistograms(GetTelemetryProcessID(mRemoteType), aAccumulations);
    5218           2 :   return IPC_OK();
    5219             : }
    5220             : 
    5221             : mozilla::ipc::IPCResult
    5222           0 : ContentParent::RecvUpdateChildScalars(
    5223             :                 InfallibleTArray<ScalarAction>&& aScalarActions)
    5224             : {
    5225           0 :   TelemetryIPC::UpdateChildScalars(GetTelemetryProcessID(mRemoteType), aScalarActions);
    5226           0 :   return IPC_OK();
    5227             : }
    5228             : 
    5229             : mozilla::ipc::IPCResult
    5230           0 : ContentParent::RecvUpdateChildKeyedScalars(
    5231             :                 InfallibleTArray<KeyedScalarAction>&& aScalarActions)
    5232             : {
    5233           0 :   TelemetryIPC::UpdateChildKeyedScalars(GetTelemetryProcessID(mRemoteType), aScalarActions);
    5234           0 :   return IPC_OK();
    5235             : }
    5236             : 
    5237             : mozilla::ipc::IPCResult
    5238           0 : ContentParent::RecvRecordChildEvents(nsTArray<mozilla::Telemetry::ChildEventData>&& aEvents)
    5239             : {
    5240           0 :   TelemetryIPC::RecordChildEvents(GetTelemetryProcessID(mRemoteType), aEvents);
    5241           0 :   return IPC_OK();
    5242             : }
    5243             : 
    5244             : mozilla::ipc::IPCResult
    5245           2 : ContentParent::RecvRecordDiscardedData(
    5246             :                 const mozilla::Telemetry::DiscardedData& aDiscardedData)
    5247             : {
    5248           2 :   TelemetryIPC::RecordDiscardedData(GetTelemetryProcessID(mRemoteType),
    5249           2 :                                     aDiscardedData);
    5250           2 :   return IPC_OK();
    5251             : }
    5252             : 
    5253             : //////////////////////////////////////////////////////////////////
    5254             : // PURLClassifierParent
    5255             : 
    5256             : PURLClassifierParent*
    5257           0 : ContentParent::AllocPURLClassifierParent(const Principal& aPrincipal,
    5258             :                                          const bool& aUseTrackingProtection,
    5259             :                                          bool* aSuccess)
    5260             : {
    5261           0 :   MOZ_ASSERT(NS_IsMainThread());
    5262             : 
    5263           0 :   *aSuccess = true;
    5264           0 :   RefPtr<URLClassifierParent> actor = new URLClassifierParent();
    5265           0 :   return actor.forget().take();
    5266             : }
    5267             : 
    5268             : mozilla::ipc::IPCResult
    5269           0 : ContentParent::RecvPURLClassifierConstructor(PURLClassifierParent* aActor,
    5270             :                                              const Principal& aPrincipal,
    5271             :                                              const bool& aUseTrackingProtection,
    5272             :                                              bool* aSuccess)
    5273             : {
    5274           0 :   MOZ_ASSERT(NS_IsMainThread());
    5275           0 :   MOZ_ASSERT(aActor);
    5276           0 :   *aSuccess = false;
    5277             : 
    5278           0 :   auto* actor = static_cast<URLClassifierParent*>(aActor);
    5279           0 :   nsCOMPtr<nsIPrincipal> principal(aPrincipal);
    5280           0 :   if (!principal) {
    5281           0 :     actor->ClassificationFailed();
    5282           0 :     return IPC_OK();
    5283             :   }
    5284           0 :   return actor->StartClassify(principal, aUseTrackingProtection, aSuccess);
    5285             : }
    5286             : 
    5287             : bool
    5288           0 : ContentParent::DeallocPURLClassifierParent(PURLClassifierParent* aActor)
    5289             : {
    5290           0 :   MOZ_ASSERT(NS_IsMainThread());
    5291           0 :   MOZ_ASSERT(aActor);
    5292             : 
    5293             :   RefPtr<URLClassifierParent> actor =
    5294           0 :     dont_AddRef(static_cast<URLClassifierParent*>(aActor));
    5295           0 :   return true;
    5296             : }
    5297             : 
    5298             : //////////////////////////////////////////////////////////////////
    5299             : // PURLClassifierLocalParent
    5300             : 
    5301             : PURLClassifierLocalParent*
    5302           0 : ContentParent::AllocPURLClassifierLocalParent(const URIParams& aURI,
    5303             :                                               const nsCString& aTables)
    5304             : {
    5305           0 :   MOZ_ASSERT(NS_IsMainThread());
    5306             : 
    5307           0 :   RefPtr<URLClassifierLocalParent> actor = new URLClassifierLocalParent();
    5308           0 :   return actor.forget().take();
    5309             : }
    5310             : 
    5311             : mozilla::ipc::IPCResult
    5312           0 : ContentParent::RecvPURLClassifierLocalConstructor(PURLClassifierLocalParent* aActor,
    5313             :                                                   const URIParams& aURI,
    5314             :                                                   const nsCString& aTables)
    5315             : {
    5316           0 :   MOZ_ASSERT(NS_IsMainThread());
    5317           0 :   MOZ_ASSERT(aActor);
    5318             : 
    5319           0 :   nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
    5320           0 :   if (!uri) {
    5321           0 :     NS_WARNING("Failed to DeserializeURI");
    5322           0 :     return IPC_FAIL_NO_REASON(this);
    5323             :   }
    5324             : 
    5325           0 :   auto* actor = static_cast<URLClassifierLocalParent*>(aActor);
    5326           0 :   return actor->StartClassify(uri, aTables);
    5327             : }
    5328             : 
    5329             : bool
    5330           0 : ContentParent::DeallocPURLClassifierLocalParent(PURLClassifierLocalParent* aActor)
    5331             : {
    5332           0 :   MOZ_ASSERT(NS_IsMainThread());
    5333           0 :   MOZ_ASSERT(aActor);
    5334             : 
    5335             :   RefPtr<URLClassifierLocalParent> actor =
    5336           0 :     dont_AddRef(static_cast<URLClassifierLocalParent*>(aActor));
    5337           0 :   return true;
    5338             : }
    5339             : 
    5340             : mozilla::ipc::IPCResult
    5341           0 : ContentParent::RecvClassifyLocal(const URIParams& aURI, const nsCString& aTables,
    5342             :                                  nsresult *aRv, nsTArray<nsCString>* aResults)
    5343             : {
    5344           0 :   MOZ_ASSERT(aResults);
    5345           0 :   nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
    5346           0 :   if (!uri) {
    5347           0 :     return IPC_FAIL_NO_REASON(this);
    5348             :   }
    5349             :   nsCOMPtr<nsIURIClassifier> uriClassifier =
    5350           0 :     do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID);
    5351           0 :   if (!uriClassifier) {
    5352           0 :     return IPC_FAIL_NO_REASON(this);
    5353             :   }
    5354           0 :   *aRv = uriClassifier->ClassifyLocalWithTables(uri, aTables, *aResults);
    5355           0 :   return IPC_OK();
    5356             : }
    5357             : 
    5358             : mozilla::ipc::IPCResult
    5359           0 : ContentParent::RecvFileCreationRequest(const nsID& aID,
    5360             :                                        const nsString& aFullPath,
    5361             :                                        const nsString& aType,
    5362             :                                        const nsString& aName,
    5363             :                                        const bool& aLastModifiedPassed,
    5364             :                                        const int64_t& aLastModified,
    5365             :                                        const bool& aExistenceCheck,
    5366             :                                        const bool& aIsFromNsIFile)
    5367             : {
    5368             :   // We allow the creation of File via this IPC call only for the 'file' process
    5369             :   // or for testing.
    5370           0 :   if (!mRemoteType.EqualsLiteral(FILE_REMOTE_TYPE) &&
    5371           0 :       !Preferences::GetBool("dom.file.createInChild", false)) {
    5372           0 :     KillHard("FileCreationRequest is not supported.");
    5373           0 :     return IPC_FAIL_NO_REASON(this);
    5374             :   }
    5375             : 
    5376           0 :   RefPtr<BlobImpl> blobImpl;
    5377             :   nsresult rv =
    5378           0 :     FileCreatorHelper::CreateBlobImplForIPC(aFullPath, aType, aName,
    5379           0 :                                             aLastModifiedPassed,
    5380           0 :                                             aLastModified, aExistenceCheck,
    5381           0 :                                             aIsFromNsIFile,
    5382           0 :                                             getter_AddRefs(blobImpl));
    5383           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    5384           0 :     if (!SendFileCreationResponse(aID, FileCreationErrorResult(rv))) {
    5385           0 :       return IPC_FAIL_NO_REASON(this);
    5386             :     }
    5387             : 
    5388           0 :     return IPC_OK();
    5389             :   }
    5390             : 
    5391           0 :   MOZ_ASSERT(blobImpl);
    5392             : 
    5393           0 :   IPCBlob ipcBlob;
    5394           0 :   rv = IPCBlobUtils::Serialize(blobImpl, this, ipcBlob);
    5395           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    5396           0 :     if (!SendFileCreationResponse(aID, FileCreationErrorResult(rv))) {
    5397           0 :       return IPC_FAIL_NO_REASON(this);
    5398             :     }
    5399             : 
    5400           0 :     return IPC_OK();
    5401             :   }
    5402             : 
    5403           0 :   if (!SendFileCreationResponse(aID, FileCreationSuccessResult(ipcBlob))) {
    5404           0 :     return IPC_FAIL_NO_REASON(this);
    5405             :   }
    5406             : 
    5407           0 :   return IPC_OK();
    5408             : }
    5409             : 
    5410             : bool
    5411           0 : ContentParent::CanCommunicateWith(ContentParentId aOtherProcess)
    5412             : {
    5413             :   // Normally a process can only communicate with its parent, but a JS plugin process can
    5414             :   // communicate with any process.
    5415           0 :   ContentProcessManager *cpm = ContentProcessManager::GetSingleton();
    5416           0 :   ContentParentId parentId;
    5417           0 :   if (!cpm->GetParentProcessId(ChildID(), &parentId)) {
    5418           0 :     return false;
    5419             :   }
    5420           0 :   if (IsForJSPlugin()) {
    5421           0 :     return parentId == ContentParentId(0);
    5422             :   }
    5423           0 :   return parentId == aOtherProcess;
    5424             : }
    5425             : 
    5426             : mozilla::ipc::IPCResult
    5427           0 : ContentParent::RecvMaybeReloadPlugins()
    5428             : {
    5429           0 :   RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
    5430           0 :   pluginHost->ReloadPlugins();
    5431           0 :   return IPC_OK();
    5432             : }
    5433             : 
    5434             : mozilla::ipc::IPCResult
    5435           0 : ContentParent::RecvDeviceReset()
    5436             : {
    5437           0 :   GPUProcessManager* pm = GPUProcessManager::Get();
    5438           0 :   if (pm) {
    5439           0 :     pm->SimulateDeviceReset();
    5440             :   }
    5441             : 
    5442           0 :   return IPC_OK();
    5443             : }

Generated by: LCOV version 1.13