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 #include "mozilla/ipc/UtilityProcessParent.h"
7 #include "mozilla/ipc/UtilityProcessManager.h"
12 # include "mozilla/WinDllServices.h"
15 #include "mozilla/ipc/ProcessChild.h"
16 #include "mozilla/FOGIPC.h"
18 #include "mozilla/Telemetry.h"
19 #include "mozilla/TelemetryIPC.h"
21 #include "nsHashPropertyBag.h"
22 #include "mozilla/Services.h"
23 #include "nsIObserverService.h"
25 namespace mozilla::ipc
{
27 UtilityProcessParent::UtilityProcessParent(UtilityProcessHost
* aHost
)
29 MOZ_ASSERT(NS_IsMainThread());
33 UtilityProcessParent::~UtilityProcessParent() = default;
35 bool UtilityProcessParent::SendRequestMemoryReport(
36 const uint32_t& aGeneration
, const bool& aAnonymize
,
37 const bool& aMinimizeMemoryUsage
, const Maybe
<FileDescriptor
>& aDMDFile
) {
38 mMemoryReportRequest
= MakeUnique
<MemoryReportRequestHost
>(aGeneration
);
40 PUtilityProcessParent::SendRequestMemoryReport(
41 aGeneration
, aAnonymize
, aMinimizeMemoryUsage
, aDMDFile
,
42 [self
= RefPtr
{this}](const uint32_t& aGeneration2
) {
43 if (self
->mMemoryReportRequest
) {
44 self
->mMemoryReportRequest
->Finish(aGeneration2
);
45 self
->mMemoryReportRequest
= nullptr;
48 [self
= RefPtr
{this}](mozilla::ipc::ResponseRejectReason
) {
49 self
->mMemoryReportRequest
= nullptr;
55 mozilla::ipc::IPCResult
UtilityProcessParent::RecvAddMemoryReport(
56 const MemoryReport
& aReport
) {
57 if (mMemoryReportRequest
) {
58 mMemoryReportRequest
->RecvReport(aReport
);
63 mozilla::ipc::IPCResult
UtilityProcessParent::RecvFOGData(ByteBuf
&& aBuf
) {
64 glean::FOGData(std::move(aBuf
));
69 mozilla::ipc::IPCResult
UtilityProcessParent::RecvGetModulesTrust(
70 ModulePaths
&& aModPaths
, bool aRunAtNormalPriority
,
71 GetModulesTrustResolver
&& aResolver
) {
72 RefPtr
<DllServices
> dllSvc(DllServices::Get());
73 dllSvc
->GetModulesTrust(std::move(aModPaths
), aRunAtNormalPriority
)
75 GetMainThreadSerialEventTarget(), __func__
,
76 [aResolver
](ModulesMapResult
&& aResult
) {
77 aResolver(Some(ModulesMapResult(std::move(aResult
))));
79 [aResolver
](nsresult aRv
) { aResolver(Nothing()); });
82 #endif // defined(XP_WIN)
84 mozilla::ipc::IPCResult
UtilityProcessParent::RecvAccumulateChildHistograms(
85 nsTArray
<HistogramAccumulation
>&& aAccumulations
) {
86 TelemetryIPC::AccumulateChildHistograms(Telemetry::ProcessID::Utility
,
91 mozilla::ipc::IPCResult
92 UtilityProcessParent::RecvAccumulateChildKeyedHistograms(
93 nsTArray
<KeyedHistogramAccumulation
>&& aAccumulations
) {
94 TelemetryIPC::AccumulateChildKeyedHistograms(Telemetry::ProcessID::Utility
,
99 mozilla::ipc::IPCResult
UtilityProcessParent::RecvUpdateChildScalars(
100 nsTArray
<ScalarAction
>&& aScalarActions
) {
101 TelemetryIPC::UpdateChildScalars(Telemetry::ProcessID::Utility
,
106 mozilla::ipc::IPCResult
UtilityProcessParent::RecvUpdateChildKeyedScalars(
107 nsTArray
<KeyedScalarAction
>&& aScalarActions
) {
108 TelemetryIPC::UpdateChildKeyedScalars(Telemetry::ProcessID::Utility
,
113 mozilla::ipc::IPCResult
UtilityProcessParent::RecvRecordChildEvents(
114 nsTArray
<mozilla::Telemetry::ChildEventData
>&& aEvents
) {
115 TelemetryIPC::RecordChildEvents(Telemetry::ProcessID::Utility
, aEvents
);
119 mozilla::ipc::IPCResult
UtilityProcessParent::RecvRecordDiscardedData(
120 const mozilla::Telemetry::DiscardedData
& aDiscardedData
) {
121 TelemetryIPC::RecordDiscardedData(Telemetry::ProcessID::Utility
,
126 mozilla::ipc::IPCResult
UtilityProcessParent::RecvInitCompleted() {
128 mHost
->ResolvePromise();
132 void UtilityProcessParent::ActorDestroy(ActorDestroyReason aWhy
) {
133 RefPtr
<nsHashPropertyBag
> props
= new nsHashPropertyBag();
135 if (aWhy
== AbnormalShutdown
) {
138 if (mCrashReporter
) {
139 #if defined(MOZ_SANDBOX)
140 RefPtr
<mozilla::ipc::UtilityProcessManager
> upm
=
141 mozilla::ipc::UtilityProcessManager::GetSingleton();
143 Span
<const UtilityActorName
> actors
= upm
->GetActors(this);
144 nsAutoCString actorsName
;
145 if (!actors
.IsEmpty()) {
146 actorsName
+= GetUtilityActorName(actors
.First
<1>()[0]);
147 for (const auto& actor
: actors
.From(1)) {
148 actorsName
+= ", "_ns
+ GetUtilityActorName(actor
);
151 mCrashReporter
->AddAnnotation(
152 CrashReporter::Annotation::UtilityActorsName
, actorsName
);
157 GenerateCrashReport(OtherPid(), &dumpID
);
159 // It's okay for dumpID to be empty if there was no minidump generated
160 // tests like ipc/glue/test/browser/browser_utility_crashReporter.js are
161 // there to verify this
162 if (!dumpID
.IsEmpty()) {
163 props
->SetPropertyAsAString(u
"dumpID"_ns
, dumpID
);
168 pid
.AppendInt(static_cast<uint64_t>(OtherPid()));
170 nsCOMPtr
<nsIObserverService
> obs
= mozilla::services::GetObserverService();
172 obs
->NotifyObservers((nsIPropertyBag2
*)props
, "ipc:utility-shutdown",
175 NS_WARNING("Could not get a nsIObserverService, ipc:utility-shutdown skip");
178 mHost
->OnChannelClosed();
181 // To ensure that IPDL is finished before UtilityParent gets deleted.
182 class DeferredDeleteUtilityProcessParent
: public Runnable
{
184 explicit DeferredDeleteUtilityProcessParent(
185 RefPtr
<UtilityProcessParent
> aParent
)
186 : Runnable("ipc::glue::DeferredDeleteUtilityProcessParent"),
187 mParent(std::move(aParent
)) {}
189 NS_IMETHODIMP
Run() override
{ return NS_OK
; }
192 RefPtr
<UtilityProcessParent
> mParent
;
196 void UtilityProcessParent::Destroy(RefPtr
<UtilityProcessParent
> aParent
) {
197 NS_DispatchToMainThread(
198 new DeferredDeleteUtilityProcessParent(std::move(aParent
)));
201 } // namespace mozilla::ipc