1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim: set sw=4 ts=8 et 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/. */
12 #include "nsQAppInstance.h"
15 #include "ContentChild.h"
16 #include "CrashReporterChild.h"
17 #include "FileDescriptorSetChild.h"
20 #include "mozilla/Attributes.h"
21 #include "mozilla/Preferences.h"
22 #include "mozilla/dom/ContentBridgeChild.h"
23 #include "mozilla/dom/ContentBridgeParent.h"
24 #include "mozilla/dom/DOMStorageIPC.h"
25 #include "mozilla/dom/ExternalHelperAppChild.h"
26 #include "mozilla/dom/PCrashReporterChild.h"
27 #include "mozilla/dom/Promise.h"
28 #include "mozilla/dom/asmjscache/AsmJSCache.h"
29 #include "mozilla/dom/asmjscache/PAsmJSCacheEntryChild.h"
30 #include "mozilla/dom/nsIContentChild.h"
31 #include "mozilla/hal_sandbox/PHalChild.h"
32 #include "mozilla/ipc/BackgroundChild.h"
33 #include "mozilla/ipc/FileDescriptorUtils.h"
34 #include "mozilla/ipc/GeckoChildProcessHost.h"
35 #include "mozilla/ipc/TestShellChild.h"
36 #include "mozilla/layers/CompositorChild.h"
37 #include "mozilla/layers/ImageBridgeChild.h"
38 #include "mozilla/layers/PCompositorChild.h"
39 #include "mozilla/layers/SharedBufferManagerChild.h"
40 #include "mozilla/net/NeckoChild.h"
42 #if defined(MOZ_CONTENT_SANDBOX)
44 #define TARGET_SANDBOX_EXPORTS
45 #include "mozilla/sandboxTarget.h"
46 #elif defined(XP_LINUX)
47 #include "mozilla/Sandbox.h"
51 #include "mozilla/unused.h"
53 #include "nsIConsoleListener.h"
54 #include "nsICycleCollectorListener.h"
55 #include "nsIIPCBackgroundChildCreateCallback.h"
56 #include "nsIInterfaceRequestorUtils.h"
57 #include "nsIMemoryReporter.h"
58 #include "nsIMemoryInfoDumper.h"
59 #include "nsIMutable.h"
60 #include "nsIObserverService.h"
61 #include "nsIScriptSecurityManager.h"
62 #include "nsScreenManagerProxy.h"
63 #include "nsMemoryInfoDumper.h"
64 #include "nsServiceManagerUtils.h"
65 #include "nsStyleSheetService.h"
66 #include "nsXULAppAPI.h"
67 #include "nsIScriptError.h"
68 #include "nsIConsoleService.h"
69 #include "nsJSEnvironment.h"
70 #include "SandboxHal.h"
71 #include "nsDebugImpl.h"
72 #include "nsHashPropertyBag.h"
73 #include "nsLayoutStylesheetCache.h"
74 #include "nsIJSRuntimeService.h"
75 #include "nsThreadManager.h"
76 #include "nsAnonymousTemporaryFile.h"
79 #include "nsNetUtil.h"
81 #include "base/message_loop.h"
82 #include "base/process_util.h"
83 #include "base/task.h"
85 #include "nsChromeRegistryContent.h"
86 #include "nsFrameMessageManager.h"
88 #include "nsIGeolocationProvider.h"
89 #include "mozilla/dom/PMemoryReportRequestChild.h"
90 #include "mozilla/dom/PCycleCollectWithLogsChild.h"
92 #ifdef MOZ_PERMISSIONS
93 #include "nsIScriptSecurityManager.h"
94 #include "nsPermission.h"
95 #include "nsPermissionManager.h"
98 #include "PermissionMessageUtils.h"
100 #if defined(MOZ_WIDGET_ANDROID)
104 #if defined(MOZ_WIDGET_GONK)
105 #include "nsVolume.h"
106 #include "nsVolumeService.h"
107 #include "SpeakerManagerService.h"
112 #define getpid _getpid
116 #include "mozilla/X11Util.h"
120 #include "nsIAccessibilityService.h"
123 #ifdef MOZ_NUWA_PROCESS
125 #include "ipc/Nuwa.h"
128 #include "mozilla/dom/indexedDB/PIndexedDBChild.h"
129 #include "mozilla/dom/mobilemessage/SmsChild.h"
130 #include "mozilla/dom/devicestorage/DeviceStorageRequestChild.h"
131 #include "mozilla/dom/PFileSystemRequestChild.h"
132 #include "mozilla/dom/FileSystemTaskBase.h"
133 #include "mozilla/dom/bluetooth/PBluetoothChild.h"
134 #include "mozilla/dom/PFMRadioChild.h"
135 #include "mozilla/ipc/InputStreamUtils.h"
138 #include "mozilla/dom/PSpeechSynthesisChild.h"
141 #include "nsDOMFile.h"
142 #include "nsIRemoteBlob.h"
143 #include "ProcessUtils.h"
144 #include "StructuredCloneUtils.h"
145 #include "URIUtils.h"
146 #include "nsContentUtils.h"
147 #include "nsIPrincipal.h"
148 #include "nsDeviceStorage.h"
149 #include "AudioChannelService.h"
150 #include "JavaScriptChild.h"
151 #include "mozilla/dom/DataStoreService.h"
152 #include "mozilla/dom/telephony/PTelephonyChild.h"
153 #include "mozilla/dom/time/DateCacheCleaner.h"
154 #include "mozilla/net/NeckoMessageUtils.h"
155 #include "mozilla/RemoteSpellCheckEngineChild.h"
157 using namespace base
;
158 using namespace mozilla
;
159 using namespace mozilla::docshell
;
160 using namespace mozilla::dom::bluetooth
;
161 using namespace mozilla::dom::devicestorage
;
162 using namespace mozilla::dom::ipc
;
163 using namespace mozilla::dom::mobilemessage
;
164 using namespace mozilla::dom::indexedDB
;
165 using namespace mozilla::dom::telephony
;
166 using namespace mozilla::hal_sandbox
;
167 using namespace mozilla::ipc
;
168 using namespace mozilla::layers
;
169 using namespace mozilla::net
;
170 using namespace mozilla::jsipc
;
171 #if defined(MOZ_WIDGET_GONK)
172 using namespace mozilla::system
;
174 using namespace mozilla::widget
;
176 #ifdef MOZ_NUWA_PROCESS
177 static bool sNuwaForking
= false;
179 // The size of the reserved stack (in unsigned ints). It's used to reserve space
180 // to push sigsetjmp() in NuwaCheckpointCurrentThread() to higher in the stack
181 // so that after it returns and do other work we don't garble the stack we want
182 // to preserve in NuwaCheckpointCurrentThread().
183 #define RESERVED_INT_STACK 128
185 // A sentinel value for checking whether RESERVED_INT_STACK is large enough.
186 #define STACK_SENTINEL_VALUE 0xdeadbeef
192 class MemoryReportRequestChild
: public PMemoryReportRequestChild
,
198 MemoryReportRequestChild(uint32_t aGeneration
, bool aAnonymize
,
199 const FileDescriptor
& aDMDFile
);
202 virtual ~MemoryReportRequestChild();
204 uint32_t mGeneration
;
206 FileDescriptor mDMDFile
;
209 NS_IMPL_ISUPPORTS(MemoryReportRequestChild
, nsIRunnable
)
211 MemoryReportRequestChild::MemoryReportRequestChild(
212 uint32_t aGeneration
, bool aAnonymize
, const FileDescriptor
& aDMDFile
)
213 : mGeneration(aGeneration
), mAnonymize(aAnonymize
),
216 MOZ_COUNT_CTOR(MemoryReportRequestChild
);
219 MemoryReportRequestChild::~MemoryReportRequestChild()
221 MOZ_COUNT_DTOR(MemoryReportRequestChild
);
224 // IPC sender for remote GC/CC logging.
225 class CycleCollectWithLogsChild MOZ_FINAL
226 : public PCycleCollectWithLogsChild
227 , public nsICycleCollectorLogSink
232 CycleCollectWithLogsChild(const FileDescriptor
& aGCLog
,
233 const FileDescriptor
& aCCLog
)
235 mGCLog
= FileDescriptorToFILE(aGCLog
, "w");
236 mCCLog
= FileDescriptorToFILE(aCCLog
, "w");
239 NS_IMETHOD
Open(FILE** aGCLog
, FILE** aCCLog
) MOZ_OVERRIDE
241 if (NS_WARN_IF(!mGCLog
) || NS_WARN_IF(!mCCLog
)) {
242 return NS_ERROR_FAILURE
;
249 NS_IMETHOD
CloseGCLog() MOZ_OVERRIDE
258 NS_IMETHOD
CloseCCLog() MOZ_OVERRIDE
267 NS_IMETHOD
GetFilenameIdentifier(nsAString
& aIdentifier
) MOZ_OVERRIDE
269 return UnimplementedProperty();
272 NS_IMETHOD
SetFilenameIdentifier(const nsAString
& aIdentifier
) MOZ_OVERRIDE
274 return UnimplementedProperty();
277 NS_IMETHOD
GetProcessIdentifier(int32_t *aIdentifier
) MOZ_OVERRIDE
279 return UnimplementedProperty();
282 NS_IMETHOD
SetProcessIdentifier(int32_t aIdentifier
) MOZ_OVERRIDE
284 return UnimplementedProperty();
287 NS_IMETHOD
GetGcLog(nsIFile
** aPath
) MOZ_OVERRIDE
289 return UnimplementedProperty();
292 NS_IMETHOD
GetCcLog(nsIFile
** aPath
) MOZ_OVERRIDE
294 return UnimplementedProperty();
298 ~CycleCollectWithLogsChild()
308 // The XPCOM refcount drives the IPC lifecycle; see also
309 // DeallocPCycleCollectWithLogsChild.
310 unused
<< Send__delete__(this);
313 nsresult
UnimplementedProperty()
315 MOZ_ASSERT(false, "This object is a remote GC/CC logger;"
316 " this property isn't meaningful.");
317 return NS_ERROR_UNEXPECTED
;
324 NS_IMPL_ISUPPORTS(CycleCollectWithLogsChild
, nsICycleCollectorLogSink
);
330 AlertObserver(nsIObserver
*aObserver
, const nsString
& aData
)
331 : mObserver(aObserver
)
338 bool ShouldRemoveFrom(nsIObserver
* aObserver
,
339 const nsString
& aData
) const
341 return (mObserver
== aObserver
&&
345 bool Observes(const nsString
& aData
) const
347 return mData
.Equals(aData
);
350 bool Notify(const nsCString
& aType
) const
352 mObserver
->Observe(nullptr, aType
.get(), mData
.get());
357 nsCOMPtr
<nsIObserver
> mObserver
;
361 class ConsoleListener MOZ_FINAL
: public nsIConsoleListener
364 explicit ConsoleListener(ContentChild
* aChild
)
368 NS_DECL_NSICONSOLELISTENER
371 ~ConsoleListener() {}
373 ContentChild
* mChild
;
374 friend class ContentChild
;
377 NS_IMPL_ISUPPORTS(ConsoleListener
, nsIConsoleListener
)
380 ConsoleListener::Observe(nsIConsoleMessage
* aMessage
)
385 nsCOMPtr
<nsIScriptError
> scriptError
= do_QueryInterface(aMessage
);
387 nsString msg
, sourceName
, sourceLine
;
388 nsXPIDLCString category
;
389 uint32_t lineNum
, colNum
, flags
;
391 nsresult rv
= scriptError
->GetErrorMessage(msg
);
392 NS_ENSURE_SUCCESS(rv
, rv
);
393 rv
= scriptError
->GetSourceName(sourceName
);
394 NS_ENSURE_SUCCESS(rv
, rv
);
395 rv
= scriptError
->GetSourceLine(sourceLine
);
396 NS_ENSURE_SUCCESS(rv
, rv
);
398 // Before we send the error to the parent process (which
399 // involves copying the memory), truncate any long lines. CSS
400 // errors in particular share the memory for long lines with
401 // repeated errors, but the IPC communication we're about to do
402 // will break that sharing, so we better truncate now.
403 if (sourceLine
.Length() > 1000) {
404 sourceLine
.Truncate(1000);
407 rv
= scriptError
->GetCategory(getter_Copies(category
));
408 NS_ENSURE_SUCCESS(rv
, rv
);
409 rv
= scriptError
->GetLineNumber(&lineNum
);
410 NS_ENSURE_SUCCESS(rv
, rv
);
411 rv
= scriptError
->GetColumnNumber(&colNum
);
412 NS_ENSURE_SUCCESS(rv
, rv
);
413 rv
= scriptError
->GetFlags(&flags
);
414 NS_ENSURE_SUCCESS(rv
, rv
);
415 mChild
->SendScriptError(msg
, sourceName
, sourceLine
,
416 lineNum
, colNum
, flags
, category
);
421 nsresult rv
= aMessage
->GetMessageMoz(getter_Copies(msg
));
422 NS_ENSURE_SUCCESS(rv
, rv
);
423 mChild
->SendConsoleMessage(msg
);
427 class SystemMessageHandledObserver MOZ_FINAL
: public nsIObserver
429 ~SystemMessageHandledObserver() {}
438 void SystemMessageHandledObserver::Init()
440 nsCOMPtr
<nsIObserverService
> os
=
441 mozilla::services::GetObserverService();
444 os
->AddObserver(this, "handle-system-messages-done",
445 /* ownsWeak */ false);
450 SystemMessageHandledObserver::Observe(nsISupports
* aSubject
,
452 const char16_t
* aData
)
454 if (ContentChild::GetSingleton()) {
455 ContentChild::GetSingleton()->SendSystemMessageHandled();
460 NS_IMPL_ISUPPORTS(SystemMessageHandledObserver
, nsIObserver
)
462 class BackgroundChildPrimer MOZ_FINAL
:
463 public nsIIPCBackgroundChildCreateCallback
466 BackgroundChildPrimer()
472 ~BackgroundChildPrimer()
476 ActorCreated(PBackgroundChild
* aActor
) MOZ_OVERRIDE
478 MOZ_ASSERT(aActor
, "Failed to create a PBackgroundChild actor!");
482 ActorFailed() MOZ_OVERRIDE
484 MOZ_CRASH("Failed to create a PBackgroundChild actor!");
488 NS_IMPL_ISUPPORTS(BackgroundChildPrimer
, nsIIPCBackgroundChildCreateCallback
)
490 ContentChild
* ContentChild::sSingleton
;
492 // Performs initialization that is not fork-safe, i.e. that must be done after
493 // forking from the Nuwa process.
495 InitOnContentProcessCreated()
497 #ifdef MOZ_NUWA_PROCESS
498 // Wait until we are forked from Nuwa
499 if (IsNuwaProcess()) {
504 // This will register cross-process observer.
505 mozilla::dom::time::InitializeDateCacheCleaner();
508 ContentChild::ContentChild()
513 , mCanOverrideProcessName(true)
515 // This process is a content process, so it's clearly running in
516 // multiprocess mode!
517 nsDebugImpl::SetMultiprocessMode("Child");
520 ContentChild::~ContentChild()
524 NS_INTERFACE_MAP_BEGIN(ContentChild
)
525 NS_INTERFACE_MAP_ENTRY(nsIContentChild
)
526 NS_INTERFACE_MAP_ENTRY(nsISupports
)
530 ContentChild::Init(MessageLoop
* aIOLoop
,
531 base::ProcessHandle aParentHandle
,
532 IPC::Channel
* aChannel
)
534 #ifdef MOZ_WIDGET_GTK
536 gtk_init(nullptr, nullptr);
541 nsQAppInstance::AddRef();
545 // Do this after initializing GDK, or GDK will install its own handler.
546 XRE_InstallX11ErrorHandler();
549 #ifdef MOZ_NUWA_PROCESS
550 SetTransport(aChannel
);
553 NS_ASSERTION(!sSingleton
, "only one ContentChild per child");
555 // Once we start sending IPC messages, we need the thread manager to be
556 // initialized so we can deal with the responses. Do that here before we
557 // try to construct the crash reporter.
558 nsresult rv
= nsThreadManager::get()->Init();
559 if (NS_WARN_IF(NS_FAILED(rv
))) {
563 Open(aChannel
, aParentHandle
, aIOLoop
);
566 // Make sure there's an nsAutoScriptBlocker on the stack when dispatching
568 GetIPCChannel()->BlockScripts();
571 // Send the parent our X socket to act as a proxy reference for our X
573 int xSocketFd
= ConnectionNumber(DefaultXDisplay());
574 SendBackUpXResources(FileDescriptor(xSocketFd
));
577 #ifdef MOZ_CRASHREPORTER
578 SendPCrashReporterConstructor(CrashReporter::CurrentThreadId(),
579 XRE_GetProcessType());
584 SendGetProcessAttributes(&mID
, &mIsForApp
, &mIsForBrowser
);
585 InitProcessAttributes();
591 ContentChild::InitProcessAttributes()
593 #ifdef MOZ_WIDGET_GONK
594 #ifdef MOZ_NUWA_PROCESS
595 if (IsNuwaProcess()) {
596 SetProcessName(NS_LITERAL_STRING("(Nuwa)"), false);
600 if (mIsForApp
&& !mIsForBrowser
) {
601 SetProcessName(NS_LITERAL_STRING("(Preallocated app)"), false);
603 SetProcessName(NS_LITERAL_STRING("Browser"), false);
606 SetProcessName(NS_LITERAL_STRING("Web Content"), true);
611 ContentChild::SetProcessName(const nsAString
& aName
, bool aDontOverride
)
613 if (!mCanOverrideProcessName
) {
618 if ((name
= PR_GetEnv("MOZ_DEBUG_APP_PROCESS")) &&
619 aName
.EqualsASCII(name
)) {
621 printf_stderr("\n\nCHILDCHILDCHILDCHILD\n [%s] debug me @%d\n\n", name
, getpid());
623 #elif defined(OS_WIN)
624 // Windows has a decent JIT debugging story, so NS_DebugBreak does the
626 NS_DebugBreak(NS_DEBUG_BREAK
,
627 "Invoking NS_DebugBreak() to debug child process",
628 nullptr, __FILE__
, __LINE__
);
632 mProcessName
= aName
;
633 mozilla::ipc::SetThisProcessName(NS_LossyConvertUTF16toASCII(aName
).get());
636 mCanOverrideProcessName
= false;
641 ContentChild::GetProcessName(nsAString
& aName
)
643 aName
.Assign(mProcessName
);
647 ContentChild::GetProcessName(nsACString
& aName
)
649 aName
.Assign(NS_ConvertUTF16toUTF8(mProcessName
));
653 ContentChild::AppendProcessId(nsACString
& aName
)
655 if (!aName
.IsEmpty()) {
658 unsigned pid
= getpid();
659 aName
.Append(nsPrintfCString("(pid %u)", pid
));
663 ContentChild::InitXPCOM()
665 // Do this as early as possible to get the parent process to initialize the
666 // background thread since we'll likely need database information very soon.
667 BackgroundChild::Startup();
669 nsCOMPtr
<nsIIPCBackgroundChildCreateCallback
> callback
=
670 new BackgroundChildPrimer();
671 if (!BackgroundChild::GetOrCreateForCurrentThread(callback
)) {
672 MOZ_CRASH("Failed to create PBackgroundChild!");
675 nsCOMPtr
<nsIConsoleService
> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID
));
677 NS_WARNING("Couldn't acquire console service");
681 mConsoleListener
= new ConsoleListener(this);
682 if (NS_FAILED(svc
->RegisterListener(mConsoleListener
)))
683 NS_WARNING("Couldn't register console listener for child process");
686 SendGetXPCOMProcessAttributes(&isOffline
);
687 RecvSetOffline(isOffline
);
689 DebugOnly
<FileUpdateDispatcher
*> observer
= FileUpdateDispatcher::GetSingleton();
690 NS_ASSERTION(observer
, "FileUpdateDispatcher is null");
692 // This object is held alive by the observer service.
693 nsRefPtr
<SystemMessageHandledObserver
> sysMsgObserver
=
694 new SystemMessageHandledObserver();
695 sysMsgObserver
->Init();
697 InitOnContentProcessCreated();
700 PMemoryReportRequestChild
*
701 ContentChild::AllocPMemoryReportRequestChild(const uint32_t& aGeneration
,
702 const bool &aAnonymize
,
703 const bool &aMinimizeMemoryUsage
,
704 const FileDescriptor
& aDMDFile
)
706 MemoryReportRequestChild
*actor
=
707 new MemoryReportRequestChild(aGeneration
, aAnonymize
, aDMDFile
);
712 // This is just a wrapper for InfallibleTArray<MemoryReport> that implements
713 // nsISupports, so it can be passed to nsIMemoryReporter::CollectReports.
714 class MemoryReportsWrapper MOZ_FINAL
: public nsISupports
{
715 ~MemoryReportsWrapper() {}
718 explicit MemoryReportsWrapper(InfallibleTArray
<MemoryReport
>* r
) : mReports(r
) { }
719 InfallibleTArray
<MemoryReport
> *mReports
;
721 NS_IMPL_ISUPPORTS0(MemoryReportsWrapper
)
723 class MemoryReportCallback MOZ_FINAL
: public nsIMemoryReporterCallback
728 explicit MemoryReportCallback(const nsACString
& aProcess
)
733 NS_IMETHOD
Callback(const nsACString
&aProcess
, const nsACString
&aPath
,
734 int32_t aKind
, int32_t aUnits
, int64_t aAmount
,
735 const nsACString
&aDescription
,
736 nsISupports
*aiWrappedReports
)
738 MemoryReportsWrapper
*wrappedReports
=
739 static_cast<MemoryReportsWrapper
*>(aiWrappedReports
);
741 MemoryReport
memreport(mProcess
, nsCString(aPath
), aKind
, aUnits
,
742 aAmount
, nsCString(aDescription
));
743 wrappedReports
->mReports
->AppendElement(memreport
);
747 ~MemoryReportCallback() {}
749 const nsCString mProcess
;
753 , nsIMemoryReporterCallback
757 ContentChild::RecvPMemoryReportRequestConstructor(
758 PMemoryReportRequestChild
* aChild
,
759 const uint32_t& aGeneration
,
760 const bool& aAnonymize
,
761 const bool& aMinimizeMemoryUsage
,
762 const FileDescriptor
& aDMDFile
)
764 MemoryReportRequestChild
*actor
=
765 static_cast<MemoryReportRequestChild
*>(aChild
);
768 if (aMinimizeMemoryUsage
) {
769 nsCOMPtr
<nsIMemoryReporterManager
> mgr
= do_GetService("@mozilla.org/memory-reporter-manager;1");
770 rv
= mgr
->MinimizeMemoryUsage(actor
);
771 // mgr will eventually call actor->Run()
776 return !NS_WARN_IF(NS_FAILED(rv
));
779 NS_IMETHODIMP
MemoryReportRequestChild::Run()
781 ContentChild
*child
= static_cast<ContentChild
*>(Manager());
782 nsCOMPtr
<nsIMemoryReporterManager
> mgr
= do_GetService("@mozilla.org/memory-reporter-manager;1");
784 InfallibleTArray
<MemoryReport
> reports
;
787 child
->GetProcessName(process
);
788 child
->AppendProcessId(process
);
790 // Run the reporters. The callback will turn each measurement into a
792 nsRefPtr
<MemoryReportsWrapper
> wrappedReports
=
793 new MemoryReportsWrapper(&reports
);
794 nsRefPtr
<MemoryReportCallback
> cb
= new MemoryReportCallback(process
);
795 mgr
->GetReportsForThisProcessExtended(cb
, wrappedReports
, mAnonymize
,
796 FileDescriptorToFILE(mDMDFile
, "wb"));
798 bool sent
= Send__delete__(this, mGeneration
, reports
);
799 return sent
? NS_OK
: NS_ERROR_FAILURE
;
803 ContentChild::RecvAudioChannelNotify()
805 nsRefPtr
<AudioChannelService
> service
=
806 AudioChannelService::GetAudioChannelService();
814 ContentChild::RecvDataStoreNotify(const uint32_t& aAppId
,
815 const nsString
& aName
,
816 const nsString
& aManifestURL
)
818 nsRefPtr
<DataStoreService
> service
= DataStoreService::GetOrCreate();
819 if (NS_WARN_IF(!service
)) {
823 nsresult rv
= service
->EnableDataStore(aAppId
, aName
, aManifestURL
);
824 if (NS_WARN_IF(NS_FAILED(rv
))) {
832 ContentChild::DeallocPMemoryReportRequestChild(PMemoryReportRequestChild
* actor
)
834 static_cast<MemoryReportRequestChild
*>(actor
)->Release();
838 PCycleCollectWithLogsChild
*
839 ContentChild::AllocPCycleCollectWithLogsChild(const bool& aDumpAllTraces
,
840 const FileDescriptor
& aGCLog
,
841 const FileDescriptor
& aCCLog
)
843 CycleCollectWithLogsChild
* actor
= new CycleCollectWithLogsChild(aGCLog
, aCCLog
);
844 // Return actor with refcount 0, which is safe because it has a non-XPCOM type.
849 ContentChild::RecvPCycleCollectWithLogsConstructor(PCycleCollectWithLogsChild
* aActor
,
850 const bool& aDumpAllTraces
,
851 const FileDescriptor
& aGCLog
,
852 const FileDescriptor
& aCCLog
)
854 // Take a reference here, where the XPCOM type is regained.
855 nsRefPtr
<CycleCollectWithLogsChild
> sink
= static_cast<CycleCollectWithLogsChild
*>(aActor
);
856 nsCOMPtr
<nsIMemoryInfoDumper
> dumper
= do_GetService("@mozilla.org/memory-info-dumper;1");
858 dumper
->DumpGCAndCCLogsToSink(aDumpAllTraces
, sink
);
860 // The actor's destructor is called when the last reference goes away...
865 ContentChild::DeallocPCycleCollectWithLogsChild(PCycleCollectWithLogsChild
* /* aActor */)
867 // ...so when we get here, there's nothing for us to do.
869 // Also, we're already in ~CycleCollectWithLogsChild (q.v.) at
870 // this point, so we shouldn't touch the actor in any case.
875 ContentChild::AllocPContentBridgeChild(mozilla::ipc::Transport
* aTransport
,
876 base::ProcessId aOtherProcess
)
878 return ContentBridgeChild::Create(aTransport
, aOtherProcess
);
881 PContentBridgeParent
*
882 ContentChild::AllocPContentBridgeParent(mozilla::ipc::Transport
* aTransport
,
883 base::ProcessId aOtherProcess
)
885 MOZ_ASSERT(!mLastBridge
);
886 mLastBridge
= static_cast<ContentBridgeParent
*>(
887 ContentBridgeParent::Create(aTransport
, aOtherProcess
));
892 ContentChild::AllocPCompositorChild(mozilla::ipc::Transport
* aTransport
,
893 base::ProcessId aOtherProcess
)
895 return CompositorChild::Create(aTransport
, aOtherProcess
);
898 PSharedBufferManagerChild
*
899 ContentChild::AllocPSharedBufferManagerChild(mozilla::ipc::Transport
* aTransport
,
900 base::ProcessId aOtherProcess
)
902 return SharedBufferManagerChild::StartUpInChildProcess(aTransport
, aOtherProcess
);
906 ContentChild::AllocPImageBridgeChild(mozilla::ipc::Transport
* aTransport
,
907 base::ProcessId aOtherProcess
)
909 return ImageBridgeChild::StartUpInChildProcess(aTransport
, aOtherProcess
);
913 ContentChild::AllocPBackgroundChild(Transport
* aTransport
,
914 ProcessId aOtherProcess
)
916 return BackgroundChild::Alloc(aTransport
, aOtherProcess
);
920 ContentChild::RecvSetProcessSandbox()
922 // We may want to move the sandbox initialization somewhere else
923 // at some point; see bug 880808.
924 #if defined(MOZ_CONTENT_SANDBOX)
925 #if defined(XP_LINUX)
926 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 19
927 // For B2G >= KitKat, sandboxing is mandatory; this has already
928 // been enforced by ContentParent::StartUp().
929 MOZ_ASSERT(CanSandboxContentProcess());
931 // Otherwise, sandboxing is best-effort.
932 if (!CanSandboxContentProcess()) {
936 SetContentProcessSandbox();
937 #elif defined(XP_WIN)
938 mozilla::SandboxTarget::Instance()->StartSandbox();
945 ContentChild::RecvSpeakerManagerNotify()
947 #ifdef MOZ_WIDGET_GONK
948 // Only notify the process which has the SpeakerManager instance.
949 nsRefPtr
<SpeakerManagerService
> service
=
950 SpeakerManagerService::GetSpeakerManagerService();
959 static CancelableTask
* sFirstIdleTask
;
961 static void FirstIdle(void)
963 MOZ_ASSERT(sFirstIdleTask
);
964 sFirstIdleTask
= nullptr;
965 ContentChild::GetSingleton()->SendFirstIdle();
968 mozilla::jsipc::PJavaScriptChild
*
969 ContentChild::AllocPJavaScriptChild()
971 MOZ_ASSERT(!ManagedPJavaScriptChild().Length());
973 return nsIContentChild::AllocPJavaScriptChild();
977 ContentChild::DeallocPJavaScriptChild(PJavaScriptChild
*aChild
)
979 return nsIContentChild::DeallocPJavaScriptChild(aChild
);
983 ContentChild::AllocPBrowserChild(const IPCTabContext
& aContext
,
984 const uint32_t& aChromeFlags
,
986 const bool& aIsForApp
,
987 const bool& aIsForBrowser
)
989 return nsIContentChild::AllocPBrowserChild(aContext
,
997 ContentChild::SendPBrowserConstructor(PBrowserChild
* aActor
,
998 const IPCTabContext
& aContext
,
999 const uint32_t& aChromeFlags
,
1000 const uint64_t& aID
,
1001 const bool& aIsForApp
,
1002 const bool& aIsForBrowser
)
1004 return PContentChild::SendPBrowserConstructor(aActor
,
1013 ContentChild::RecvPBrowserConstructor(PBrowserChild
* aActor
,
1014 const IPCTabContext
& aContext
,
1015 const uint32_t& aChromeFlags
,
1016 const uint64_t& aID
,
1017 const bool& aIsForApp
,
1018 const bool& aIsForBrowser
)
1020 // This runs after AllocPBrowserChild() returns and the IPC machinery for this
1021 // PBrowserChild has been set up.
1023 nsCOMPtr
<nsIObserverService
> os
= services::GetObserverService();
1026 static_cast<nsITabChild
*>(static_cast<TabChild
*>(aActor
));
1027 os
->NotifyObservers(tc
, "tab-child-created", nullptr);
1030 static bool hasRunOnce
= false;
1034 MOZ_ASSERT(!sFirstIdleTask
);
1035 sFirstIdleTask
= NewRunnableFunction(FirstIdle
);
1036 MessageLoop::current()->PostIdleTask(FROM_HERE
, sFirstIdleTask
);
1038 // Redo InitProcessAttributes() when the app or browser is really
1039 // launching so the attributes will be correct.
1041 mIsForApp
= aIsForApp
;
1042 mIsForBrowser
= aIsForBrowser
;
1043 InitProcessAttributes();
1049 PFileDescriptorSetChild
*
1050 ContentChild::AllocPFileDescriptorSetChild(const FileDescriptor
& aFD
)
1052 return new FileDescriptorSetChild(aFD
);
1056 ContentChild::DeallocPFileDescriptorSetChild(PFileDescriptorSetChild
* aActor
)
1058 delete static_cast<FileDescriptorSetChild
*>(aActor
);
1063 ContentChild::DeallocPBrowserChild(PBrowserChild
* aIframe
)
1065 return nsIContentChild::DeallocPBrowserChild(aIframe
);
1069 ContentChild::AllocPBlobChild(const BlobConstructorParams
& aParams
)
1071 return nsIContentChild::AllocPBlobChild(aParams
);
1074 mozilla::PRemoteSpellcheckEngineChild
*
1075 ContentChild::AllocPRemoteSpellcheckEngineChild()
1077 NS_NOTREACHED("Default Constructor for PRemoteSpellcheckEngineChilf should never be called");
1082 ContentChild::DeallocPRemoteSpellcheckEngineChild(PRemoteSpellcheckEngineChild
*child
)
1089 ContentChild::DeallocPBlobChild(PBlobChild
* aActor
)
1091 return nsIContentChild::DeallocPBlobChild(aActor
);
1095 ContentChild::SendPBlobConstructor(PBlobChild
* aActor
,
1096 const BlobConstructorParams
& aParams
)
1098 return PContentChild::SendPBlobConstructor(aActor
, aParams
);
1101 PCrashReporterChild
*
1102 ContentChild::AllocPCrashReporterChild(const mozilla::dom::NativeThreadId
& id
,
1103 const uint32_t& processType
)
1105 #ifdef MOZ_CRASHREPORTER
1106 return new CrashReporterChild();
1113 ContentChild::DeallocPCrashReporterChild(PCrashReporterChild
* crashreporter
)
1115 delete crashreporter
;
1120 ContentChild::AllocPHalChild()
1122 return CreateHalChild();
1126 ContentChild::DeallocPHalChild(PHalChild
* aHal
)
1133 ContentChild::AllocPIndexedDBChild()
1135 NS_NOTREACHED("Should never get here!");
1140 ContentChild::DeallocPIndexedDBChild(PIndexedDBChild
* aActor
)
1146 asmjscache::PAsmJSCacheEntryChild
*
1147 ContentChild::AllocPAsmJSCacheEntryChild(
1148 const asmjscache::OpenMode
& aOpenMode
,
1149 const asmjscache::WriteParams
& aWriteParams
,
1150 const IPC::Principal
& aPrincipal
)
1152 NS_NOTREACHED("Should never get here!");
1157 ContentChild::DeallocPAsmJSCacheEntryChild(PAsmJSCacheEntryChild
* aActor
)
1159 asmjscache::DeallocEntryChild(aActor
);
1164 ContentChild::AllocPTestShellChild()
1166 return new TestShellChild();
1170 ContentChild::DeallocPTestShellChild(PTestShellChild
* shell
)
1176 jsipc::JavaScriptChild
*
1177 ContentChild::GetCPOWManager()
1179 if (ManagedPJavaScriptChild().Length()) {
1180 return static_cast<JavaScriptChild
*>(ManagedPJavaScriptChild()[0]);
1182 JavaScriptChild
* actor
= static_cast<JavaScriptChild
*>(SendPJavaScriptConstructor());
1187 ContentChild::RecvPTestShellConstructor(PTestShellChild
* actor
)
1192 PDeviceStorageRequestChild
*
1193 ContentChild::AllocPDeviceStorageRequestChild(const DeviceStorageParams
& aParams
)
1195 return new DeviceStorageRequestChild();
1199 ContentChild::DeallocPDeviceStorageRequestChild(PDeviceStorageRequestChild
* aDeviceStorage
)
1201 delete aDeviceStorage
;
1205 PFileSystemRequestChild
*
1206 ContentChild::AllocPFileSystemRequestChild(const FileSystemParams
& aParams
)
1208 NS_NOTREACHED("Should never get here!");
1213 ContentChild::DeallocPFileSystemRequestChild(PFileSystemRequestChild
* aFileSystem
)
1215 mozilla::dom::FileSystemTaskBase
* child
=
1216 static_cast<mozilla::dom::FileSystemTaskBase
*>(aFileSystem
);
1217 // The reference is increased in FileSystemTaskBase::Start of
1218 // FileSystemTaskBase.cpp. We should decrease it after IPC.
1224 ContentChild::AllocPNeckoChild()
1226 return new NeckoChild();
1230 ContentChild::DeallocPNeckoChild(PNeckoChild
* necko
)
1236 PScreenManagerChild
*
1237 ContentChild::AllocPScreenManagerChild(uint32_t* aNumberOfScreens
,
1238 float* aSystemDefaultScale
,
1241 // The ContentParent should never attempt to allocate the
1242 // nsScreenManagerProxy. Instead, the nsScreenManagerProxy
1243 // service is requested and instantiated via XPCOM, and the
1244 // constructor of nsScreenManagerProxy sets up the IPC connection.
1245 NS_NOTREACHED("Should never get here!");
1250 ContentChild::DeallocPScreenManagerChild(PScreenManagerChild
* aService
)
1252 // nsScreenManagerProxy is AddRef'd in its constructor.
1253 nsScreenManagerProxy
*child
= static_cast<nsScreenManagerProxy
*>(aService
);
1258 PExternalHelperAppChild
*
1259 ContentChild::AllocPExternalHelperAppChild(const OptionalURIParams
& uri
,
1260 const nsCString
& aMimeContentType
,
1261 const nsCString
& aContentDisposition
,
1262 const uint32_t& aContentDispositionHint
,
1263 const nsString
& aContentDispositionFilename
,
1264 const bool& aForceSave
,
1265 const int64_t& aContentLength
,
1266 const OptionalURIParams
& aReferrer
,
1267 PBrowserChild
* aBrowser
)
1269 ExternalHelperAppChild
*child
= new ExternalHelperAppChild();
1275 ContentChild::DeallocPExternalHelperAppChild(PExternalHelperAppChild
* aService
)
1277 ExternalHelperAppChild
*child
= static_cast<ExternalHelperAppChild
*>(aService
);
1283 ContentChild::AllocPSmsChild()
1285 return new SmsChild();
1289 ContentChild::DeallocPSmsChild(PSmsChild
* aSms
)
1296 ContentChild::AllocPTelephonyChild()
1298 MOZ_CRASH("No one should be allocating PTelephonyChild actors");
1302 ContentChild::DeallocPTelephonyChild(PTelephonyChild
* aActor
)
1309 ContentChild::AllocPStorageChild()
1311 NS_NOTREACHED("We should never be manually allocating PStorageChild actors");
1316 ContentChild::DeallocPStorageChild(PStorageChild
* aActor
)
1318 DOMStorageDBChild
* child
= static_cast<DOMStorageDBChild
*>(aActor
);
1319 child
->ReleaseIPDLReference();
1324 ContentChild::AllocPBluetoothChild()
1327 MOZ_CRASH("No one should be allocating PBluetoothChild actors");
1329 MOZ_CRASH("No support for bluetooth on this platform!");
1334 ContentChild::DeallocPBluetoothChild(PBluetoothChild
* aActor
)
1340 MOZ_CRASH("No support for bluetooth on this platform!");
1345 ContentChild::AllocPFMRadioChild()
1348 NS_RUNTIMEABORT("No one should be allocating PFMRadioChild actors");
1351 NS_RUNTIMEABORT("No support for FMRadio on this platform!");
1357 ContentChild::DeallocPFMRadioChild(PFMRadioChild
* aActor
)
1363 NS_RUNTIMEABORT("No support for FMRadio on this platform!");
1368 PSpeechSynthesisChild
*
1369 ContentChild::AllocPSpeechSynthesisChild()
1371 #ifdef MOZ_WEBSPEECH
1372 MOZ_CRASH("No one should be allocating PSpeechSynthesisChild actors");
1379 ContentChild::DeallocPSpeechSynthesisChild(PSpeechSynthesisChild
* aActor
)
1381 #ifdef MOZ_WEBSPEECH
1390 ContentChild::RecvRegisterChrome(const InfallibleTArray
<ChromePackage
>& packages
,
1391 const InfallibleTArray
<ResourceMapping
>& resources
,
1392 const InfallibleTArray
<OverrideMapping
>& overrides
,
1393 const nsCString
& locale
,
1396 nsCOMPtr
<nsIChromeRegistry
> registrySvc
= nsChromeRegistry::GetService();
1397 nsChromeRegistryContent
* chromeRegistry
=
1398 static_cast<nsChromeRegistryContent
*>(registrySvc
.get());
1399 chromeRegistry
->RegisterRemoteChrome(packages
, resources
, overrides
,
1405 ContentChild::RecvRegisterChromeItem(const ChromeRegistryItem
& item
)
1407 nsCOMPtr
<nsIChromeRegistry
> registrySvc
= nsChromeRegistry::GetService();
1408 nsChromeRegistryContent
* chromeRegistry
=
1409 static_cast<nsChromeRegistryContent
*>(registrySvc
.get());
1410 switch (item
.type()) {
1411 case ChromeRegistryItem::TChromePackage
:
1412 chromeRegistry
->RegisterPackage(item
.get_ChromePackage());
1415 case ChromeRegistryItem::TOverrideMapping
:
1416 chromeRegistry
->RegisterOverride(item
.get_OverrideMapping());
1420 MOZ_ASSERT(false, "bad chrome item");
1428 ContentChild::RecvSetOffline(const bool& offline
)
1430 nsCOMPtr
<nsIIOService
> io (do_GetIOService());
1431 NS_ASSERTION(io
, "IO Service can not be null");
1433 io
->SetOffline(offline
);
1439 ContentChild::ActorDestroy(ActorDestroyReason why
)
1441 if (AbnormalShutdown
== why
) {
1442 NS_WARNING("shutting down early because of crash!");
1447 // In release builds, there's no point in the content process
1448 // going through the full XPCOM shutdown path, because it doesn't
1449 // keep persistent state.
1453 if (sFirstIdleTask
) {
1454 sFirstIdleTask
->Cancel();
1457 mAlertObservers
.Clear();
1459 mIdleObservers
.Clear();
1461 nsCOMPtr
<nsIConsoleService
> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID
));
1463 svc
->UnregisterListener(mConsoleListener
);
1464 mConsoleListener
->mChild
= nullptr;
1467 #ifdef MOZ_NUWA_PROCESS
1468 if (IsNuwaProcess()) {
1469 // The Nuwa cannot go through the full XPCOM shutdown path or deadlock
1475 XRE_ShutdownChildProcess();
1479 ContentChild::ProcessingError(Result what
)
1486 NS_RUNTIMEABORT("aborting because of MsgNotKnown");
1488 NS_RUNTIMEABORT("aborting because of MsgNotAllowed");
1489 case MsgPayloadError
:
1490 NS_RUNTIMEABORT("aborting because of MsgPayloadError");
1491 case MsgProcessingError
:
1492 NS_RUNTIMEABORT("aborting because of MsgProcessingError");
1494 NS_RUNTIMEABORT("aborting because of MsgRouteError");
1496 NS_RUNTIMEABORT("aborting because of MsgValueError");
1499 NS_RUNTIMEABORT("not reached");
1504 ContentChild::QuickExit()
1506 NS_WARNING("content process _exit()ing");
1511 ContentChild::AddRemoteAlertObserver(const nsString
& aData
,
1512 nsIObserver
* aObserver
)
1514 NS_ASSERTION(aObserver
, "Adding a null observer?");
1515 mAlertObservers
.AppendElement(new AlertObserver(aObserver
, aData
));
1521 ContentChild::RecvSystemMemoryAvailable(const uint64_t& aGetterId
,
1522 const uint32_t& aMemoryAvailable
)
1524 nsRefPtr
<Promise
> p
= dont_AddRef(reinterpret_cast<Promise
*>(aGetterId
));
1526 if (!aMemoryAvailable
) {
1527 p
->MaybeReject(NS_ERROR_NOT_AVAILABLE
);
1531 p
->MaybeResolve((int)aMemoryAvailable
);
1536 ContentChild::RecvPreferenceUpdate(const PrefSetting
& aPref
)
1538 Preferences::SetPreference(aPref
);
1543 ContentChild::RecvNotifyAlertsObserver(const nsCString
& aType
, const nsString
& aData
)
1545 for (uint32_t i
= 0; i
< mAlertObservers
.Length();
1546 /*we mutate the array during the loop; ++i iff no mutation*/) {
1547 AlertObserver
* observer
= mAlertObservers
[i
];
1548 if (observer
->Observes(aData
) && observer
->Notify(aType
)) {
1549 // if aType == alertfinished, this alert is done. we can
1550 // remove the observer.
1551 if (aType
.Equals(nsDependentCString("alertfinished"))) {
1552 mAlertObservers
.RemoveElementAt(i
);
1562 ContentChild::RecvNotifyVisited(const URIParams
& aURI
)
1564 nsCOMPtr
<nsIURI
> newURI
= DeserializeURI(aURI
);
1568 nsCOMPtr
<IHistory
> history
= services::GetHistoryService();
1570 history
->NotifyVisited(newURI
);
1576 ContentChild::RecvAsyncMessage(const nsString
& aMsg
,
1577 const ClonedMessageData
& aData
,
1578 const InfallibleTArray
<CpowEntry
>& aCpows
,
1579 const IPC::Principal
& aPrincipal
)
1581 nsRefPtr
<nsFrameMessageManager
> cpm
= nsFrameMessageManager::sChildProcessManager
;
1583 StructuredCloneData cloneData
= ipc::UnpackClonedMessageDataForChild(aData
);
1584 CpowIdHolder
cpows(GetCPOWManager(), aCpows
);
1585 cpm
->ReceiveMessage(static_cast<nsIContentFrameMessageManager
*>(cpm
.get()),
1586 aMsg
, false, &cloneData
, &cpows
, aPrincipal
, nullptr);
1592 ContentChild::RecvGeolocationUpdate(const GeoPosition
& somewhere
)
1594 nsCOMPtr
<nsIGeolocationUpdate
> gs
= do_GetService("@mozilla.org/geolocation/service;1");
1598 nsCOMPtr
<nsIDOMGeoPosition
> position
= somewhere
;
1599 gs
->Update(position
);
1604 ContentChild::RecvAddPermission(const IPC::Permission
& permission
)
1607 nsCOMPtr
<nsIPermissionManager
> permissionManagerIface
=
1608 services::GetPermissionManager();
1609 nsPermissionManager
* permissionManager
=
1610 static_cast<nsPermissionManager
*>(permissionManagerIface
.get());
1611 NS_ABORT_IF_FALSE(permissionManager
,
1612 "We have no permissionManager in the Content process !");
1614 nsCOMPtr
<nsIURI
> uri
;
1615 NS_NewURI(getter_AddRefs(uri
), NS_LITERAL_CSTRING("http://") + nsCString(permission
.host
));
1616 NS_ENSURE_TRUE(uri
, true);
1618 nsIScriptSecurityManager
* secMan
= nsContentUtils::GetSecurityManager();
1621 nsCOMPtr
<nsIPrincipal
> principal
;
1622 nsresult rv
= secMan
->GetAppCodebasePrincipal(uri
, permission
.appId
,
1623 permission
.isInBrowserElement
,
1624 getter_AddRefs(principal
));
1625 NS_ENSURE_SUCCESS(rv
, true);
1627 permissionManager
->AddInternal(principal
,
1628 nsCString(permission
.type
),
1629 permission
.capability
,
1631 permission
.expireType
,
1632 permission
.expireTime
,
1633 nsPermissionManager::eNotify
,
1634 nsPermissionManager::eNoDBOperation
);
1641 ContentChild::RecvScreenSizeChanged(const gfxIntSize
& size
)
1646 NS_RUNTIMEABORT("Message currently only expected on android");
1652 ContentChild::RecvFlushMemory(const nsString
& reason
)
1654 #ifdef MOZ_NUWA_PROCESS
1655 if (IsNuwaProcess()) {
1656 // Don't flush memory in the nuwa process: the GC thread could be frozen.
1660 nsCOMPtr
<nsIObserverService
> os
=
1661 mozilla::services::GetObserverService();
1663 os
->NotifyObservers(nullptr, "memory-pressure", reason
.get());
1668 ContentChild::RecvActivateA11y()
1670 #ifdef ACCESSIBILITY
1671 // Start accessibility in content process if it's running in chrome
1673 nsCOMPtr
<nsIAccessibilityService
> accService
=
1674 services::GetAccessibilityService();
1680 ContentChild::RecvGarbageCollect()
1682 // Rebroadcast the "child-gc-request" so that workers will GC.
1683 nsCOMPtr
<nsIObserverService
> obs
= mozilla::services::GetObserverService();
1685 obs
->NotifyObservers(nullptr, "child-gc-request", nullptr);
1687 nsJSContext::GarbageCollectNow(JS::gcreason::DOM_IPC
);
1692 ContentChild::RecvCycleCollect()
1694 // Rebroadcast the "child-cc-request" so that workers will CC.
1695 nsCOMPtr
<nsIObserverService
> obs
= mozilla::services::GetObserverService();
1697 obs
->NotifyObservers(nullptr, "child-cc-request", nullptr);
1699 nsJSContext::CycleCollectNow();
1703 #ifdef MOZ_NUWA_PROCESS
1705 OnFinishNuwaPreparation ()
1714 // This fetches and creates all the built-in stylesheets.
1715 nsLayoutStylesheetCache::UserContentSheet();
1717 TabChild::PreloadSlowThings();
1722 ContentChild::RecvAppInfo(const nsCString
& version
, const nsCString
& buildID
,
1723 const nsCString
& name
, const nsCString
& UAName
)
1725 mAppInfo
.version
.Assign(version
);
1726 mAppInfo
.buildID
.Assign(buildID
);
1727 mAppInfo
.name
.Assign(name
);
1728 mAppInfo
.UAName
.Assign(UAName
);
1730 if (!Preferences::GetBool("dom.ipc.processPrelaunch.enabled", false)) {
1734 // If we're part of the mozbrowser machinery, go ahead and start
1735 // preloading things. We can only do this for mozbrowser because
1736 // PreloadSlowThings() may set the docshell of the first TabChild
1737 // inactive, and we can only safely restore it to active from
1738 // BrowserElementChild.js.
1739 if ((mIsForApp
|| mIsForBrowser
)
1740 #ifdef MOZ_NUWA_PROCESS
1744 PreloadSlowThings();
1747 #ifdef MOZ_NUWA_PROCESS
1748 if (IsNuwaProcess()) {
1749 ContentChild::GetSingleton()->RecvGarbageCollect();
1750 MessageLoop::current()->PostTask(
1751 FROM_HERE
, NewRunnableFunction(OnFinishNuwaPreparation
));
1759 ContentChild::RecvLastPrivateDocShellDestroyed()
1761 nsCOMPtr
<nsIObserverService
> obs
= mozilla::services::GetObserverService();
1762 obs
->NotifyObservers(nullptr, "last-pb-context-exited", nullptr);
1767 ContentChild::RecvFilePathUpdate(const nsString
& aStorageType
,
1768 const nsString
& aStorageName
,
1769 const nsString
& aPath
,
1770 const nsCString
& aReason
)
1772 nsRefPtr
<DeviceStorageFile
> dsf
= new DeviceStorageFile(aStorageType
, aStorageName
, aPath
);
1775 CopyASCIItoUTF16(aReason
, reason
);
1776 nsCOMPtr
<nsIObserverService
> obs
= mozilla::services::GetObserverService();
1777 obs
->NotifyObservers(dsf
, "file-watcher-update", reason
.get());
1782 ContentChild::RecvFileSystemUpdate(const nsString
& aFsName
,
1783 const nsString
& aVolumeName
,
1784 const int32_t& aState
,
1785 const int32_t& aMountGeneration
,
1786 const bool& aIsMediaPresent
,
1787 const bool& aIsSharing
,
1788 const bool& aIsFormatting
,
1789 const bool& aIsFake
,
1790 const bool& aIsUnmounting
)
1792 #ifdef MOZ_WIDGET_GONK
1793 nsRefPtr
<nsVolume
> volume
= new nsVolume(aFsName
, aVolumeName
, aState
,
1794 aMountGeneration
, aIsMediaPresent
,
1795 aIsSharing
, aIsFormatting
, aIsFake
,
1798 nsRefPtr
<nsVolumeService
> vs
= nsVolumeService::GetSingleton();
1800 vs
->UpdateVolume(volume
);
1803 // Remove warnings about unused arguments
1805 unused
<< aVolumeName
;
1807 unused
<< aMountGeneration
;
1808 unused
<< aIsMediaPresent
;
1809 unused
<< aIsSharing
;
1810 unused
<< aIsFormatting
;
1812 unused
<< aIsUnmounting
;
1818 ContentChild::RecvNotifyProcessPriorityChanged(
1819 const hal::ProcessPriority
& aPriority
)
1821 nsCOMPtr
<nsIObserverService
> os
= services::GetObserverService();
1822 NS_ENSURE_TRUE(os
, true);
1824 nsRefPtr
<nsHashPropertyBag
> props
= new nsHashPropertyBag();
1825 props
->SetPropertyAsInt32(NS_LITERAL_STRING("priority"),
1826 static_cast<int32_t>(aPriority
));
1828 os
->NotifyObservers(static_cast<nsIPropertyBag2
*>(props
),
1829 "ipc:process-priority-changed", nullptr);
1834 ContentChild::RecvMinimizeMemoryUsage()
1836 #ifdef MOZ_NUWA_PROCESS
1837 if (IsNuwaProcess()) {
1838 // Don't minimize memory in the nuwa process: it will perform GC, but the
1839 // GC thread could be frozen.
1843 nsCOMPtr
<nsIMemoryReporterManager
> mgr
=
1844 do_GetService("@mozilla.org/memory-reporter-manager;1");
1845 NS_ENSURE_TRUE(mgr
, true);
1847 mgr
->MinimizeMemoryUsage(/* callback = */ nullptr);
1852 ContentChild::RecvNotifyPhoneStateChange(const nsString
& aState
)
1854 nsCOMPtr
<nsIObserverService
> os
= services::GetObserverService();
1856 os
->NotifyObservers(nullptr, "phone-state-changed", aState
.get());
1862 ContentChild::AddIdleObserver(nsIObserver
* aObserver
, uint32_t aIdleTimeInS
)
1864 MOZ_ASSERT(aObserver
, "null idle observer");
1865 // Make sure aObserver isn't released while we wait for the parent
1866 aObserver
->AddRef();
1867 SendAddIdleObserver(reinterpret_cast<uint64_t>(aObserver
), aIdleTimeInS
);
1868 mIdleObservers
.PutEntry(aObserver
);
1872 ContentChild::RemoveIdleObserver(nsIObserver
* aObserver
, uint32_t aIdleTimeInS
)
1874 MOZ_ASSERT(aObserver
, "null idle observer");
1875 SendRemoveIdleObserver(reinterpret_cast<uint64_t>(aObserver
), aIdleTimeInS
);
1876 aObserver
->Release();
1877 mIdleObservers
.RemoveEntry(aObserver
);
1881 ContentChild::RecvNotifyIdleObserver(const uint64_t& aObserver
,
1882 const nsCString
& aTopic
,
1883 const nsString
& aTimeStr
)
1885 nsIObserver
* observer
= reinterpret_cast<nsIObserver
*>(aObserver
);
1886 if (mIdleObservers
.Contains(observer
)) {
1887 observer
->Observe(nullptr, aTopic
.get(), aTimeStr
.get());
1889 NS_WARNING("Received notification for an idle observer that was removed.");
1895 ContentChild::RecvLoadAndRegisterSheet(const URIParams
& aURI
, const uint32_t& aType
)
1897 nsCOMPtr
<nsIURI
> uri
= DeserializeURI(aURI
);
1902 nsStyleSheetService
*sheetService
= nsStyleSheetService::GetInstance();
1904 sheetService
->LoadAndRegisterSheet(uri
, aType
);
1911 ContentChild::RecvUnregisterSheet(const URIParams
& aURI
, const uint32_t& aType
)
1913 nsCOMPtr
<nsIURI
> uri
= DeserializeURI(aURI
);
1918 nsStyleSheetService
*sheetService
= nsStyleSheetService::GetInstance();
1920 sheetService
->UnregisterSheet(uri
, aType
);
1926 #ifdef MOZ_NUWA_PROCESS
1927 class CallNuwaSpawn
: public nsRunnable
1933 if (IsNuwaProcess()) {
1937 // In the new process.
1938 ContentChild
* child
= ContentChild::GetSingleton();
1939 child
->SetProcessName(NS_LITERAL_STRING("(Preallocated app)"), false);
1940 mozilla::ipc::Transport
* transport
= child
->GetTransport();
1941 int fd
= transport
->GetFileDescriptor();
1942 transport
->ResetFileDescriptor(fd
);
1944 IToplevelProtocol
* toplevel
= child
->GetFirstOpenedActors();
1945 while (toplevel
!= nullptr) {
1946 transport
= toplevel
->GetTransport();
1947 fd
= transport
->GetFileDescriptor();
1948 transport
->ResetFileDescriptor(fd
);
1950 toplevel
= toplevel
->getNext();
1953 // Perform other after-fork initializations.
1954 InitOnContentProcessCreated();
1963 NS_ASSERTION(NuwaSpawnPrepare
!= nullptr,
1964 "NuwaSpawnPrepare() is not available!");
1965 NuwaSpawnPrepare(); // NuwaSpawn will be blocked.
1968 nsCOMPtr
<nsIRunnable
> callSpawn(new CallNuwaSpawn());
1969 NS_DispatchToMainThread(callSpawn
);
1972 // IOThread should be blocked here for waiting NuwaSpawn().
1973 NS_ASSERTION(NuwaSpawnWait
!= nullptr,
1974 "NuwaSpawnWait() is not available!");
1975 NuwaSpawnWait(); // Now! NuwaSpawn can go.
1976 // Here, we can make sure the spawning was finished.
1980 * This function should keep IO thread in a stable state and freeze it
1981 * until the spawning is finished.
1986 if (NuwaCheckpointCurrentThread()) {
1993 ContentChild::RecvNuwaFork()
1995 #ifdef MOZ_NUWA_PROCESS
1996 if (sNuwaForking
) { // No reentry.
1999 sNuwaForking
= true;
2001 // We want to ensure that the PBackground actor gets cloned in the Nuwa
2002 // process before we freeze. Also, we have to do this to avoid deadlock.
2003 // Protocols that are "opened" (e.g. PBackground, PCompositor) block the
2004 // main thread to wait for the IPC thread during the open operation.
2005 // NuwaSpawnWait() blocks the IPC thread to wait for the main thread when
2006 // the Nuwa process is forked. Unless we ensure that the two cannot happen
2007 // at the same time then we risk deadlock. Spinning the event loop here
2008 // guarantees the ordering is safe for PBackground.
2009 while (!BackgroundChild::GetForCurrentThread()) {
2010 if (NS_WARN_IF(!NS_ProcessNextEvent())) {
2015 MessageLoop
* ioloop
= XRE_GetIOMessageLoop();
2016 ioloop
->PostTask(FROM_HERE
, NewRunnableFunction(RunNuwaFork
));
2019 return false; // Makes the underlying IPC channel abort.
2024 ContentChild::RecvOnAppThemeChanged()
2026 nsCOMPtr
<nsIObserverService
> os
= services::GetObserverService();
2028 os
->NotifyObservers(nullptr, "app-theme-changed", nullptr);
2034 } // namespace mozilla
2038 #if defined(MOZ_NUWA_PROCESS)
2040 GetProtoFdInfos(NuwaProtoFdInfo
* aInfoList
,
2041 size_t aInfoListSize
,
2046 mozilla::dom::ContentChild
* content
=
2047 mozilla::dom::ContentChild::GetSingleton();
2048 aInfoList
[i
].protoId
= content
->GetProtocolId();
2049 aInfoList
[i
].originFd
=
2050 content
->GetTransport()->GetFileDescriptor();
2053 for (IToplevelProtocol
* actor
= content
->GetFirstOpenedActors();
2055 actor
= actor
->getNext()) {
2056 if (i
>= aInfoListSize
) {
2057 NS_RUNTIMEABORT("Too many top level protocols!");
2060 aInfoList
[i
].protoId
= actor
->GetProtocolId();
2061 aInfoList
[i
].originFd
=
2062 actor
->GetTransport()->GetFileDescriptor();
2066 if (i
> NUWA_TOPLEVEL_MAX
) {
2067 NS_RUNTIMEABORT("Too many top level protocols!");
2072 class RunAddNewIPCProcess
: public nsRunnable
2075 RunAddNewIPCProcess(pid_t aPid
,
2076 nsTArray
<mozilla::ipc::ProtocolFdMapping
>& aMaps
)
2079 mMaps
.SwapElements(aMaps
);
2084 mozilla::dom::ContentChild::GetSingleton()->
2085 SendAddNewProcess(mPid
, mMaps
);
2087 MOZ_ASSERT(sNuwaForking
);
2088 sNuwaForking
= false;
2095 nsTArray
<mozilla::ipc::ProtocolFdMapping
> mMaps
;
2099 * AddNewIPCProcess() is called by Nuwa process to tell the parent
2100 * process that a new process is created.
2102 * In the newly created process, ResetContentChildTransport() is called to
2103 * reset fd for the IPC Channel and the session.
2106 AddNewIPCProcess(pid_t aPid
, NuwaProtoFdInfo
* aInfoList
, size_t aInfoListSize
)
2108 nsTArray
<mozilla::ipc::ProtocolFdMapping
> maps
;
2110 for (size_t i
= 0; i
< aInfoListSize
; i
++) {
2111 int _fd
= aInfoList
[i
].newFds
[NUWA_NEWFD_PARENT
];
2112 mozilla::ipc::FileDescriptor
fd(_fd
);
2113 mozilla::ipc::ProtocolFdMapping
map(aInfoList
[i
].protoId
, fd
);
2114 maps
.AppendElement(map
);
2117 nsRefPtr
<RunAddNewIPCProcess
> runner
= new RunAddNewIPCProcess(aPid
, maps
);
2118 NS_DispatchToMainThread(runner
);
2122 OnNuwaProcessReady()
2124 mozilla::dom::ContentChild
* content
=
2125 mozilla::dom::ContentChild::GetSingleton();
2126 content
->SendNuwaReady();
2132 SetCurrentProcessPrivileges(base::PRIVILEGES_DEFAULT
);
2135 #endif // MOZ_NUWA_PROCESS