Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: chrome/browser/ui/prefs/prefs_tab_helper.cc

Issue 878363002: Watch the preferences for changes per profile instead of per tab. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/prefs/prefs_tab_helper.h" 5 #include "chrome/browser/ui/prefs/prefs_tab_helper.h"
6 6
7 #include <set>
7 #include <string> 8 #include <string>
8 9
10 #include "base/memory/singleton.h"
9 #include "base/prefs/overlay_user_pref_store.h" 11 #include "base/prefs/overlay_user_pref_store.h"
12 #include "base/prefs/pref_change_registrar.h"
10 #include "base/prefs/pref_service.h" 13 #include "base/prefs/pref_service.h"
11 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
13 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
14 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
15 #include "chrome/browser/browser_process.h" 18 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/chrome_notification_types.h" 19 #include "chrome/browser/chrome_notification_types.h"
20 #include "chrome/browser/profiles/incognito_helpers.h"
17 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/renderer_preferences_util.h" 22 #include "chrome/browser/renderer_preferences_util.h"
19 #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h" 23 #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h"
20 #include "chrome/common/pref_font_webkit_names.h" 24 #include "chrome/common/pref_font_webkit_names.h"
21 #include "chrome/common/pref_names.h" 25 #include "chrome/common/pref_names.h"
22 #include "chrome/common/pref_names_util.h" 26 #include "chrome/common/pref_names_util.h"
23 #include "chrome/grit/locale_settings.h" 27 #include "chrome/grit/locale_settings.h"
28 #include "components/keyed_service/content/browser_context_dependency_manager.h"
29 #include "components/keyed_service/content/browser_context_keyed_service_factory .h"
30 #include "components/keyed_service/core/keyed_service.h"
24 #include "components/pref_registry/pref_registry_syncable.h" 31 #include "components/pref_registry/pref_registry_syncable.h"
25 #include "content/public/browser/notification_details.h" 32 #include "content/public/browser/notification_details.h"
26 #include "content/public/browser/notification_service.h" 33 #include "content/public/browser/notification_service.h"
27 #include "content/public/browser/render_view_host.h" 34 #include "content/public/browser/render_view_host.h"
28 #include "content/public/browser/web_contents.h" 35 #include "content/public/browser/web_contents.h"
29 #include "content/public/common/renderer_preferences.h" 36 #include "content/public/common/renderer_preferences.h"
30 #include "content/public/common/web_preferences.h" 37 #include "content/public/common/web_preferences.h"
31 #include "grit/platform_locale_settings.h" 38 #include "grit/platform_locale_settings.h"
32 #include "third_party/icu/source/common/unicode/uchar.h" 39 #include "third_party/icu/source/common/unicode/uchar.h"
33 #include "third_party/icu/source/common/unicode/uscript.h" 40 #include "third_party/icu/source/common/unicode/uscript.h"
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 user_prefs::PrefRegistrySyncable::PrefSyncStatus status) { 328 user_prefs::PrefRegistrySyncable::PrefSyncStatus status) {
322 int val = 0; 329 int val = 0;
323 bool success = base::StringToInt(l10n_util::GetStringUTF8( 330 bool success = base::StringToInt(l10n_util::GetStringUTF8(
324 default_message_id), &val); 331 default_message_id), &val);
325 DCHECK(success); 332 DCHECK(success);
326 registry->RegisterIntegerPref(path, val, status); 333 registry->RegisterIntegerPref(path, val, status);
327 } 334 }
328 335
329 } // namespace 336 } // namespace
330 337
331 PrefsTabHelper::PrefsTabHelper(WebContents* contents) 338 // Watching all these settings per tab is slow when a user has a lot of tabs and
332 : web_contents_(contents), 339 // and they use session restore. So watch them once per profile.
333 weak_ptr_factory_(this) { 340 // http://crbug.com/452693
Bernhard Bauer 2015/01/28 23:35:52 Nit: I don't think we even need to mention the bug
334 PrefService* prefs = GetProfile()->GetPrefs(); 341 class PrefWatcher : public KeyedService {
335 pref_change_registrar_.Init(prefs); 342 public:
336 if (prefs) { 343 explicit PrefWatcher(Profile* profile) : profile_(profile) {
337 // If the tab is in an incognito profile, we track changes in the default 344 pref_change_registrar_.Init(profile_->GetPrefs());
338 // zoom level of the parent profile instead.
339 Profile* profile_to_track = GetProfile()->GetOriginalProfile();
340 chrome::ChromeZoomLevelPrefs* zoom_level_prefs =
341 profile_to_track->GetZoomLevelPrefs();
342 345
343 base::Closure renderer_callback = base::Bind( 346 base::Closure renderer_callback = base::Bind(
344 &PrefsTabHelper::UpdateRendererPreferences, base::Unretained(this)); 347 &PrefWatcher::UpdateRendererPreferences, base::Unretained(this));
345 // Tests should not need to create a ZoomLevelPrefs.
346 if (zoom_level_prefs) {
347 default_zoom_level_subscription_ =
348 zoom_level_prefs->RegisterDefaultZoomLevelCallback(renderer_callback);
349 }
350 pref_change_registrar_.Add(prefs::kAcceptLanguages, renderer_callback); 348 pref_change_registrar_.Add(prefs::kAcceptLanguages, renderer_callback);
351 pref_change_registrar_.Add(prefs::kEnableDoNotTrack, renderer_callback); 349 pref_change_registrar_.Add(prefs::kEnableDoNotTrack, renderer_callback);
352 pref_change_registrar_.Add(prefs::kEnableReferrers, renderer_callback); 350 pref_change_registrar_.Add(prefs::kEnableReferrers, renderer_callback);
353 351
354 #if !defined(OS_MACOSX) 352 #if !defined(OS_MACOSX)
355 pref_change_registrar_.Add(prefs::kFullscreenAllowed, renderer_callback); 353 pref_change_registrar_.Add(prefs::kFullscreenAllowed, renderer_callback);
356 #endif 354 #endif
357 355
358 PrefChangeRegistrar::NamedChangeCallback webkit_callback = base::Bind( 356 PrefChangeRegistrar::NamedChangeCallback webkit_callback = base::Bind(
359 &PrefsTabHelper::OnWebPrefChanged, base::Unretained(this)); 357 &PrefWatcher::OnWebPrefChanged, base::Unretained(this));
360 for (int i = 0; i < kPrefsToObserveLength; ++i) { 358 for (int i = 0; i < kPrefsToObserveLength; ++i) {
361 const char* pref_name = kPrefsToObserve[i]; 359 const char* pref_name = kPrefsToObserve[i];
362 pref_change_registrar_.Add(pref_name, webkit_callback); 360 pref_change_registrar_.Add(pref_name, webkit_callback);
363 } 361 }
364 362
365 RegisterFontFamilyMapObserver(&pref_change_registrar_, 363 RegisterFontFamilyMapObserver(&pref_change_registrar_,
366 prefs::kWebKitStandardFontFamilyMap, 364 prefs::kWebKitStandardFontFamilyMap,
367 webkit_callback); 365 webkit_callback);
368 RegisterFontFamilyMapObserver(&pref_change_registrar_, 366 RegisterFontFamilyMapObserver(&pref_change_registrar_,
369 prefs::kWebKitFixedFontFamilyMap, 367 prefs::kWebKitFixedFontFamilyMap,
370 webkit_callback); 368 webkit_callback);
371 RegisterFontFamilyMapObserver(&pref_change_registrar_, 369 RegisterFontFamilyMapObserver(&pref_change_registrar_,
372 prefs::kWebKitSerifFontFamilyMap, 370 prefs::kWebKitSerifFontFamilyMap,
373 webkit_callback); 371 webkit_callback);
374 RegisterFontFamilyMapObserver(&pref_change_registrar_, 372 RegisterFontFamilyMapObserver(&pref_change_registrar_,
375 prefs::kWebKitSansSerifFontFamilyMap, 373 prefs::kWebKitSansSerifFontFamilyMap,
376 webkit_callback); 374 webkit_callback);
377 RegisterFontFamilyMapObserver(&pref_change_registrar_, 375 RegisterFontFamilyMapObserver(&pref_change_registrar_,
378 prefs::kWebKitCursiveFontFamilyMap, 376 prefs::kWebKitCursiveFontFamilyMap,
379 webkit_callback); 377 webkit_callback);
380 RegisterFontFamilyMapObserver(&pref_change_registrar_, 378 RegisterFontFamilyMapObserver(&pref_change_registrar_,
381 prefs::kWebKitFantasyFontFamilyMap, 379 prefs::kWebKitFantasyFontFamilyMap,
382 webkit_callback); 380 webkit_callback);
383 RegisterFontFamilyMapObserver(&pref_change_registrar_, 381 RegisterFontFamilyMapObserver(&pref_change_registrar_,
384 prefs::kWebKitPictographFontFamilyMap, 382 prefs::kWebKitPictographFontFamilyMap,
385 webkit_callback); 383 webkit_callback);
386 } 384 }
387 385
386 static PrefWatcher* Get(Profile* profile);
387
388 void RegisterHelper(PrefsTabHelper* helper) {
389 helpers_.insert(helper);
390 }
391
392 void UnregisterHelper(PrefsTabHelper* helper) {
393 helpers_.erase(helper);
394 }
395
396 private:
397 // KeyedService overrides:
398 void Shutdown() override {
399 pref_change_registrar_.RemoveAll();
400 }
401
402 void UpdateRendererPreferences() {
403 for (auto it = helpers_.begin(); it != helpers_.end(); ++it)
brettw 2015/01/28 19:13:29 for (const auto& helper : helpers_) helper->Upda
jam 2015/01/28 19:29:11 Done.
404 (*it)->UpdateRendererPreferences();
405 }
406
407 void OnWebPrefChanged(const std::string& pref_name) {
408 for (auto it = helpers_.begin(); it != helpers_.end(); ++it)
brettw 2015/01/28 19:13:29 Ditto
jam 2015/01/28 19:29:11 Done.
409 (*it)->OnWebPrefChanged(pref_name);
410 }
411
412 Profile* profile_;
413 PrefChangeRegistrar pref_change_registrar_;
414 std::set<PrefsTabHelper*> helpers_;
415 };
416
417 class PrefWatcherFactory : public BrowserContextKeyedServiceFactory {
418 public:
419 static PrefWatcher* GetForProfile(Profile* profile) {
420 return static_cast<PrefWatcher*>(
421 GetInstance()->GetServiceForBrowserContext(profile, true));
422 }
423
424 static PrefWatcherFactory* GetInstance() {
425 return Singleton<PrefWatcherFactory>::get();
426 }
427
428 private:
429 friend struct DefaultSingletonTraits<PrefWatcherFactory>;
430
431 PrefWatcherFactory() : BrowserContextKeyedServiceFactory(
Bernhard Bauer 2015/01/28 23:35:52 This looks somewhat weirdly formatted. Does breaki
432 "PrefWatcher",
433 BrowserContextDependencyManager::GetInstance()) {
434 }
435
436 ~PrefWatcherFactory() override {}
437
438 // BrowserContextKeyedServiceFactory:
439 KeyedService* BuildServiceInstanceFor(
440 content::BrowserContext* browser_context) const override {
441 return new PrefWatcher(Profile::FromBrowserContext(browser_context));
442 }
443
444 content::BrowserContext* GetBrowserContextToUse(
445 content::BrowserContext* context) const override {
446 return chrome::GetBrowserContextOwnInstanceInIncognito(context);
447 }
448 };
449
450 // static
451 PrefWatcher* PrefWatcher::Get(Profile* profile) {
452 return PrefWatcherFactory::GetForProfile(profile);
453 }
454
455 PrefsTabHelper::PrefsTabHelper(WebContents* contents)
456 : web_contents_(contents),
457 profile_(Profile::FromBrowserContext(web_contents_->GetBrowserContext())),
458 weak_ptr_factory_(this) {
459 PrefService* prefs = profile_->GetPrefs();
460 if (prefs) {
461 // If the tab is in an incognito profile, we track changes in the default
462 // zoom level of the parent profile instead.
463 Profile* profile_to_track = profile_->GetOriginalProfile();
464 chrome::ChromeZoomLevelPrefs* zoom_level_prefs =
465 profile_to_track->GetZoomLevelPrefs();
466
467 base::Closure renderer_callback = base::Bind(
468 &PrefsTabHelper::UpdateRendererPreferences, base::Unretained(this));
469 // Tests should not need to create a ZoomLevelPrefs.
470 if (zoom_level_prefs) {
471 default_zoom_level_subscription_ =
472 zoom_level_prefs->RegisterDefaultZoomLevelCallback(renderer_callback);
473 }
474
475 PrefWatcher::Get(profile_)->RegisterHelper(this);
476 }
477
388 content::RendererPreferences* render_prefs = 478 content::RendererPreferences* render_prefs =
389 web_contents_->GetMutableRendererPrefs(); 479 web_contents_->GetMutableRendererPrefs();
390 renderer_preferences_util::UpdateFromSystemSettings(render_prefs, 480 renderer_preferences_util::UpdateFromSystemSettings(render_prefs,
391 GetProfile(), 481 profile_,
392 web_contents_); 482 web_contents_);
393 483
394 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES) 484 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES)
395 registrar_.Add(this, 485 registrar_.Add(this,
396 chrome::NOTIFICATION_BROWSER_THEME_CHANGED, 486 chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
397 content::Source<ThemeService>( 487 content::Source<ThemeService>(
398 ThemeServiceFactory::GetForProfile(GetProfile()))); 488 ThemeServiceFactory::GetForProfile(profile_)));
399 #endif 489 #endif
400 #if defined(USE_AURA) 490 #if defined(USE_AURA)
401 registrar_.Add(this, 491 registrar_.Add(this,
402 chrome::NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED, 492 chrome::NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED,
403 content::NotificationService::AllSources()); 493 content::NotificationService::AllSources());
404 #endif 494 #endif
405 } 495 }
406 496
407 PrefsTabHelper::~PrefsTabHelper() { 497 PrefsTabHelper::~PrefsTabHelper() {
498 PrefWatcher::Get(profile_)->UnregisterHelper(this);
408 } 499 }
409 500
410 // static 501 // static
411 void PrefsTabHelper::InitIncognitoUserPrefStore( 502 void PrefsTabHelper::InitIncognitoUserPrefStore(
412 OverlayUserPrefStore* pref_store) { 503 OverlayUserPrefStore* pref_store) {
413 // List of keys that cannot be changed in the user prefs file by the incognito 504 // List of keys that cannot be changed in the user prefs file by the incognito
414 // profile. All preferences that store information about the browsing history 505 // profile. All preferences that store information about the browsing history
415 // or behavior of the user should have this property. 506 // or behavior of the user should have this property.
416 pref_store->RegisterOverlayPref(prefs::kBrowserWindowPlacement); 507 pref_store->RegisterOverlayPref(prefs::kBrowserWindowPlacement);
417 pref_store->RegisterOverlayPref(prefs::kSaveFileDefaultDirectory); 508 pref_store->RegisterOverlayPref(prefs::kSaveFileDefaultDirectory);
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 registry->RegisterStringPref( 659 registry->RegisterStringPref(
569 prefs::kStaticEncodings, 660 prefs::kStaticEncodings,
570 l10n_util::GetStringUTF8(IDS_STATIC_ENCODING_LIST), 661 l10n_util::GetStringUTF8(IDS_STATIC_ENCODING_LIST),
571 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 662 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
572 registry->RegisterStringPref( 663 registry->RegisterStringPref(
573 prefs::kRecentlySelectedEncoding, 664 prefs::kRecentlySelectedEncoding,
574 std::string(), 665 std::string(),
575 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 666 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
576 } 667 }
577 668
669 // static
670 void PrefsTabHelper::GetServiceInstance() {
671 PrefWatcherFactory::GetInstance();
672 }
673
578 void PrefsTabHelper::Observe(int type, 674 void PrefsTabHelper::Observe(int type,
579 const content::NotificationSource& source, 675 const content::NotificationSource& source,
580 const content::NotificationDetails& details) { 676 const content::NotificationDetails& details) {
581 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES) 677 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES)
582 if (type == chrome::NOTIFICATION_BROWSER_THEME_CHANGED) { 678 if (type == chrome::NOTIFICATION_BROWSER_THEME_CHANGED) {
583 UpdateRendererPreferences(); 679 UpdateRendererPreferences();
584 return; 680 return;
585 } 681 }
586 #endif 682 #endif
587 683
588 #if defined(USE_AURA) 684 #if defined(USE_AURA)
589 if (type == chrome::NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED) { 685 if (type == chrome::NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED) {
590 UpdateRendererPreferences(); 686 UpdateRendererPreferences();
591 return; 687 return;
592 } 688 }
593 #endif // defined(USE_AURA) 689 #endif // defined(USE_AURA)
594 690
595 NOTREACHED(); 691 NOTREACHED();
596 } 692 }
597 693
598 void PrefsTabHelper::UpdateWebPreferences() { 694 void PrefsTabHelper::UpdateWebPreferences() {
599 web_contents_->GetRenderViewHost()->UpdateWebkitPreferences( 695 web_contents_->GetRenderViewHost()->UpdateWebkitPreferences(
600 web_contents_->GetRenderViewHost()->GetWebkitPreferences()); 696 web_contents_->GetRenderViewHost()->GetWebkitPreferences());
601 } 697 }
602 698
603 void PrefsTabHelper::UpdateRendererPreferences() { 699 void PrefsTabHelper::UpdateRendererPreferences() {
604 content::RendererPreferences* prefs = 700 content::RendererPreferences* prefs =
605 web_contents_->GetMutableRendererPrefs(); 701 web_contents_->GetMutableRendererPrefs();
606 renderer_preferences_util::UpdateFromSystemSettings( 702 renderer_preferences_util::UpdateFromSystemSettings(
607 prefs, GetProfile(), web_contents_); 703 prefs, profile_, web_contents_);
608 web_contents_->GetRenderViewHost()->SyncRendererPrefs(); 704 web_contents_->GetRenderViewHost()->SyncRendererPrefs();
609 } 705 }
610
611 Profile* PrefsTabHelper::GetProfile() {
612 return Profile::FromBrowserContext(web_contents_->GetBrowserContext());
613 }
614
615 void PrefsTabHelper::OnFontFamilyPrefChanged(const std::string& pref_name) { 706 void PrefsTabHelper::OnFontFamilyPrefChanged(const std::string& pref_name) {
616 // When a font family pref's value goes from non-empty to the empty string, we 707 // When a font family pref's value goes from non-empty to the empty string, we
617 // must add it to the usual WebPreferences struct passed to the renderer. 708 // must add it to the usual WebPreferences struct passed to the renderer.
618 // 709 //
619 // The empty string means to fall back to the pref for the Common script 710 // The empty string means to fall back to the pref for the Common script
620 // ("Zyyy"). For example, if chrome.fonts.serif.Cyrl is the empty string, it 711 // ("Zyyy"). For example, if chrome.fonts.serif.Cyrl is the empty string, it
621 // means to use chrome.fonts.serif.Zyyy for Cyrillic script. Prefs that are 712 // means to use chrome.fonts.serif.Zyyy for Cyrillic script. Prefs that are
622 // the empty string are normally not passed to WebKit, since there are so many 713 // the empty string are normally not passed to WebKit, since there are so many
623 // of them that it would cause a performance regression. Not passing the pref 714 // of them that it would cause a performance regression. Not passing the pref
624 // is normally okay since WebKit does the desired fallback behavior regardless 715 // is normally okay since WebKit does the desired fallback behavior regardless
625 // of whether the empty string is passed or the pref is not passed at all. But 716 // of whether the empty string is passed or the pref is not passed at all. But
626 // if the pref has changed from non-empty to the empty string, we must let 717 // if the pref has changed from non-empty to the empty string, we must let
627 // WebKit know. 718 // WebKit know.
628 std::string generic_family; 719 std::string generic_family;
629 std::string script; 720 std::string script;
630 if (pref_names_util::ParseFontNamePrefPath(pref_name, 721 if (pref_names_util::ParseFontNamePrefPath(pref_name,
631 &generic_family, 722 &generic_family,
632 &script)) { 723 &script)) {
633 PrefService* prefs = GetProfile()->GetPrefs(); 724 PrefService* prefs = profile_->GetPrefs();
634 std::string pref_value = prefs->GetString(pref_name); 725 std::string pref_value = prefs->GetString(pref_name);
635 if (pref_value.empty()) { 726 if (pref_value.empty()) {
636 WebPreferences web_prefs = 727 WebPreferences web_prefs =
637 web_contents_->GetRenderViewHost()->GetWebkitPreferences(); 728 web_contents_->GetRenderViewHost()->GetWebkitPreferences();
638 OverrideFontFamily(&web_prefs, generic_family, script, std::string()); 729 OverrideFontFamily(&web_prefs, generic_family, script, std::string());
639 web_contents_->GetRenderViewHost()->UpdateWebkitPreferences(web_prefs); 730 web_contents_->GetRenderViewHost()->UpdateWebkitPreferences(web_prefs);
640 return; 731 return;
641 } 732 }
642 } 733 }
643 } 734 }
644 735
645 void PrefsTabHelper::OnWebPrefChanged(const std::string& pref_name) { 736 void PrefsTabHelper::OnWebPrefChanged(const std::string& pref_name) {
646 #if !defined(OS_ANDROID) 737 #if !defined(OS_ANDROID)
647 OnFontFamilyPrefChanged(pref_name); 738 OnFontFamilyPrefChanged(pref_name);
648 #endif 739 #endif
649 740
650 web_contents_->GetRenderViewHost()->OnWebkitPreferencesChanged(); 741 web_contents_->GetRenderViewHost()->OnWebkitPreferencesChanged();
651 } 742 }
OLDNEW
« chrome/browser/ui/prefs/prefs_tab_helper.h ('K') | « chrome/browser/ui/prefs/prefs_tab_helper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698