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