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