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

Generated by: LCOV version 1.13-14-ga5dd952