Bug 1550422 - P5. Sync preferences with RDD process when then changed. r?mattwoodrow!,mjf! draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Thu, 09 May 2019 15:42:01 +1000
changeset 2008582 f47d32abe14b41358f8d7b7879f6e0955fef8c0a
parent 2008581 faaa9a7490ceb2a6b5bcc517d4140a10b797ce35
child 2008583 6fc8c9a7f77354381a26167a04a7f9d345e39f06
push id363925
push userjyavenard@mozilla.com
push dateSat, 18 May 2019 07:53:18 +0000
treeherdertry@5082cd581229 [default view] [failures only]
reviewersmattwoodrow
bugs1550422
milestone68.0a1
Bug 1550422 - P5. Sync preferences with RDD process when then changed. r?mattwoodrow!,mjf! Differential Revision: https://phabricator.services.mozilla.com/D30590
dom/media/ipc/PRDD.ipdl
dom/media/ipc/RDDParent.cpp
dom/media/ipc/RDDParent.h
dom/media/ipc/RDDProcessManager.cpp
dom/media/ipc/RDDProcessManager.h
--- a/dom/media/ipc/PRDD.ipdl
+++ b/dom/media/ipc/PRDD.ipdl
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include MemoryReportTypes;
+include PrefsTypes;
 
 include protocol PProfiler;
 include protocol PRemoteDecoderManager;
 
 using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
 
 namespace mozilla {
 
@@ -27,16 +28,18 @@ parent:
   async NewContentRemoteDecoderManager(
             Endpoint<PRemoteDecoderManagerParent> endpoint);
 
   async RequestMemoryReport(uint32_t generation,
                             bool anonymize,
                             bool minimizeMemoryUsage,
                             FileDescriptor? DMDFile);
 
+  async PreferenceUpdate(Pref pref);
+
 child:
   // args TBD, sent when init complete. Occurs once, after Init().
   async InitComplete();
 
   async InitCrashReporter(Shmem shmem, NativeThreadId threadId);
 
   async AddMemoryReport(MemoryReport aReport);
   async FinishMemoryReport(uint32_t aGeneration);
--- a/dom/media/ipc/RDDParent.cpp
+++ b/dom/media/ipc/RDDParent.cpp
@@ -170,16 +170,21 @@ mozilla::ipc::IPCResult RDDParent::RecvR
         Unused << GetSingleton()->SendAddMemoryReport(aReport);
       },
       [&](const uint32_t& aGeneration) {
         return GetSingleton()->SendFinishMemoryReport(aGeneration);
       });
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult RDDParent::RecvPreferenceUpdate(const Pref& aPref) {
+  Preferences::SetPreference(aPref);
+  return IPC_OK();
+}
+
 void RDDParent::ActorDestroy(ActorDestroyReason aWhy) {
   if (AbnormalShutdown == aWhy) {
     NS_WARNING("Shutting down RDD process early due to a crash!");
     ProcessChild::QuickExit();
   }
 
 #ifndef NS_FREE_PERMANENT_DATA
   // No point in going through XPCOM shutdown because we don't keep persistent
--- a/dom/media/ipc/RDDParent.h
+++ b/dom/media/ipc/RDDParent.h
@@ -30,16 +30,17 @@ class RDDParent final : public PRDDParen
       Endpoint<PProfilerChild>&& aEndpoint);
 
   mozilla::ipc::IPCResult RecvNewContentRemoteDecoderManager(
       Endpoint<PRemoteDecoderManagerParent>&& aEndpoint);
   mozilla::ipc::IPCResult RecvRequestMemoryReport(
       const uint32_t& generation, const bool& anonymize,
       const bool& minimizeMemoryUsage,
       const Maybe<ipc::FileDescriptor>& DMDFile);
+  mozilla::ipc::IPCResult RecvPreferenceUpdate(const Pref& pref);
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
  private:
   const TimeStamp mLaunchTime;
 #ifdef MOZ_GECKO_PROFILER
   RefPtr<ChildProfilerController> mProfilerController;
 #endif
--- a/dom/media/ipc/RDDProcessManager.cpp
+++ b/dom/media/ipc/RDDProcessManager.cpp
@@ -3,18 +3,19 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "RDDProcessManager.h"
 
 #include "mozilla/MemoryReportingProcess.h"
 #include "mozilla/RemoteDecoderManagerChild.h"
 #include "mozilla/RemoteDecoderManagerParent.h"
+#include "mozilla/Preferences.h"
 #include "mozilla/StaticPrefs.h"
