tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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