Commit d9bb3b78 authored by jam's avatar jam Committed by Commit bot

Watch the preferences for changes per profile instead of per tab.

PrefsTabHelper was watching > 1K prefs so that it could update the renderer side data structures when they change. When session restore was used and it had 50 tabs, this would take almost a second on a Z620. Switch this to watching these prefs once per profile instead.

BUG=452693

Review URL: https://codereview.chromium.org/878363002

Cr-Commit-Position: refs/heads/master@{#313573}
parent 9794e18c
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h"
#include "chrome/browser/ui/find_bar/find_bar_state_factory.h" #include "chrome/browser/ui/find_bar/find_bar_state_factory.h"
#include "chrome/browser/ui/global_error/global_error_service_factory.h" #include "chrome/browser/ui/global_error/global_error_service_factory.h"
#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
#include "chrome/browser/ui/tabs/pinned_tab_service_factory.h" #include "chrome/browser/ui/tabs/pinned_tab_service_factory.h"
#include "chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.h" #include "chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.h"
#include "chrome/browser/undo/bookmark_undo_service_factory.h" #include "chrome/browser/undo/bookmark_undo_service_factory.h"
...@@ -233,6 +234,7 @@ EnsureBrowserContextKeyedServiceFactoriesBuilt() { ...@@ -233,6 +234,7 @@ EnsureBrowserContextKeyedServiceFactoriesBuilt() {
#if defined(ENABLE_PLUGINS) #if defined(ENABLE_PLUGINS)
PluginPrefsFactory::GetInstance(); PluginPrefsFactory::GetInstance();
#endif #endif
PrefsTabHelper::GetServiceInstance();
policy::ProfilePolicyConnectorFactory::GetInstance(); policy::ProfilePolicyConnectorFactory::GetInstance();
#if defined(ENABLE_CONFIGURATION_POLICY) #if defined(ENABLE_CONFIGURATION_POLICY)
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
......
...@@ -4,9 +4,12 @@ ...@@ -4,9 +4,12 @@
#include "chrome/browser/ui/prefs/prefs_tab_helper.h" #include "chrome/browser/ui/prefs/prefs_tab_helper.h"
#include <set>
#include <string> #include <string>
#include "base/memory/singleton.h"
#include "base/prefs/overlay_user_pref_store.h" #include "base/prefs/overlay_user_pref_store.h"
#include "base/prefs/pref_change_registrar.h"
#include "base/prefs/pref_service.h" #include "base/prefs/pref_service.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
...@@ -14,6 +17,7 @@ ...@@ -14,6 +17,7 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/incognito_helpers.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_preferences_util.h" #include "chrome/browser/renderer_preferences_util.h"
#include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h" #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h"
...@@ -21,6 +25,9 @@ ...@@ -21,6 +25,9 @@
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "chrome/common/pref_names_util.h" #include "chrome/common/pref_names_util.h"
#include "chrome/grit/locale_settings.h" #include "chrome/grit/locale_settings.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/pref_registry/pref_registry_syncable.h" #include "components/pref_registry/pref_registry_syncable.h"
#include "content/public/browser/notification_details.h" #include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h" #include "content/public/browser/notification_service.h"
...@@ -328,25 +335,16 @@ void RegisterLocalizedFontPref( ...@@ -328,25 +335,16 @@ void RegisterLocalizedFontPref(
} // namespace } // namespace
PrefsTabHelper::PrefsTabHelper(WebContents* contents) // Watching all these settings per tab is slow when a user has a lot of tabs and
: web_contents_(contents), // and they use session restore. So watch them once per profile.
weak_ptr_factory_(this) { // http://crbug.com/452693
PrefService* prefs = GetProfile()->GetPrefs(); class PrefWatcher : public KeyedService {
pref_change_registrar_.Init(prefs); public:
if (prefs) { explicit PrefWatcher(Profile* profile) : profile_(profile) {
// If the tab is in an incognito profile, we track changes in the default pref_change_registrar_.Init(profile_->GetPrefs());
// zoom level of the parent profile instead.
Profile* profile_to_track = GetProfile()->GetOriginalProfile();
chrome::ChromeZoomLevelPrefs* zoom_level_prefs =
profile_to_track->GetZoomLevelPrefs();
base::Closure renderer_callback = base::Bind( base::Closure renderer_callback = base::Bind(
&PrefsTabHelper::UpdateRendererPreferences, base::Unretained(this)); &PrefWatcher::UpdateRendererPreferences, base::Unretained(this));
// Tests should not need to create a ZoomLevelPrefs.
if (zoom_level_prefs) {
default_zoom_level_subscription_ =
zoom_level_prefs->RegisterDefaultZoomLevelCallback(renderer_callback);
}
pref_change_registrar_.Add(prefs::kAcceptLanguages, renderer_callback); pref_change_registrar_.Add(prefs::kAcceptLanguages, renderer_callback);
pref_change_registrar_.Add(prefs::kEnableDoNotTrack, renderer_callback); pref_change_registrar_.Add(prefs::kEnableDoNotTrack, renderer_callback);
pref_change_registrar_.Add(prefs::kEnableReferrers, renderer_callback); pref_change_registrar_.Add(prefs::kEnableReferrers, renderer_callback);
...@@ -356,7 +354,7 @@ PrefsTabHelper::PrefsTabHelper(WebContents* contents) ...@@ -356,7 +354,7 @@ PrefsTabHelper::PrefsTabHelper(WebContents* contents)
#endif #endif
PrefChangeRegistrar::NamedChangeCallback webkit_callback = base::Bind( PrefChangeRegistrar::NamedChangeCallback webkit_callback = base::Bind(
&PrefsTabHelper::OnWebPrefChanged, base::Unretained(this)); &PrefWatcher::OnWebPrefChanged, base::Unretained(this));
for (int i = 0; i < kPrefsToObserveLength; ++i) { for (int i = 0; i < kPrefsToObserveLength; ++i) {
const char* pref_name = kPrefsToObserve[i]; const char* pref_name = kPrefsToObserve[i];
pref_change_registrar_.Add(pref_name, webkit_callback); pref_change_registrar_.Add(pref_name, webkit_callback);
...@@ -385,17 +383,109 @@ PrefsTabHelper::PrefsTabHelper(WebContents* contents) ...@@ -385,17 +383,109 @@ PrefsTabHelper::PrefsTabHelper(WebContents* contents)
webkit_callback); webkit_callback);
} }
static PrefWatcher* Get(Profile* profile);
void RegisterHelper(PrefsTabHelper* helper) {
helpers_.insert(helper);
}
void UnregisterHelper(PrefsTabHelper* helper) {
helpers_.erase(helper);
}
private:
// KeyedService overrides:
void Shutdown() override {
pref_change_registrar_.RemoveAll();
}
void UpdateRendererPreferences() {
for (const auto& helper : helpers_)
helper->UpdateRendererPreferences();
}
void OnWebPrefChanged(const std::string& pref_name) {
for (const auto& helper : helpers_)
helper->OnWebPrefChanged(pref_name);
}
Profile* profile_;
PrefChangeRegistrar pref_change_registrar_;
std::set<PrefsTabHelper*> helpers_;
};
class PrefWatcherFactory : public BrowserContextKeyedServiceFactory {
public:
static PrefWatcher* GetForProfile(Profile* profile) {
return static_cast<PrefWatcher*>(
GetInstance()->GetServiceForBrowserContext(profile, true));
}
static PrefWatcherFactory* GetInstance() {
return Singleton<PrefWatcherFactory>::get();
}
private:
friend struct DefaultSingletonTraits<PrefWatcherFactory>;
PrefWatcherFactory() : BrowserContextKeyedServiceFactory(
"PrefWatcher",
BrowserContextDependencyManager::GetInstance()) {
}
~PrefWatcherFactory() override {}
// BrowserContextKeyedServiceFactory:
KeyedService* BuildServiceInstanceFor(
content::BrowserContext* browser_context) const override {
return new PrefWatcher(Profile::FromBrowserContext(browser_context));
}
content::BrowserContext* GetBrowserContextToUse(
content::BrowserContext* context) const override {
return chrome::GetBrowserContextOwnInstanceInIncognito(context);
}
};
// static
PrefWatcher* PrefWatcher::Get(Profile* profile) {
return PrefWatcherFactory::GetForProfile(profile);
}
PrefsTabHelper::PrefsTabHelper(WebContents* contents)
: web_contents_(contents),
profile_(Profile::FromBrowserContext(web_contents_->GetBrowserContext())),
weak_ptr_factory_(this) {
PrefService* prefs = profile_->GetPrefs();
if (prefs) {
// If the tab is in an incognito profile, we track changes in the default
// zoom level of the parent profile instead.
Profile* profile_to_track = profile_->GetOriginalProfile();
chrome::ChromeZoomLevelPrefs* zoom_level_prefs =
profile_to_track->GetZoomLevelPrefs();
base::Closure renderer_callback = base::Bind(
&PrefsTabHelper::UpdateRendererPreferences, base::Unretained(this));
// Tests should not need to create a ZoomLevelPrefs.
if (zoom_level_prefs) {
default_zoom_level_subscription_ =
zoom_level_prefs->RegisterDefaultZoomLevelCallback(renderer_callback);
}
PrefWatcher::Get(profile_)->RegisterHelper(this);
}
content::RendererPreferences* render_prefs = content::RendererPreferences* render_prefs =
web_contents_->GetMutableRendererPrefs(); web_contents_->GetMutableRendererPrefs();
renderer_preferences_util::UpdateFromSystemSettings(render_prefs, renderer_preferences_util::UpdateFromSystemSettings(render_prefs,
GetProfile(), profile_,
web_contents_); web_contents_);
#if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES) #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES)
registrar_.Add(this, registrar_.Add(this,
chrome::NOTIFICATION_BROWSER_THEME_CHANGED, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
content::Source<ThemeService>( content::Source<ThemeService>(
ThemeServiceFactory::GetForProfile(GetProfile()))); ThemeServiceFactory::GetForProfile(profile_)));
#endif #endif
#if defined(USE_AURA) #if defined(USE_AURA)
registrar_.Add(this, registrar_.Add(this,
...@@ -405,6 +495,7 @@ PrefsTabHelper::PrefsTabHelper(WebContents* contents) ...@@ -405,6 +495,7 @@ PrefsTabHelper::PrefsTabHelper(WebContents* contents)
} }
PrefsTabHelper::~PrefsTabHelper() { PrefsTabHelper::~PrefsTabHelper() {
PrefWatcher::Get(profile_)->UnregisterHelper(this);
} }
// static // static
...@@ -575,6 +666,11 @@ void PrefsTabHelper::RegisterProfilePrefs( ...@@ -575,6 +666,11 @@ void PrefsTabHelper::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
} }
// static
void PrefsTabHelper::GetServiceInstance() {
PrefWatcherFactory::GetInstance();
}
void PrefsTabHelper::Observe(int type, void PrefsTabHelper::Observe(int type,
const content::NotificationSource& source, const content::NotificationSource& source,
const content::NotificationDetails& details) { const content::NotificationDetails& details) {
...@@ -604,14 +700,9 @@ void PrefsTabHelper::UpdateRendererPreferences() { ...@@ -604,14 +700,9 @@ void PrefsTabHelper::UpdateRendererPreferences() {
content::RendererPreferences* prefs = content::RendererPreferences* prefs =
web_contents_->GetMutableRendererPrefs(); web_contents_->GetMutableRendererPrefs();
renderer_preferences_util::UpdateFromSystemSettings( renderer_preferences_util::UpdateFromSystemSettings(
prefs, GetProfile(), web_contents_); prefs, profile_, web_contents_);
web_contents_->GetRenderViewHost()->SyncRendererPrefs(); web_contents_->GetRenderViewHost()->SyncRendererPrefs();
} }
Profile* PrefsTabHelper::GetProfile() {
return Profile::FromBrowserContext(web_contents_->GetBrowserContext());
}
void PrefsTabHelper::OnFontFamilyPrefChanged(const std::string& pref_name) { void PrefsTabHelper::OnFontFamilyPrefChanged(const std::string& pref_name) {
// When a font family pref's value goes from non-empty to the empty string, we // When a font family pref's value goes from non-empty to the empty string, we
// must add it to the usual WebPreferences struct passed to the renderer. // must add it to the usual WebPreferences struct passed to the renderer.
...@@ -630,7 +721,7 @@ void PrefsTabHelper::OnFontFamilyPrefChanged(const std::string& pref_name) { ...@@ -630,7 +721,7 @@ void PrefsTabHelper::OnFontFamilyPrefChanged(const std::string& pref_name) {
if (pref_names_util::ParseFontNamePrefPath(pref_name, if (pref_names_util::ParseFontNamePrefPath(pref_name,
&generic_family, &generic_family,
&script)) { &script)) {
PrefService* prefs = GetProfile()->GetPrefs(); PrefService* prefs = profile_->GetPrefs();
std::string pref_value = prefs->GetString(pref_name); std::string pref_value = prefs->GetString(pref_name);
if (pref_value.empty()) { if (pref_value.empty()) {
WebPreferences web_prefs = WebPreferences web_prefs =
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include "base/callback_list.h" #include "base/callback_list.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/prefs/pref_change_registrar.h"
#include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h" #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h"
#include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
...@@ -34,6 +33,7 @@ class PrefsTabHelper : public content::NotificationObserver, ...@@ -34,6 +33,7 @@ class PrefsTabHelper : public content::NotificationObserver,
static void InitIncognitoUserPrefStore(OverlayUserPrefStore* pref_store); static void InitIncognitoUserPrefStore(OverlayUserPrefStore* pref_store);
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
static void GetServiceInstance();
protected: protected:
// Update the RenderView's WebPreferences. Exposed as protected for testing. // Update the RenderView's WebPreferences. Exposed as protected for testing.
...@@ -42,6 +42,7 @@ class PrefsTabHelper : public content::NotificationObserver, ...@@ -42,6 +42,7 @@ class PrefsTabHelper : public content::NotificationObserver,
private: private:
explicit PrefsTabHelper(content::WebContents* contents); explicit PrefsTabHelper(content::WebContents* contents);
friend class content::WebContentsUserData<PrefsTabHelper>; friend class content::WebContentsUserData<PrefsTabHelper>;
friend class PrefWatcher;
// content::NotificationObserver overrides: // content::NotificationObserver overrides:
void Observe(int type, void Observe(int type,
...@@ -51,14 +52,12 @@ class PrefsTabHelper : public content::NotificationObserver, ...@@ -51,14 +52,12 @@ class PrefsTabHelper : public content::NotificationObserver,
// Update the WebContents's RendererPreferences. // Update the WebContents's RendererPreferences.
void UpdateRendererPreferences(); void UpdateRendererPreferences();
Profile* GetProfile();
void OnFontFamilyPrefChanged(const std::string& pref_name); void OnFontFamilyPrefChanged(const std::string& pref_name);
void OnWebPrefChanged(const std::string& pref_name); void OnWebPrefChanged(const std::string& pref_name);
content::WebContents* web_contents_; content::WebContents* web_contents_;
Profile* profile_;
content::NotificationRegistrar registrar_; content::NotificationRegistrar registrar_;
PrefChangeRegistrar pref_change_registrar_;
scoped_ptr<base::CallbackList<void(void)>::Subscription> scoped_ptr<base::CallbackList<void(void)>::Subscription>
style_sheet_subscription_; style_sheet_subscription_;
scoped_ptr<chrome::ChromeZoomLevelPrefs::DefaultZoomLevelSubscription> scoped_ptr<chrome::ChromeZoomLevelPrefs::DefaultZoomLevelSubscription>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment