blob: e38f8c50b10f045d94503d6f881b5eda66803d0c [file] [log] [blame] [edit]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/prefs/pref_watcher.h"
#include "base/bind.h"
#include "build/build_config.h"
#include "chrome/browser/profiles/incognito_helpers.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_preferences_util.h"
#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
#include "chrome/common/pref_names.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "content/public/common/renderer_preferences.h"
namespace {
// The list of prefs we want to observe.
const char* const kWebPrefsToObserve[] = {
#if BUILDFLAG(ENABLE_EXTENSIONS)
prefs::kAnimationPolicy,
#endif
prefs::kDataSaverEnabled,
prefs::kDefaultCharset,
prefs::kDisable3DAPIs,
prefs::kEnableHyperlinkAuditing,
prefs::kWebKitAllowRunningInsecureContent,
prefs::kWebKitDefaultFixedFontSize,
prefs::kWebKitDefaultFontSize,
prefs::kWebKitDomPasteEnabled,
#if defined(OS_ANDROID)
prefs::kWebKitFontScaleFactor,
prefs::kWebKitForceEnableZoom,
prefs::kWebKitPasswordEchoEnabled,
#endif
prefs::kWebKitJavascriptEnabled,
prefs::kWebKitLoadsImagesAutomatically,
prefs::kWebKitMinimumFontSize,
prefs::kWebKitMinimumLogicalFontSize,
prefs::kWebKitPluginsEnabled,
prefs::kWebkitTabsToLinks,
prefs::kWebKitTextAreasAreResizable,
prefs::kWebKitWebSecurityEnabled,
};
const int kWebPrefsToObserveLength = base::size(kWebPrefsToObserve);
} // namespace
// Watching all these settings per tab is slow when a user has a lot of tabs and
// and they use session restore. So watch them once per profile.
// http://crbug.com/452693
PrefWatcher::PrefWatcher(Profile* profile) : profile_(profile) {
pref_change_registrar_.Init(profile_->GetPrefs());
base::RepeatingClosure renderer_callback = base::BindRepeating(
&PrefWatcher::UpdateRendererPreferences, base::Unretained(this));
pref_change_registrar_.Add(prefs::kAcceptLanguages, renderer_callback);
pref_change_registrar_.Add(prefs::kEnableDoNotTrack, renderer_callback);
pref_change_registrar_.Add(prefs::kEnableReferrers, renderer_callback);
pref_change_registrar_.Add(prefs::kEnableEncryptedMedia, renderer_callback);
pref_change_registrar_.Add(prefs::kWebRTCMultipleRoutesEnabled,
renderer_callback);
pref_change_registrar_.Add(prefs::kWebRTCNonProxiedUdpEnabled,
renderer_callback);
pref_change_registrar_.Add(prefs::kWebRTCIPHandlingPolicy, renderer_callback);
pref_change_registrar_.Add(prefs::kWebRTCUDPPortRange, renderer_callback);
#if !defined(OS_MACOSX)
pref_change_registrar_.Add(prefs::kFullscreenAllowed, renderer_callback);
#endif
PrefChangeRegistrar::NamedChangeCallback webkit_callback =
base::BindRepeating(&PrefWatcher::OnWebPrefChanged,
base::Unretained(this));
for (int i = 0; i < kWebPrefsToObserveLength; ++i) {
const char* pref_name = kWebPrefsToObserve[i];
pref_change_registrar_.Add(pref_name, webkit_callback);
}
}
PrefWatcher::~PrefWatcher() = default;
void PrefWatcher::RegisterHelper(PrefsTabHelper* helper) {
tab_helpers_.insert(helper);
}
void PrefWatcher::UnregisterHelper(PrefsTabHelper* helper) {
tab_helpers_.erase(helper);
}
void PrefWatcher::RegisterWatcherForWorkers(
content::mojom::RendererPreferenceWatcherPtr worker_watcher) {
worker_watchers_.AddPtr(std::move(worker_watcher));
}
void PrefWatcher::Shutdown() {
pref_change_registrar_.RemoveAll();
}
void PrefWatcher::UpdateRendererPreferences() {
for (auto* helper : tab_helpers_)
helper->UpdateRendererPreferences();
content::RendererPreferences prefs;
renderer_preferences_util::UpdateFromSystemSettings(&prefs, profile_);
worker_watchers_.ForAllPtrs(
[&prefs](content::mojom::RendererPreferenceWatcher* watcher) {
watcher->NotifyUpdate(prefs);
});
}
void PrefWatcher::OnWebPrefChanged(const std::string& pref_name) {
for (auto* helper : tab_helpers_)
helper->OnWebPrefChanged(pref_name);
}
// static
PrefWatcher* PrefWatcherFactory::GetForProfile(Profile* profile) {
return static_cast<PrefWatcher*>(
GetInstance()->GetServiceForBrowserContext(profile, true));
}
// static
PrefWatcherFactory* PrefWatcherFactory::GetInstance() {
return base::Singleton<PrefWatcherFactory>::get();
}
PrefWatcherFactory::PrefWatcherFactory()
: BrowserContextKeyedServiceFactory(
"PrefWatcher",
BrowserContextDependencyManager::GetInstance()) {}
PrefWatcherFactory::~PrefWatcherFactory() = default;
KeyedService* PrefWatcherFactory::BuildServiceInstanceFor(
content::BrowserContext* browser_context) const {
return new PrefWatcher(Profile::FromBrowserContext(browser_context));
}
content::BrowserContext* PrefWatcherFactory::GetBrowserContextToUse(
content::BrowserContext* context) const {
return chrome::GetBrowserContextOwnInstanceInIncognito(context);
}
// static
PrefWatcher* PrefWatcher::Get(Profile* profile) {
return PrefWatcherFactory::GetForProfile(profile);
}