-
+#include "mozilla/dom/ContentParent.h"
 #include "nsAppRunner.h"
 #include "nsContentUtils.h"
 #include "RDDChild.h"
 #include "RDDProcessHost.h"
 
 namespace mozilla {
 
 using namespace mozilla::layers;
@@ -35,16 +36,17 @@ RDDProcessManager::RDDProcessManager()
       mNumProcessAttempts(0),
       mProcess(nullptr),
       mProcessToken(0),
       mRDDChild(nullptr) {
   MOZ_COUNT_CTOR(RDDProcessManager);
 
   mObserver = new Observer(this);
   nsContentUtils::RegisterShutdownObserver(mObserver);
+  Preferences::AddStrongObserver(mObserver, "");
 }
 
 RDDProcessManager::~RDDProcessManager() {
   MOZ_COUNT_DTOR(RDDProcessManager);
 
   // The RDD process should have already been shut down.
   MOZ_ASSERT(!mProcess && !mRDDChild);
 
@@ -57,29 +59,51 @@ NS_IMPL_ISUPPORTS(RDDProcessManager::Obs
 RDDProcessManager::Observer::Observer(RDDProcessManager* aManager)
     : mManager(aManager) {}
 
 NS_IMETHODIMP
 RDDProcessManager::Observer::Observe(nsISupports* aSubject, const char* aTopic,
                                      const char16_t* aData) {
   if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
     mManager->OnXPCOMShutdown();
+  } else if (!strcmp(aTopic, "nsPref:changed")) {
+    mManager->OnPreferenceChange(aData);
   }
   return NS_OK;
 }
 
 void RDDProcessManager::OnXPCOMShutdown() {
   if (mObserver) {
     nsContentUtils::UnregisterShutdownObserver(mObserver);
+    Preferences::RemoveObserver(mObserver, "");
     mObserver = nullptr;
   }
 
   CleanShutdown();
 }
 
+void RDDProcessManager::OnPreferenceChange(const char16_t* aData) {
+  // A pref changed. If it's not on the blacklist, inform child processes.
+  if (!dom::ContentParent::ShouldSyncPreference(aData)) {
+    return;
+  }
+
+  // We know prefs are ASCII here.
+  NS_LossyConvertUTF16toASCII strData(aData);
+
+  mozilla::dom::Pref pref(strData, /* isLocked */ false, Nothing(), Nothing());
+  Preferences::GetPreference(&pref);
+  if (!!mRDDChild) {
+    MOZ_ASSERT(mQueuedPrefs.IsEmpty());
+    mRDDChild->SendPreferenceUpdate(pref);
+  } else {
+    mQueuedPrefs.AppendElement(pref);
+  }
+}
+
 void RDDProcessManager::LaunchRDDProcess() {
   if (mProcess) {
     return;
   }
 
   mNumProcessAttempts++;
 
   std::vector<std::string> extraArgs;
@@ -124,16 +148,23 @@ void RDDProcessManager::OnProcessLaunchC
   if (!mProcess->IsConnected()) {
     DestroyProcess();
     return;
   }
 
   mRDDChild = mProcess->GetActor();
   mProcessToken = mProcess->GetProcessToken();
 
+  // Flush any pref updates that happened during launch and weren't
+  // included in the blobs set up in LaunchRDDProcess.
+  for (const mozilla::dom::Pref& pref : mQueuedPrefs) {
+    Unused << NS_WARN_IF(!mRDDChild->SendPreferenceUpdate(pref));
+  }
+  mQueuedPrefs.Clear();
+
   CrashReporter::AnnotateCrashReport(
       CrashReporter::Annotation::RDDProcessStatus,
       NS_LITERAL_CSTRING("Running"));
 }
 
 void RDDProcessManager::OnProcessUnexpectedShutdown(RDDProcessHost* aHost) {
   MOZ_ASSERT(mProcess && mProcess == aHost);
 
--- a/dom/media/ipc/RDDProcessManager.h
+++ b/dom/media/ipc/RDDProcessManager.h
@@ -59,16 +59,17 @@ class RDDProcessManager final : public R
   RDDChild* GetRDDChild() { return mRDDChild; }
 
   // Returns whether or not a RDD process was ever launched.
   bool AttemptedRDDProcess() const { return mNumProcessAttempts > 0; }
 
  private:
   // Called from our xpcom-shutdown observer.
   void OnXPCOMShutdown();
+  void OnPreferenceChange(const char16_t* aData);
 
   RDDProcessManager();
 
   // Shutdown the RDD process.
   void CleanShutdown();
   void DestroyProcess();
 
   DISALLOW_COPY_AND_ASSIGN(RDDProcessManager);
@@ -90,13 +91,17 @@ class RDDProcessManager final : public R
   RefPtr<Observer> mObserver;
   mozilla::ipc::TaskFactory<RDDProcessManager> mTaskFactory;
   uint32_t mNumProcessAttempts;
 
   // Fields that are associated with the current RDD process.
   RDDProcessHost* mProcess;
   uint64_t mProcessToken;
   RDDChild* mRDDChild;
+  // Collects any pref changes that occur during process launch (after
+  // the initial map is passed in command-line arguments) to be sent
+  // when the process can receive IPC messages.
+  nsTArray<mozilla::dom::Pref> mQueuedPrefs;
 };
 
 }  // namespace mozilla
 
 #endif  // _include_dom_media_ipc_RDDProcessManager_h_