Bug 1550422 - P4. Sync preferences when they changed. r=mattwoodrow

This will allow to remove gfxPrefs later. On Windows in particular, the need to decide gfxPrefs vs StaticPrefs for the WMF decoders has caused several bugs in the past.
We will remove the confusion as a consequence.

Differential Revision: https://phabricator.services.mozilla.com/D30589

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jean-Yves Avenard 2019-05-25 10:12:51 +00:00
parent 5de210a9b9
commit 51808a6f27
7 changed files with 80 additions and 24 deletions

View File

@ -2957,30 +2957,8 @@ ContentParent::Observe(nsISupports* aSubject, const char* aTopic,
if (!strcmp(aTopic, "nsPref:changed")) {
// A pref changed. If it's not on the blacklist, inform child processes.
#define BLACKLIST_ENTRY(s) \
{ s, (sizeof(s) / sizeof(char16_t)) - 1 }
struct BlacklistEntry {
const char16_t* mPrefBranch;
size_t mLen;
};
// These prefs are not useful in child processes.
static const BlacklistEntry sContentPrefBranchBlacklist[] = {
BLACKLIST_ENTRY(u"app.update.lastUpdateTime."),
BLACKLIST_ENTRY(u"datareporting.policy."),
BLACKLIST_ENTRY(u"browser.safebrowsing.provider."),
BLACKLIST_ENTRY(u"browser.shell."),
BLACKLIST_ENTRY(u"browser.slowStartup."),
BLACKLIST_ENTRY(u"extensions.getAddons.cache."),
BLACKLIST_ENTRY(u"media.gmp-manager."),
BLACKLIST_ENTRY(u"media.gmp-gmpopenh264."),
BLACKLIST_ENTRY(u"privacy.sanitize."),
};
#undef BLACKLIST_ENTRY
for (const auto& entry : sContentPrefBranchBlacklist) {
if (NS_strncmp(entry.mPrefBranch, aData, entry.mLen) == 0) {
return NS_OK;
}
if (!ShouldSyncPreference(aData)) {
return NS_OK;
}
// We know prefs are ASCII here.
@ -3128,6 +3106,37 @@ ContentParent::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK;
}
/* static */
bool ContentParent::ShouldSyncPreference(const char16_t* aData) {
#define BLACKLIST_ENTRY(s) \
{ s, (sizeof(s) / sizeof(char16_t)) - 1 }
struct BlacklistEntry {
const char16_t* mPrefBranch;
size_t mLen;
};
// These prefs are not useful in child processes.
static const BlacklistEntry sContentPrefBranchBlacklist[] = {
BLACKLIST_ENTRY(u"app.update.lastUpdateTime."),
BLACKLIST_ENTRY(u"datareporting.policy."),
BLACKLIST_ENTRY(u"browser.safebrowsing.provider."),
BLACKLIST_ENTRY(u"browser.shell."),
BLACKLIST_ENTRY(u"browser.slowStartup."),
BLACKLIST_ENTRY(u"browser.startup."),
BLACKLIST_ENTRY(u"extensions.getAddons.cache."),
BLACKLIST_ENTRY(u"media.gmp-manager."),
BLACKLIST_ENTRY(u"media.gmp-gmpopenh264."),
BLACKLIST_ENTRY(u"privacy.sanitize."),
};
#undef BLACKLIST_ENTRY
for (const auto& entry : sContentPrefBranchBlacklist) {
if (NS_strncmp(entry.mPrefBranch, aData, entry.mLen) == 0) {
return false;
}
}
return true;
}
void ContentParent::UpdateNetworkLinkType() {
nsresult rv;
nsCOMPtr<nsINetworkLinkService> nls =

View File

@ -1216,6 +1216,8 @@ class ContentParent final : public PContentParent,
void UpdateNetworkLinkType();
static bool ShouldSyncPreference(const char16_t* aData);
private:
// Released in ActorDestroy; deliberately not exposed to the CC.
RefPtr<ContentParent> mSelfRef;

View File

@ -342,6 +342,11 @@ mozilla::ipc::IPCResult GPUParent::RecvUpdateVar(const GfxVarUpdate& aUpdate) {
return IPC_OK();
}
mozilla::ipc::IPCResult GPUParent::RecvPreferenceUpdate(const Pref& aPref) {
Preferences::SetPreference(aPref);
return IPC_OK();
}
static void CopyFeatureChange(Feature aFeature, Maybe<FeatureFailure>* aOut) {
FeatureState& feature = gfxConfig::GetFeature(aFeature);
if (feature.DisabledByDefault() || feature.IsEnabled()) {

View File

@ -57,6 +57,7 @@ class GPUParent final : public PGPUParent {
Endpoint<PProfilerChild>&& aEndpoint);
mozilla::ipc::IPCResult RecvUpdatePref(const GfxPrefSetting& pref);
mozilla::ipc::IPCResult RecvUpdateVar(const GfxVarUpdate& pref);
mozilla::ipc::IPCResult RecvPreferenceUpdate(const Pref& pref);
mozilla::ipc::IPCResult RecvNewContentCompositorManager(
Endpoint<PCompositorManagerParent>&& aEndpoint);
mozilla::ipc::IPCResult RecvNewContentImageBridge(

View File

@ -10,6 +10,7 @@
#include "GPUProcessHost.h"
#include "GPUProcessListener.h"
#include "mozilla/MemoryReportingProcess.h"
#include "mozilla/Preferences.h"
#include "mozilla/Sprintf.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/StaticPrefs.h"
@ -84,6 +85,7 @@ GPUProcessManager::GPUProcessManager()
mIdNamespace = AllocateNamespace();
mObserver = new Observer(this);
nsContentUtils::RegisterShutdownObserver(mObserver);
Preferences::AddStrongObserver(mObserver, "");
mDeviceResetLastTime = TimeStamp::Now();
@ -112,6 +114,8 @@ GPUProcessManager::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;
}
@ -119,12 +123,32 @@ GPUProcessManager::Observer::Observe(nsISupports* aSubject, const char* aTopic,
void GPUProcessManager::OnXPCOMShutdown() {
if (mObserver) {
nsContentUtils::UnregisterShutdownObserver(mObserver);
Preferences::RemoveObserver(mObserver, "");
mObserver = nullptr;
}
CleanShutdown();
}
void GPUProcessManager::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 (!!mGPUChild) {
MOZ_ASSERT(mQueuedPrefs.IsEmpty());
mGPUChild->SendPreferenceUpdate(pref);
} else {
mQueuedPrefs.AppendElement(pref);
}
}
void GPUProcessManager::LaunchGPUProcess() {
if (mProcess) {
return;
@ -342,6 +366,13 @@ void GPUProcessManager::OnProcessLaunchComplete(GPUProcessHost* aHost) {
std::move(vsyncChild));
mGPUChild->SendInitVsyncBridge(std::move(vsyncParent));
// Flush any pref updates that happened during launch and weren't
// included in the blobs set up in LaunchGPUProcess.
for (const mozilla::dom::Pref& pref : mQueuedPrefs) {
Unused << NS_WARN_IF(!mGPUChild->SendPreferenceUpdate(pref));
}
mQueuedPrefs.Clear();
CrashReporter::AnnotateCrashReport(
CrashReporter::Annotation::GPUProcessStatus,
NS_LITERAL_CSTRING("Running"));

View File

@ -179,6 +179,7 @@ class GPUProcessManager final : public GPUProcessHost::Listener {
private:
// Called from our xpcom-shutdown observer.
void OnXPCOMShutdown();
void OnPreferenceChange(const char16_t* aData);
bool CreateContentCompositorManager(
base::ProcessId aOtherProcess,
@ -277,6 +278,10 @@ class GPUProcessManager final : public GPUProcessHost::Listener {
uint64_t mProcessToken;
GPUChild* mGPUChild;
RefPtr<VsyncBridgeChild> mVsyncBridge;
// 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 gfx

View File

@ -6,6 +6,7 @@
include GraphicsMessages;
include MemoryReportTypes;
include HangTypes;
include PrefsTypes;
include protocol PAPZInputBridge;
include protocol PCompositorManager;
include protocol PImageBridge;
@ -66,6 +67,8 @@ parent:
async UpdatePref(GfxPrefSetting pref);
async UpdateVar(GfxVarUpdate var);
async PreferenceUpdate(Pref pref);
// Create a new content-process compositor bridge.
async NewContentCompositorManager(Endpoint<PCompositorManagerParent> endpoint);
async NewContentImageBridge(Endpoint<PImageBridgeParent> endpoint);