RDDChild.cpp (7451B)
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 "RDDChild.h" 7 8 #include "TelemetryProbesReporter.h" 9 #include "VideoUtils.h" 10 #include "mozilla/FOGIPC.h" 11 #include "mozilla/RDDProcessManager.h" 12 #include "mozilla/dom/ContentParent.h" 13 #include "mozilla/dom/MemoryReportRequest.h" 14 #include "mozilla/gfx/GPUProcessManager.h" 15 #include "mozilla/gfx/gfxVars.h" 16 #include "mozilla/ipc/CrashReporterHost.h" 17 #include "mozilla/ipc/Endpoint.h" 18 19 #if defined(XP_LINUX) && defined(MOZ_SANDBOX) 20 # include "mozilla/SandboxBroker.h" 21 # include "mozilla/SandboxBrokerPolicyFactory.h" 22 #endif 23 24 #include "mozilla/Telemetry.h" 25 #include "mozilla/TelemetryIPC.h" 26 27 #if defined(XP_WIN) 28 # include "mozilla/WinDllServices.h" 29 #endif 30 31 #include "ProfilerParent.h" 32 #include "RDDProcessHost.h" 33 34 namespace mozilla { 35 36 using namespace layers; 37 using namespace gfx; 38 39 RDDChild::RDDChild(RDDProcessHost* aHost) : mHost(aHost) {} 40 41 RDDChild::~RDDChild() = default; 42 43 bool RDDChild::Init() { 44 Maybe<FileDescriptor> brokerFd; 45 46 #if defined(XP_LINUX) && defined(MOZ_SANDBOX) 47 auto policy = SandboxBrokerPolicyFactory::GetRDDPolicy(OtherPid()); 48 if (policy != nullptr) { 49 brokerFd = Some(FileDescriptor()); 50 mSandboxBroker = 51 SandboxBroker::Create(std::move(policy), OtherPid(), brokerFd.ref()); 52 // This is unlikely to fail and probably indicates OS resource 53 // exhaustion, but we can at least try to recover. 54 if (NS_WARN_IF(mSandboxBroker == nullptr)) { 55 return false; 56 } 57 MOZ_ASSERT(brokerFd.ref().IsValid()); 58 } 59 #endif // XP_LINUX && MOZ_SANDBOX 60 61 nsTArray<GfxVarUpdate> updates = gfxVars::FetchNonDefaultVars(); 62 63 bool isReadyForBackgroundProcessing = false; 64 #if defined(XP_WIN) 65 RefPtr<DllServices> dllSvc(DllServices::Get()); 66 isReadyForBackgroundProcessing = dllSvc->IsReadyForBackgroundProcessing(); 67 #endif 68 69 SendInit(updates, brokerFd, Telemetry::CanRecordReleaseData(), 70 isReadyForBackgroundProcessing); 71 72 (void)SendInitProfiler(ProfilerParent::CreateForProcess(OtherPid())); 73 74 gfxVars::AddReceiver(this); 75 76 return true; 77 } 78 79 bool RDDChild::SendRequestMemoryReport(const uint32_t& aGeneration, 80 const bool& aAnonymize, 81 const bool& aMinimizeMemoryUsage, 82 const Maybe<FileDescriptor>& aDMDFile) { 83 mMemoryReportRequest = MakeUnique<MemoryReportRequestHost>(aGeneration); 84 85 PRDDChild::SendRequestMemoryReport( 86 aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, 87 [&](const uint32_t& aGeneration2) { 88 if (RDDProcessManager* rddpm = RDDProcessManager::Get()) { 89 if (RDDChild* child = rddpm->GetRDDChild()) { 90 if (child->mMemoryReportRequest) { 91 child->mMemoryReportRequest->Finish(aGeneration2); 92 child->mMemoryReportRequest = nullptr; 93 } 94 } 95 } 96 }, 97 [&](mozilla::ipc::ResponseRejectReason) { 98 if (RDDProcessManager* rddpm = RDDProcessManager::Get()) { 99 if (RDDChild* child = rddpm->GetRDDChild()) { 100 child->mMemoryReportRequest = nullptr; 101 } 102 } 103 }); 104 105 return true; 106 } 107 108 void RDDChild::OnCompositorUnexpectedShutdown() { 109 if (!CanSend()) { 110 return; 111 } 112 113 if (RDDProcessManager* rddpm = RDDProcessManager::Get()) { 114 if (auto* gpm = GPUProcessManager::Get()) { 115 gpm->CreateRddVideoBridge(rddpm, this); 116 } 117 } 118 } 119 120 void RDDChild::OnVarChanged(const nsTArray<GfxVarUpdate>& aVar) { 121 SendUpdateVar(aVar); 122 } 123 124 mozilla::ipc::IPCResult RDDChild::RecvAddMemoryReport( 125 const MemoryReport& aReport) { 126 if (mMemoryReportRequest) { 127 mMemoryReportRequest->RecvReport(aReport); 128 } 129 return IPC_OK(); 130 } 131 132 #if defined(XP_WIN) 133 mozilla::ipc::IPCResult RDDChild::RecvGetModulesTrust( 134 ModulePaths&& aModPaths, bool aRunAtNormalPriority, 135 GetModulesTrustResolver&& aResolver) { 136 RefPtr<DllServices> dllSvc(DllServices::Get()); 137 dllSvc->GetModulesTrust(std::move(aModPaths), aRunAtNormalPriority) 138 ->Then( 139 GetMainThreadSerialEventTarget(), __func__, 140 [aResolver](ModulesMapResult&& aResult) { 141 aResolver(Some(ModulesMapResult(std::move(aResult)))); 142 }, 143 [aResolver](nsresult aRv) { aResolver(Nothing()); }); 144 return IPC_OK(); 145 } 146 #endif // defined(XP_WIN) 147 148 mozilla::ipc::IPCResult RDDChild::RecvUpdateMediaCodecsSupported( 149 const media::MediaCodecsSupported& aSupported) { 150 #if defined(XP_MACOSX) || defined(XP_LINUX) 151 // We report this on GPUChild on Windows and Android 152 if (ContainHardwareCodecsSupported(aSupported)) { 153 mozilla::TelemetryProbesReporter::ReportDeviceMediaCodecSupported( 154 aSupported); 155 } 156 #endif 157 dom::ContentParent::BroadcastMediaCodecsSupportedUpdate( 158 RemoteMediaIn::RddProcess, aSupported); 159 return IPC_OK(); 160 } 161 162 mozilla::ipc::IPCResult RDDChild::RecvAccumulateChildHistograms( 163 nsTArray<HistogramAccumulation>&& aAccumulations) { 164 TelemetryIPC::AccumulateChildHistograms(Telemetry::ProcessID::Rdd, 165 aAccumulations); 166 return IPC_OK(); 167 } 168 169 mozilla::ipc::IPCResult RDDChild::RecvAccumulateChildKeyedHistograms( 170 nsTArray<KeyedHistogramAccumulation>&& aAccumulations) { 171 TelemetryIPC::AccumulateChildKeyedHistograms(Telemetry::ProcessID::Rdd, 172 aAccumulations); 173 return IPC_OK(); 174 } 175 176 mozilla::ipc::IPCResult RDDChild::RecvUpdateChildScalars( 177 nsTArray<ScalarAction>&& aScalarActions) { 178 TelemetryIPC::UpdateChildScalars(Telemetry::ProcessID::Rdd, aScalarActions); 179 return IPC_OK(); 180 } 181 182 mozilla::ipc::IPCResult RDDChild::RecvUpdateChildKeyedScalars( 183 nsTArray<KeyedScalarAction>&& aScalarActions) { 184 TelemetryIPC::UpdateChildKeyedScalars(Telemetry::ProcessID::Rdd, 185 aScalarActions); 186 return IPC_OK(); 187 } 188 189 mozilla::ipc::IPCResult RDDChild::RecvRecordChildEvents( 190 nsTArray<mozilla::Telemetry::ChildEventData>&& aEvents) { 191 TelemetryIPC::RecordChildEvents(Telemetry::ProcessID::Rdd, aEvents); 192 return IPC_OK(); 193 } 194 195 mozilla::ipc::IPCResult RDDChild::RecvRecordDiscardedData( 196 const mozilla::Telemetry::DiscardedData& aDiscardedData) { 197 TelemetryIPC::RecordDiscardedData(Telemetry::ProcessID::Rdd, aDiscardedData); 198 return IPC_OK(); 199 } 200 201 mozilla::ipc::IPCResult RDDChild::RecvFOGData(ByteBuf&& aBuf) { 202 glean::FOGData(std::move(aBuf)); 203 return IPC_OK(); 204 } 205 206 void RDDChild::ActorDestroy(ActorDestroyReason aWhy) { 207 if (aWhy == AbnormalShutdown) { 208 GenerateCrashReport(); 209 } 210 211 if (auto* gpm = gfx::GPUProcessManager::Get()) { 212 // Note: the manager could have shutdown already. 213 gpm->RemoveListener(this); 214 } 215 216 gfxVars::RemoveReceiver(this); 217 mHost->OnChannelClosed(); 218 } 219 220 class DeferredDeleteRDDChild : public Runnable { 221 public: 222 explicit DeferredDeleteRDDChild(RefPtr<RDDChild>&& aChild) 223 : Runnable("gfx::DeferredDeleteRDDChild"), mChild(std::move(aChild)) {} 224 225 NS_IMETHODIMP Run() override { return NS_OK; } 226 227 private: 228 RefPtr<RDDChild> mChild; 229 }; 230 231 /* static */ 232 void RDDChild::Destroy(RefPtr<RDDChild>&& aChild) { 233 NS_DispatchToMainThread(new DeferredDeleteRDDChild(std::move(aChild))); 234 } 235 236 } // namespace mozilla