Home | History | Annotate | Download | only in prefs
      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
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/ui/prefs/prefs_tab_helper.h"
      6 
      7 #include <string>
      8 
      9 #include "base/prefs/overlay_user_pref_store.h"
     10 #include "base/prefs/pref_service.h"
     11 #include "base/strings/string_util.h"
     12 #include "base/strings/stringprintf.h"
     13 #include "base/strings/utf_string_conversions.h"
     14 #include "chrome/browser/browser_process.h"
     15 #include "chrome/browser/chrome_notification_types.h"
     16 #include "chrome/browser/profiles/profile.h"
     17 #include "chrome/browser/renderer_preferences_util.h"
     18 #include "chrome/common/pref_font_webkit_names.h"
     19 #include "chrome/common/pref_names.h"
     20 #include "chrome/common/pref_names_util.h"
     21 #include "components/pref_registry/pref_registry_syncable.h"
     22 #include "content/public/browser/notification_details.h"
     23 #include "content/public/browser/notification_service.h"
     24 #include "content/public/browser/render_view_host.h"
     25 #include "content/public/browser/web_contents.h"
     26 #include "grit/locale_settings.h"
     27 #include "grit/platform_locale_settings.h"
     28 #include "third_party/icu/source/common/unicode/uchar.h"
     29 #include "third_party/icu/source/common/unicode/uscript.h"
     30 #include "ui/base/l10n/l10n_util.h"
     31 #include "webkit/common/webpreferences.h"
     32 
     33 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES)
     34 #include "chrome/browser/themes/theme_service.h"
     35 #include "chrome/browser/themes/theme_service_factory.h"
     36 #endif
     37 
     38 #if defined(OS_WIN)
     39 #include "base/win/windows_version.h"
     40 #endif
     41 
     42 using content::WebContents;
     43 
     44 DEFINE_WEB_CONTENTS_USER_DATA_KEY(PrefsTabHelper);
     45 
     46 namespace {
     47 
     48 // The list of prefs we want to observe.
     49 const char* kPrefsToObserve[] = {
     50   prefs::kDefaultCharset,
     51   prefs::kWebKitAllowDisplayingInsecureContent,
     52   prefs::kWebKitAllowRunningInsecureContent,
     53   prefs::kWebKitDefaultFixedFontSize,
     54   prefs::kWebKitDefaultFontSize,
     55 #if defined(OS_ANDROID)
     56   prefs::kWebKitFontScaleFactor,
     57   prefs::kWebKitForceEnableZoom,
     58   prefs::kWebKitPasswordEchoEnabled,
     59 #endif
     60   prefs::kWebKitJavascriptEnabled,
     61   prefs::kWebKitJavaEnabled,
     62   prefs::kWebKitLoadsImagesAutomatically,
     63   prefs::kWebKitMinimumFontSize,
     64   prefs::kWebKitMinimumLogicalFontSize,
     65   prefs::kWebKitPluginsEnabled,
     66   prefs::kWebkitTabsToLinks,
     67   prefs::kWebKitUsesUniversalDetector
     68 };
     69 
     70 const int kPrefsToObserveLength = arraysize(kPrefsToObserve);
     71 
     72 #if !defined(OS_ANDROID)
     73 // Registers a preference under the path |pref_name| for each script used for
     74 // per-script font prefs.
     75 // For example, for WEBKIT_WEBPREFS_FONTS_SERIF ("fonts.serif"):
     76 // "fonts.serif.Arab", "fonts.serif.Hang", etc. are registered.
     77 // |fonts_with_defaults| contains all |pref_names| already registered since they
     78 // have a specified default value.
     79 // On Android there are no default values for these properties and there is no
     80 // way to set them (because extensions are not supported so the Font Settings
     81 // API cannot be used), so we can avoid registering them altogether.
     82 void RegisterFontFamilyPrefs(user_prefs::PrefRegistrySyncable* registry,
     83                              const std::set<std::string>& fonts_with_defaults) {
     84 
     85   // Expand the font concatenated with script name so this stays at RO memory
     86   // rather than allocated in heap.
     87   static const char* const kFontFamilyMap[] = {
     88 #define EXPAND_SCRIPT_FONT(map_name, script_name) map_name "." script_name,
     89 
     90 #include "chrome/common/pref_font_script_names-inl.h"
     91 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_CURSIVE)
     92 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_FANTASY)
     93 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_FIXED)
     94 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_PICTOGRAPH)
     95 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_SANSERIF)
     96 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_SERIF)
     97 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_STANDARD)
     98 
     99 #undef EXPAND_SCRIPT_FONT
    100   };
    101 
    102   for (size_t i = 0; i < arraysize(kFontFamilyMap); ++i) {
    103     const char* pref_name = kFontFamilyMap[i];
    104     if (fonts_with_defaults.find(pref_name) == fonts_with_defaults.end()) {
    105       // We haven't already set a default value for this font preference, so set
    106       // an empty string as the default.
    107       registry->RegisterStringPref(
    108           pref_name,
    109           std::string(),
    110           user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    111     }
    112   }
    113 }
    114 
    115 // Registers |obs| to observe per-script font prefs under the path |map_name|.
    116 // On android, there's no exposed way to change these prefs, so we can save
    117 // ~715KB of heap and some startup cycles by avoiding observing these prefs
    118 // since they will never change.
    119 void RegisterFontFamilyMapObserver(
    120     PrefChangeRegistrar* registrar,
    121     const char* map_name,
    122     const PrefChangeRegistrar::NamedChangeCallback& obs) {
    123   DCHECK(StartsWithASCII(map_name, "webkit.webprefs.", true));
    124   for (size_t i = 0; i < prefs::kWebKitScriptsForFontFamilyMapsLength; ++i) {
    125     const char* script = prefs::kWebKitScriptsForFontFamilyMaps[i];
    126     std::string pref_name = base::StringPrintf("%s.%s", map_name, script);
    127     registrar->Add(pref_name.c_str(), obs);
    128   }
    129 }
    130 #endif  // !defined(OS_ANDROID)
    131 
    132 #if defined(OS_WIN)
    133 // On Windows with antialising we want to use an alternate fixed font like
    134 // Consolas, which looks much better than Courier New.
    135 bool ShouldUseAlternateDefaultFixedFont(const std::string& script) {
    136   if (!StartsWithASCII(script, "courier", false))
    137     return false;
    138   UINT smooth_type = 0;
    139   SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &smooth_type, 0);
    140   return (base::win::GetVersion() >= base::win::VERSION_WIN7) &&
    141          (smooth_type == FE_FONTSMOOTHINGCLEARTYPE);
    142 }
    143 #endif
    144 
    145 struct FontDefault {
    146   const char* pref_name;
    147   int resource_id;
    148 };
    149 
    150 // Font pref defaults.  The prefs that have defaults vary by platform, since not
    151 // all platforms have fonts for all scripts for all generic families.
    152 // TODO(falken): add proper defaults when possible for all
    153 // platforms/scripts/generic families.
    154 const FontDefault kFontDefaults[] = {
    155   { prefs::kWebKitStandardFontFamily, IDS_STANDARD_FONT_FAMILY },
    156   { prefs::kWebKitFixedFontFamily, IDS_FIXED_FONT_FAMILY },
    157   { prefs::kWebKitSerifFontFamily, IDS_SERIF_FONT_FAMILY },
    158   { prefs::kWebKitSansSerifFontFamily, IDS_SANS_SERIF_FONT_FAMILY },
    159   { prefs::kWebKitCursiveFontFamily, IDS_CURSIVE_FONT_FAMILY },
    160   { prefs::kWebKitFantasyFontFamily, IDS_FANTASY_FONT_FAMILY },
    161   { prefs::kWebKitPictographFontFamily, IDS_PICTOGRAPH_FONT_FAMILY },
    162 #if defined(OS_CHROMEOS) || defined(OS_MACOSX) || defined(OS_WIN)
    163   { prefs::kWebKitStandardFontFamilyJapanese,
    164     IDS_STANDARD_FONT_FAMILY_JAPANESE },
    165   { prefs::kWebKitFixedFontFamilyJapanese, IDS_FIXED_FONT_FAMILY_JAPANESE },
    166   { prefs::kWebKitSerifFontFamilyJapanese, IDS_SERIF_FONT_FAMILY_JAPANESE },
    167   { prefs::kWebKitSansSerifFontFamilyJapanese,
    168     IDS_SANS_SERIF_FONT_FAMILY_JAPANESE },
    169   { prefs::kWebKitStandardFontFamilyKorean, IDS_STANDARD_FONT_FAMILY_KOREAN },
    170   { prefs::kWebKitSerifFontFamilyKorean, IDS_SERIF_FONT_FAMILY_KOREAN },
    171   { prefs::kWebKitSansSerifFontFamilyKorean,
    172     IDS_SANS_SERIF_FONT_FAMILY_KOREAN },
    173   { prefs::kWebKitStandardFontFamilySimplifiedHan,
    174     IDS_STANDARD_FONT_FAMILY_SIMPLIFIED_HAN },
    175   { prefs::kWebKitSerifFontFamilySimplifiedHan,
    176     IDS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN },
    177   { prefs::kWebKitSansSerifFontFamilySimplifiedHan,
    178     IDS_SANS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN },
    179   { prefs::kWebKitStandardFontFamilyTraditionalHan,
    180     IDS_STANDARD_FONT_FAMILY_TRADITIONAL_HAN },
    181   { prefs::kWebKitSerifFontFamilyTraditionalHan,
    182     IDS_SERIF_FONT_FAMILY_TRADITIONAL_HAN },
    183   { prefs::kWebKitSansSerifFontFamilyTraditionalHan,
    184     IDS_SANS_SERIF_FONT_FAMILY_TRADITIONAL_HAN },
    185 #endif
    186 #if defined(OS_CHROMEOS)
    187   { prefs::kWebKitStandardFontFamilyArabic, IDS_STANDARD_FONT_FAMILY_ARABIC },
    188   { prefs::kWebKitSerifFontFamilyArabic, IDS_SERIF_FONT_FAMILY_ARABIC },
    189   { prefs::kWebKitSansSerifFontFamilyArabic,
    190     IDS_SANS_SERIF_FONT_FAMILY_ARABIC },
    191   { prefs::kWebKitFixedFontFamilyKorean, IDS_FIXED_FONT_FAMILY_KOREAN },
    192   { prefs::kWebKitFixedFontFamilySimplifiedHan,
    193     IDS_FIXED_FONT_FAMILY_SIMPLIFIED_HAN },
    194   { prefs::kWebKitFixedFontFamilyTraditionalHan,
    195     IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN },
    196 #elif defined(OS_WIN)
    197   { prefs::kWebKitStandardFontFamilyCyrillic,
    198     IDS_STANDARD_FONT_FAMILY_CYRILLIC },
    199   { prefs::kWebKitFixedFontFamilyCyrillic, IDS_FIXED_FONT_FAMILY_CYRILLIC },
    200   { prefs::kWebKitSerifFontFamilyCyrillic, IDS_SERIF_FONT_FAMILY_CYRILLIC },
    201   { prefs::kWebKitSansSerifFontFamilyCyrillic,
    202     IDS_SANS_SERIF_FONT_FAMILY_CYRILLIC },
    203   { prefs::kWebKitStandardFontFamilyGreek, IDS_STANDARD_FONT_FAMILY_GREEK },
    204   { prefs::kWebKitFixedFontFamilyGreek, IDS_FIXED_FONT_FAMILY_GREEK },
    205   { prefs::kWebKitSerifFontFamilyGreek, IDS_SERIF_FONT_FAMILY_GREEK },
    206   { prefs::kWebKitSansSerifFontFamilyGreek, IDS_SANS_SERIF_FONT_FAMILY_GREEK },
    207   { prefs::kWebKitFixedFontFamilyKorean, IDS_FIXED_FONT_FAMILY_KOREAN },
    208   { prefs::kWebKitCursiveFontFamilyKorean, IDS_CURSIVE_FONT_FAMILY_KOREAN },
    209   { prefs::kWebKitFixedFontFamilySimplifiedHan,
    210     IDS_FIXED_FONT_FAMILY_SIMPLIFIED_HAN },
    211   { prefs::kWebKitFixedFontFamilyTraditionalHan,
    212     IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN },
    213 #endif
    214 };
    215 
    216 const size_t kFontDefaultsLength = arraysize(kFontDefaults);
    217 
    218 // Returns the script of the font pref |pref_name|.  For example, suppose
    219 // |pref_name| is "webkit.webprefs.fonts.serif.Hant".  Since the script code for
    220 // the script name "Hant" is USCRIPT_TRADITIONAL_HAN, the function returns
    221 // USCRIPT_TRADITIONAL_HAN.  |pref_name| must be a valid font pref name.
    222 UScriptCode GetScriptOfFontPref(const char* pref_name) {
    223   // ICU script names are four letters.
    224   static const size_t kScriptNameLength = 4;
    225 
    226   size_t len = strlen(pref_name);
    227   DCHECK_GT(len, kScriptNameLength);
    228   const char* scriptName = &pref_name[len - kScriptNameLength];
    229   int32 code = u_getPropertyValueEnum(UCHAR_SCRIPT, scriptName);
    230   DCHECK(code >= 0 && code < USCRIPT_CODE_LIMIT);
    231   return static_cast<UScriptCode>(code);
    232 }
    233 
    234 // If |scriptCode| is a member of a family of "similar" script codes, returns
    235 // the script code in that family that is used in font pref names.  For example,
    236 // USCRIPT_HANGUL and USCRIPT_KOREAN are considered equivalent for the purposes
    237 // of font selection.  Chrome uses the script code USCRIPT_HANGUL (script name
    238 // "Hang") in Korean font pref names (for example,
    239 // "webkit.webprefs.fonts.serif.Hang").  So, if |scriptCode| is USCRIPT_KOREAN,
    240 // the function returns USCRIPT_HANGUL.  If |scriptCode| is not a member of such
    241 // a family, returns |scriptCode|.
    242 UScriptCode GetScriptForFontPrefMatching(UScriptCode scriptCode) {
    243   switch (scriptCode) {
    244   case USCRIPT_HIRAGANA:
    245   case USCRIPT_KATAKANA:
    246   case USCRIPT_KATAKANA_OR_HIRAGANA:
    247     return USCRIPT_JAPANESE;
    248   case USCRIPT_KOREAN:
    249     return USCRIPT_HANGUL;
    250   default:
    251     return scriptCode;
    252   }
    253 }
    254 
    255 // Returns the primary script used by the browser's UI locale.  For example, if
    256 // the locale is "ru", the function returns USCRIPT_CYRILLIC, and if the locale
    257 // is "en", the function returns USCRIPT_LATIN.
    258 UScriptCode GetScriptOfBrowserLocale() {
    259   std::string locale = g_browser_process->GetApplicationLocale();
    260 
    261   // For Chinese locales, uscript_getCode() just returns USCRIPT_HAN but our
    262   // per-script fonts are for USCRIPT_SIMPLIFIED_HAN and
    263   // USCRIPT_TRADITIONAL_HAN.
    264   if (locale == "zh-CN")
    265     return USCRIPT_SIMPLIFIED_HAN;
    266   if (locale == "zh-TW")
    267     return USCRIPT_TRADITIONAL_HAN;
    268 
    269   UScriptCode code = USCRIPT_INVALID_CODE;
    270   UErrorCode err = U_ZERO_ERROR;
    271   uscript_getCode(locale.c_str(), &code, 1, &err);
    272 
    273   // Ignore the error that multiple scripts could be returned, since we only
    274   // want one script.
    275   if (U_FAILURE(err) && err != U_BUFFER_OVERFLOW_ERROR)
    276     code = USCRIPT_INVALID_CODE;
    277   return GetScriptForFontPrefMatching(code);
    278 }
    279 
    280 // Sets a font family pref in |prefs| to |pref_value|.
    281 void OverrideFontFamily(WebPreferences* prefs,
    282                         const std::string& generic_family,
    283                         const std::string& script,
    284                         const std::string& pref_value) {
    285   webkit_glue::ScriptFontFamilyMap* map = NULL;
    286   if (generic_family == "standard")
    287     map = &prefs->standard_font_family_map;
    288   else if (generic_family == "fixed")
    289     map = &prefs->fixed_font_family_map;
    290   else if (generic_family == "serif")
    291     map = &prefs->serif_font_family_map;
    292   else if (generic_family == "sansserif")
    293     map = &prefs->sans_serif_font_family_map;
    294   else if (generic_family == "cursive")
    295     map = &prefs->cursive_font_family_map;
    296   else if (generic_family == "fantasy")
    297     map = &prefs->fantasy_font_family_map;
    298   else if (generic_family == "pictograph")
    299     map = &prefs->pictograph_font_family_map;
    300   else
    301     NOTREACHED() << "Unknown generic font family: " << generic_family;
    302   (*map)[script] = base::UTF8ToUTF16(pref_value);
    303 }
    304 
    305 }  // namespace
    306 
    307 PrefsTabHelper::PrefsTabHelper(WebContents* contents)
    308     : web_contents_(contents),
    309       weak_ptr_factory_(this) {
    310   PrefService* prefs = GetProfile()->GetPrefs();
    311   pref_change_registrar_.Init(prefs);
    312   if (prefs) {
    313     base::Closure renderer_callback = base::Bind(
    314         &PrefsTabHelper::UpdateRendererPreferences, base::Unretained(this));
    315     pref_change_registrar_.Add(prefs::kAcceptLanguages, renderer_callback);
    316     pref_change_registrar_.Add(prefs::kDefaultZoomLevel, renderer_callback);
    317     pref_change_registrar_.Add(prefs::kEnableDoNotTrack, renderer_callback);
    318     pref_change_registrar_.Add(prefs::kEnableReferrers, renderer_callback);
    319 
    320 #if !defined(OS_MACOSX)
    321     pref_change_registrar_.Add(prefs::kFullscreenAllowed, renderer_callback);
    322 #endif
    323 
    324     PrefChangeRegistrar::NamedChangeCallback webkit_callback = base::Bind(
    325         &PrefsTabHelper::OnWebPrefChanged, base::Unretained(this));
    326     for (int i = 0; i < kPrefsToObserveLength; ++i) {
    327       const char* pref_name = kPrefsToObserve[i];
    328       DCHECK(std::string(pref_name) == prefs::kDefaultCharset ||
    329              StartsWithASCII(pref_name, "webkit.webprefs.", true));
    330       pref_change_registrar_.Add(pref_name, webkit_callback);
    331     }
    332 
    333 #if !defined(OS_ANDROID)
    334     RegisterFontFamilyMapObserver(&pref_change_registrar_,
    335                                   prefs::kWebKitStandardFontFamilyMap,
    336                                   webkit_callback);
    337     RegisterFontFamilyMapObserver(&pref_change_registrar_,
    338                                   prefs::kWebKitFixedFontFamilyMap,
    339                                   webkit_callback);
    340     RegisterFontFamilyMapObserver(&pref_change_registrar_,
    341                                   prefs::kWebKitSerifFontFamilyMap,
    342                                   webkit_callback);
    343     RegisterFontFamilyMapObserver(&pref_change_registrar_,
    344                                   prefs::kWebKitSansSerifFontFamilyMap,
    345                                   webkit_callback);
    346     RegisterFontFamilyMapObserver(&pref_change_registrar_,
    347                                   prefs::kWebKitCursiveFontFamilyMap,
    348                                   webkit_callback);
    349     RegisterFontFamilyMapObserver(&pref_change_registrar_,
    350                                   prefs::kWebKitFantasyFontFamilyMap,
    351                                   webkit_callback);
    352     RegisterFontFamilyMapObserver(&pref_change_registrar_,
    353                                   prefs::kWebKitPictographFontFamilyMap,
    354                                   webkit_callback);
    355 #endif  // !defined(OS_ANDROID)
    356   }
    357 
    358   renderer_preferences_util::UpdateFromSystemSettings(
    359       web_contents_->GetMutableRendererPrefs(), GetProfile());
    360 
    361 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES)
    362   registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
    363                  content::Source<ThemeService>(
    364                      ThemeServiceFactory::GetForProfile(GetProfile())));
    365 #endif
    366 #if defined(USE_AURA)
    367   registrar_.Add(this,
    368                  chrome::NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED,
    369                  content::NotificationService::AllSources());
    370 #endif
    371 }
    372 
    373 PrefsTabHelper::~PrefsTabHelper() {
    374 }
    375 
    376 // static
    377 void PrefsTabHelper::InitIncognitoUserPrefStore(
    378     OverlayUserPrefStore* pref_store) {
    379   // List of keys that cannot be changed in the user prefs file by the incognito
    380   // profile.  All preferences that store information about the browsing history
    381   // or behavior of the user should have this property.
    382   pref_store->RegisterOverlayPref(prefs::kBrowserWindowPlacement);
    383   pref_store->RegisterOverlayPref(prefs::kSaveFileDefaultDirectory);
    384 #if defined(OS_ANDROID) || defined(OS_IOS)
    385   pref_store->RegisterOverlayPref(prefs::kProxy);
    386 #endif  // defined(OS_ANDROID) || defined(OS_IOS)
    387 }
    388 
    389 // static
    390 void PrefsTabHelper::RegisterProfilePrefs(
    391     user_prefs::PrefRegistrySyncable* registry) {
    392   WebPreferences pref_defaults;
    393   registry->RegisterBooleanPref(
    394       prefs::kWebKitJavascriptEnabled,
    395       pref_defaults.javascript_enabled,
    396       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    397   registry->RegisterBooleanPref(
    398       prefs::kWebKitWebSecurityEnabled,
    399       pref_defaults.web_security_enabled,
    400       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    401   registry->RegisterBooleanPref(
    402       prefs::kWebKitJavascriptCanOpenWindowsAutomatically,
    403       true,
    404       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    405   registry->RegisterBooleanPref(
    406       prefs::kWebKitLoadsImagesAutomatically,
    407       pref_defaults.loads_images_automatically,
    408       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    409   registry->RegisterBooleanPref(
    410       prefs::kWebKitPluginsEnabled,
    411       pref_defaults.plugins_enabled,
    412       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    413   registry->RegisterBooleanPref(
    414       prefs::kWebKitDomPasteEnabled,
    415       pref_defaults.dom_paste_enabled,
    416       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    417   registry->RegisterBooleanPref(
    418       prefs::kWebKitShrinksStandaloneImagesToFit,
    419       pref_defaults.shrinks_standalone_images_to_fit,
    420       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    421   registry->RegisterDictionaryPref(
    422       prefs::kWebKitInspectorSettings,
    423       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    424   registry->RegisterBooleanPref(
    425       prefs::kWebKitTextAreasAreResizable,
    426       pref_defaults.text_areas_are_resizable,
    427       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    428   registry->RegisterBooleanPref(
    429       prefs::kWebKitJavaEnabled,
    430       pref_defaults.java_enabled,
    431       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    432   registry->RegisterBooleanPref(
    433       prefs::kWebkitTabsToLinks,
    434       pref_defaults.tabs_to_links,
    435       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    436   registry->RegisterBooleanPref(
    437       prefs::kWebKitAllowRunningInsecureContent,
    438       false,
    439       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    440   registry->RegisterBooleanPref(
    441       prefs::kWebKitAllowDisplayingInsecureContent,
    442       true,
    443       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    444   registry->RegisterBooleanPref(
    445       prefs::kEnableReferrers,
    446       true,
    447       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    448 #if defined(OS_ANDROID)
    449   registry->RegisterDoublePref(
    450       prefs::kWebKitFontScaleFactor,
    451       1.0,
    452       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    453   registry->RegisterBooleanPref(
    454       prefs::kWebKitForceEnableZoom,
    455       pref_defaults.force_enable_zoom,
    456       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    457   registry->RegisterBooleanPref(
    458       prefs::kWebKitPasswordEchoEnabled,
    459       pref_defaults.password_echo_enabled,
    460       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    461 #endif
    462   registry->RegisterLocalizedStringPref(
    463       prefs::kAcceptLanguages,
    464       IDS_ACCEPT_LANGUAGES,
    465       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
    466   registry->RegisterLocalizedStringPref(
    467       prefs::kDefaultCharset,
    468       IDS_DEFAULT_ENCODING,
    469       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
    470 
    471   // Register font prefs that have defaults.
    472   std::set<std::string> fonts_with_defaults;
    473   UScriptCode browser_script = GetScriptOfBrowserLocale();
    474   for (size_t i = 0; i < kFontDefaultsLength; ++i) {
    475     FontDefault pref = kFontDefaults[i];
    476 
    477 #if defined(OS_WIN)
    478     if (pref.pref_name == prefs::kWebKitFixedFontFamily) {
    479       if (ShouldUseAlternateDefaultFixedFont(
    480               l10n_util::GetStringUTF8(pref.resource_id)))
    481         pref.resource_id = IDS_FIXED_FONT_FAMILY_ALT_WIN;
    482     }
    483 #endif
    484 
    485     UScriptCode pref_script = GetScriptOfFontPref(pref.pref_name);
    486 
    487     // Suppress this default font pref value if it is for the primary script of
    488     // the browser's UI locale.  For example, if the pref is for the sans-serif
    489     // font for the Cyrillic script, and the browser locale is "ru" (Russian),
    490     // the default is suppressed.  Otherwise, the default would override the
    491     // user's font preferences when viewing pages in their native language.
    492     // This is because users have no way yet of customizing their per-script
    493     // font preferences.  The font prefs accessible in the options UI are for
    494     // the default, unknown script; these prefs have less priority than the
    495     // per-script font prefs when the script of the content is known.  This code
    496     // can possibly be removed later if users can easily access per-script font
    497     // prefs (e.g., via the extensions workflow), or the problem turns out to
    498     // not be really critical after all.
    499     if (browser_script != pref_script) {
    500       registry->RegisterLocalizedStringPref(
    501           pref.pref_name,
    502           pref.resource_id,
    503           user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    504       fonts_with_defaults.insert(pref.pref_name);
    505     }
    506   }
    507 
    508   // Register per-script font prefs that don't have defaults.
    509 #if !defined(OS_ANDROID)
    510   RegisterFontFamilyPrefs(registry, fonts_with_defaults);
    511 #endif
    512 
    513   registry->RegisterLocalizedIntegerPref(
    514       prefs::kWebKitDefaultFontSize,
    515       IDS_DEFAULT_FONT_SIZE,
    516       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    517   registry->RegisterLocalizedIntegerPref(
    518       prefs::kWebKitDefaultFixedFontSize,
    519       IDS_DEFAULT_FIXED_FONT_SIZE,
    520       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    521   registry->RegisterLocalizedIntegerPref(
    522       prefs::kWebKitMinimumFontSize,
    523       IDS_MINIMUM_FONT_SIZE,
    524       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    525   registry->RegisterLocalizedIntegerPref(
    526       prefs::kWebKitMinimumLogicalFontSize,
    527       IDS_MINIMUM_LOGICAL_FONT_SIZE,
    528       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    529   registry->RegisterLocalizedBooleanPref(
    530       prefs::kWebKitUsesUniversalDetector,
    531       IDS_USES_UNIVERSAL_DETECTOR,
    532       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
    533   registry->RegisterLocalizedStringPref(
    534       prefs::kStaticEncodings,
    535       IDS_STATIC_ENCODING_LIST,
    536       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    537   registry->RegisterStringPref(
    538       prefs::kRecentlySelectedEncoding,
    539       std::string(),
    540       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    541 }
    542 
    543 void PrefsTabHelper::Observe(int type,
    544                              const content::NotificationSource& source,
    545                              const content::NotificationDetails& details) {
    546 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES)
    547   if (type == chrome::NOTIFICATION_BROWSER_THEME_CHANGED) {
    548     UpdateRendererPreferences();
    549     return;
    550   }
    551 #endif
    552 
    553 #if defined(USE_AURA)
    554   if (type == chrome::NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED) {
    555     UpdateRendererPreferences();
    556     return;
    557   }
    558 #endif  // defined(USE_AURA)
    559 
    560   NOTREACHED();
    561 }
    562 
    563 void PrefsTabHelper::UpdateWebPreferences() {
    564   web_contents_->GetRenderViewHost()->UpdateWebkitPreferences(
    565       web_contents_->GetRenderViewHost()->GetWebkitPreferences());
    566 }
    567 
    568 void PrefsTabHelper::UpdateRendererPreferences() {
    569   renderer_preferences_util::UpdateFromSystemSettings(
    570       web_contents_->GetMutableRendererPrefs(), GetProfile());
    571   web_contents_->GetRenderViewHost()->SyncRendererPrefs();
    572 }
    573 
    574 Profile* PrefsTabHelper::GetProfile() {
    575   return Profile::FromBrowserContext(web_contents_->GetBrowserContext());
    576 }
    577 
    578 void PrefsTabHelper::OnWebPrefChanged(const std::string& pref_name) {
    579   // When a font family pref's value goes from non-empty to the empty string, we
    580   // must add it to the usual WebPreferences struct passed to the renderer.
    581   //
    582   // The empty string means to fall back to the pref for the Common script
    583   // ("Zyyy").  For example, if chrome.fonts.serif.Cyrl is the empty string, it
    584   // means to use chrome.fonts.serif.Zyyy for Cyrillic script. Prefs that are
    585   // the empty string are normally not passed to WebKit, since there are so many
    586   // of them that it would cause a performance regression. Not passing the pref
    587   // is normally okay since WebKit does the desired fallback behavior regardless
    588   // of whether the empty string is passed or the pref is not passed at all. But
    589   // if the pref has changed from non-empty to the empty string, we must let
    590   // WebKit know.
    591   std::string generic_family;
    592   std::string script;
    593   if (pref_names_util::ParseFontNamePrefPath(pref_name,
    594                                              &generic_family,
    595                                              &script)) {
    596     PrefService* prefs = GetProfile()->GetPrefs();
    597     std::string pref_value = prefs->GetString(pref_name.c_str());
    598     if (pref_value.empty()) {
    599       WebPreferences web_prefs =
    600           web_contents_->GetRenderViewHost()->GetWebkitPreferences();
    601       OverrideFontFamily(&web_prefs, generic_family, script, std::string());
    602       web_contents_->GetRenderViewHost()->UpdateWebkitPreferences(web_prefs);
    603       return;
    604     }
    605   }
    606 
    607   UpdateWebPreferences();
    608 }
    609