Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / prefs / prefs_tab_helper.cc
blob5cb2d6e067ac12b6808f94468a13a7d948ee9be2
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.
5 #include "chrome/browser/ui/prefs/prefs_tab_helper.h"
7 #include <set>
8 #include <string>
10 #include "base/memory/singleton.h"
11 #include "base/prefs/overlay_user_pref_store.h"
12 #include "base/prefs/pref_change_registrar.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/chrome_notification_types.h"
20 #include "chrome/browser/profiles/incognito_helpers.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/renderer_preferences_util.h"
23 #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h"
24 #include "chrome/common/pref_font_webkit_names.h"
25 #include "chrome/common/pref_names.h"
26 #include "chrome/common/pref_names_util.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"
31 #include "components/pref_registry/pref_registry_syncable.h"
32 #include "components/proxy_config/proxy_config_pref_names.h"
33 #include "content/public/browser/notification_details.h"
34 #include "content/public/browser/notification_service.h"
35 #include "content/public/browser/render_view_host.h"
36 #include "content/public/browser/web_contents.h"
37 #include "content/public/common/renderer_preferences.h"
38 #include "content/public/common/web_preferences.h"
39 #include "grit/platform_locale_settings.h"
40 #include "third_party/icu/source/common/unicode/uchar.h"
41 #include "third_party/icu/source/common/unicode/uscript.h"
42 #include "ui/base/l10n/l10n_util.h"
44 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES)
45 #include "chrome/browser/themes/theme_service.h"
46 #include "chrome/browser/themes/theme_service_factory.h"
47 #endif
49 #if defined(OS_WIN)
50 #include "base/win/windows_version.h"
51 #endif
53 using content::WebContents;
54 using content::WebPreferences;
56 DEFINE_WEB_CONTENTS_USER_DATA_KEY(PrefsTabHelper);
58 namespace {
60 // The list of prefs we want to observe.
61 const char* kPrefsToObserve[] = {
62 #if defined(ENABLE_EXTENSIONS)
63 prefs::kAnimationPolicy,
64 #endif
65 prefs::kDefaultCharset,
66 prefs::kDisable3DAPIs,
67 prefs::kEnableHyperlinkAuditing,
68 prefs::kWebKitAllowDisplayingInsecureContent,
69 prefs::kWebKitAllowRunningInsecureContent,
70 prefs::kWebKitDefaultFixedFontSize,
71 prefs::kWebKitDefaultFontSize,
72 prefs::kWebKitDomPasteEnabled,
73 #if defined(OS_ANDROID)
74 prefs::kWebKitFontScaleFactor,
75 prefs::kWebKitForceEnableZoom,
76 prefs::kWebKitPasswordEchoEnabled,
77 #endif
78 prefs::kWebKitJavascriptCanOpenWindowsAutomatically,
79 prefs::kWebKitJavascriptEnabled,
80 prefs::kWebKitLoadsImagesAutomatically,
81 prefs::kWebKitMinimumFontSize,
82 prefs::kWebKitMinimumLogicalFontSize,
83 prefs::kWebKitPluginsEnabled,
84 prefs::kWebkitTabsToLinks,
85 prefs::kWebKitTextAreasAreResizable,
86 prefs::kWebKitUsesUniversalDetector,
87 prefs::kWebKitWebSecurityEnabled,
90 const int kPrefsToObserveLength = arraysize(kPrefsToObserve);
92 #if !defined(OS_ANDROID)
93 // Registers a preference under the path |pref_name| for each script used for
94 // per-script font prefs.
95 // For example, for WEBKIT_WEBPREFS_FONTS_SERIF ("fonts.serif"):
96 // "fonts.serif.Arab", "fonts.serif.Hang", etc. are registered.
97 // |fonts_with_defaults| contains all |pref_names| already registered since they
98 // have a specified default value.
99 // On Android there are no default values for these properties and there is no
100 // way to set them (because extensions are not supported so the Font Settings
101 // API cannot be used), so we can avoid registering them altogether.
102 void RegisterFontFamilyPrefs(user_prefs::PrefRegistrySyncable* registry,
103 const std::set<std::string>& fonts_with_defaults) {
104 // Expand the font concatenated with script name so this stays at RO memory
105 // rather than allocated in heap.
106 static const char* const kFontFamilyMap[] = {
107 #define EXPAND_SCRIPT_FONT(map_name, script_name) map_name "." script_name,
109 #include "chrome/common/pref_font_script_names-inl.h"
110 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_CURSIVE)
111 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_FANTASY)
112 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_FIXED)
113 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_PICTOGRAPH)
114 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_SANSERIF)
115 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_SERIF)
116 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_STANDARD)
118 #undef EXPAND_SCRIPT_FONT
121 for (size_t i = 0; i < arraysize(kFontFamilyMap); ++i) {
122 const char* pref_name = kFontFamilyMap[i];
123 if (fonts_with_defaults.find(pref_name) == fonts_with_defaults.end()) {
124 // We haven't already set a default value for this font preference, so set
125 // an empty string as the default.
126 registry->RegisterStringPref(pref_name, std::string());
130 #endif // !defined(OS_ANDROID)
132 // Registers |obs| to observe per-script font prefs under the path |map_name|.
133 // On android, there's no exposed way to change these prefs, so we can save
134 // ~715KB of heap and some startup cycles by avoiding observing these prefs
135 // since they will never change.
136 void RegisterFontFamilyMapObserver(
137 PrefChangeRegistrar* registrar,
138 const char* map_name,
139 const PrefChangeRegistrar::NamedChangeCallback& obs) {
140 DCHECK(base::StartsWith(map_name, "webkit.webprefs.",
141 base::CompareCase::SENSITIVE));
143 for (size_t i = 0; i < prefs::kWebKitScriptsForFontFamilyMapsLength; ++i) {
144 const char* script = prefs::kWebKitScriptsForFontFamilyMaps[i];
145 registrar->Add(base::StringPrintf("%s.%s", map_name, script), obs);
149 #if defined(OS_WIN)
150 // On Windows with antialising we want to use an alternate fixed font like
151 // Consolas, which looks much better than Courier New.
152 bool ShouldUseAlternateDefaultFixedFont(const std::string& script) {
153 if (!base::StartsWith(script, "courier",
154 base::CompareCase::INSENSITIVE_ASCII))
155 return false;
156 UINT smooth_type = 0;
157 SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &smooth_type, 0);
158 return (base::win::GetVersion() >= base::win::VERSION_WIN7) &&
159 (smooth_type == FE_FONTSMOOTHINGCLEARTYPE);
161 #endif
163 struct FontDefault {
164 const char* pref_name;
165 int resource_id;
168 // Font pref defaults. The prefs that have defaults vary by platform, since not
169 // all platforms have fonts for all scripts for all generic families.
170 // TODO(falken): add proper defaults when possible for all
171 // platforms/scripts/generic families.
172 const FontDefault kFontDefaults[] = {
173 { prefs::kWebKitStandardFontFamily, IDS_STANDARD_FONT_FAMILY },
174 { prefs::kWebKitFixedFontFamily, IDS_FIXED_FONT_FAMILY },
175 { prefs::kWebKitSerifFontFamily, IDS_SERIF_FONT_FAMILY },
176 { prefs::kWebKitSansSerifFontFamily, IDS_SANS_SERIF_FONT_FAMILY },
177 { prefs::kWebKitCursiveFontFamily, IDS_CURSIVE_FONT_FAMILY },
178 { prefs::kWebKitFantasyFontFamily, IDS_FANTASY_FONT_FAMILY },
179 { prefs::kWebKitPictographFontFamily, IDS_PICTOGRAPH_FONT_FAMILY },
180 #if defined(OS_CHROMEOS) || defined(OS_MACOSX) || defined(OS_WIN)
181 { prefs::kWebKitStandardFontFamilyJapanese,
182 IDS_STANDARD_FONT_FAMILY_JAPANESE },
183 { prefs::kWebKitFixedFontFamilyJapanese, IDS_FIXED_FONT_FAMILY_JAPANESE },
184 { prefs::kWebKitSerifFontFamilyJapanese, IDS_SERIF_FONT_FAMILY_JAPANESE },
185 { prefs::kWebKitSansSerifFontFamilyJapanese,
186 IDS_SANS_SERIF_FONT_FAMILY_JAPANESE },
187 { prefs::kWebKitStandardFontFamilyKorean, IDS_STANDARD_FONT_FAMILY_KOREAN },
188 { prefs::kWebKitSerifFontFamilyKorean, IDS_SERIF_FONT_FAMILY_KOREAN },
189 { prefs::kWebKitSansSerifFontFamilyKorean,
190 IDS_SANS_SERIF_FONT_FAMILY_KOREAN },
191 { prefs::kWebKitStandardFontFamilySimplifiedHan,
192 IDS_STANDARD_FONT_FAMILY_SIMPLIFIED_HAN },
193 { prefs::kWebKitSerifFontFamilySimplifiedHan,
194 IDS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN },
195 { prefs::kWebKitSansSerifFontFamilySimplifiedHan,
196 IDS_SANS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN },
197 { prefs::kWebKitStandardFontFamilyTraditionalHan,
198 IDS_STANDARD_FONT_FAMILY_TRADITIONAL_HAN },
199 { prefs::kWebKitSerifFontFamilyTraditionalHan,
200 IDS_SERIF_FONT_FAMILY_TRADITIONAL_HAN },
201 { prefs::kWebKitSansSerifFontFamilyTraditionalHan,
202 IDS_SANS_SERIF_FONT_FAMILY_TRADITIONAL_HAN },
203 #endif
204 #if defined(OS_CHROMEOS)
205 { prefs::kWebKitStandardFontFamilyArabic, IDS_STANDARD_FONT_FAMILY_ARABIC },
206 { prefs::kWebKitSerifFontFamilyArabic, IDS_SERIF_FONT_FAMILY_ARABIC },
207 { prefs::kWebKitSansSerifFontFamilyArabic,
208 IDS_SANS_SERIF_FONT_FAMILY_ARABIC },
209 { prefs::kWebKitFixedFontFamilyKorean, IDS_FIXED_FONT_FAMILY_KOREAN },
210 { prefs::kWebKitFixedFontFamilySimplifiedHan,
211 IDS_FIXED_FONT_FAMILY_SIMPLIFIED_HAN },
212 { prefs::kWebKitFixedFontFamilyTraditionalHan,
213 IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN },
214 #elif defined(OS_WIN)
215 { prefs::kWebKitFixedFontFamilyArabic, IDS_FIXED_FONT_FAMILY_ARABIC },
216 { prefs::kWebKitSansSerifFontFamilyArabic,
217 IDS_SANS_SERIF_FONT_FAMILY_ARABIC },
218 { prefs::kWebKitStandardFontFamilyCyrillic,
219 IDS_STANDARD_FONT_FAMILY_CYRILLIC },
220 { prefs::kWebKitFixedFontFamilyCyrillic, IDS_FIXED_FONT_FAMILY_CYRILLIC },
221 { prefs::kWebKitSerifFontFamilyCyrillic, IDS_SERIF_FONT_FAMILY_CYRILLIC },
222 { prefs::kWebKitSansSerifFontFamilyCyrillic,
223 IDS_SANS_SERIF_FONT_FAMILY_CYRILLIC },
224 { prefs::kWebKitStandardFontFamilyGreek, IDS_STANDARD_FONT_FAMILY_GREEK },
225 { prefs::kWebKitFixedFontFamilyGreek, IDS_FIXED_FONT_FAMILY_GREEK },
226 { prefs::kWebKitSerifFontFamilyGreek, IDS_SERIF_FONT_FAMILY_GREEK },
227 { prefs::kWebKitSansSerifFontFamilyGreek, IDS_SANS_SERIF_FONT_FAMILY_GREEK },
228 { prefs::kWebKitFixedFontFamilyKorean, IDS_FIXED_FONT_FAMILY_KOREAN },
229 { prefs::kWebKitCursiveFontFamilyKorean, IDS_CURSIVE_FONT_FAMILY_KOREAN },
230 { prefs::kWebKitFixedFontFamilySimplifiedHan,
231 IDS_FIXED_FONT_FAMILY_SIMPLIFIED_HAN },
232 { prefs::kWebKitFixedFontFamilyTraditionalHan,
233 IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN },
234 #endif
237 const size_t kFontDefaultsLength = arraysize(kFontDefaults);
239 // Returns the script of the font pref |pref_name|. For example, suppose
240 // |pref_name| is "webkit.webprefs.fonts.serif.Hant". Since the script code for
241 // the script name "Hant" is USCRIPT_TRADITIONAL_HAN, the function returns
242 // USCRIPT_TRADITIONAL_HAN. |pref_name| must be a valid font pref name.
243 UScriptCode GetScriptOfFontPref(const char* pref_name) {
244 // ICU script names are four letters.
245 static const size_t kScriptNameLength = 4;
247 size_t len = strlen(pref_name);
248 DCHECK_GT(len, kScriptNameLength);
249 const char* scriptName = &pref_name[len - kScriptNameLength];
250 int32 code = u_getPropertyValueEnum(UCHAR_SCRIPT, scriptName);
251 DCHECK(code >= 0 && code < USCRIPT_CODE_LIMIT);
252 return static_cast<UScriptCode>(code);
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();
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 // For Korean and Japanese, multiple scripts are returned by
269 // |uscript_getCode|, but we're passing a one entry buffer leading
270 // the buffer to be filled by USCRIPT_INVALID_CODE. We need to
271 // hard-code the results for them.
272 if (locale == "ko")
273 return USCRIPT_HANGUL;
274 if (locale == "ja")
275 return USCRIPT_JAPANESE;
277 UScriptCode code = USCRIPT_INVALID_CODE;
278 UErrorCode err = U_ZERO_ERROR;
279 uscript_getCode(locale.c_str(), &code, 1, &err);
281 if (U_FAILURE(err))
282 code = USCRIPT_INVALID_CODE;
283 return code;
286 // Sets a font family pref in |prefs| to |pref_value|.
287 void OverrideFontFamily(WebPreferences* prefs,
288 const std::string& generic_family,
289 const std::string& script,
290 const std::string& pref_value) {
291 content::ScriptFontFamilyMap* map = NULL;
292 if (generic_family == "standard")
293 map = &prefs->standard_font_family_map;
294 else if (generic_family == "fixed")
295 map = &prefs->fixed_font_family_map;
296 else if (generic_family == "serif")
297 map = &prefs->serif_font_family_map;
298 else if (generic_family == "sansserif")
299 map = &prefs->sans_serif_font_family_map;
300 else if (generic_family == "cursive")
301 map = &prefs->cursive_font_family_map;
302 else if (generic_family == "fantasy")
303 map = &prefs->fantasy_font_family_map;
304 else if (generic_family == "pictograph")
305 map = &prefs->pictograph_font_family_map;
306 else
307 NOTREACHED() << "Unknown generic font family: " << generic_family;
308 (*map)[script] = base::UTF8ToUTF16(pref_value);
311 void RegisterLocalizedFontPref(user_prefs::PrefRegistrySyncable* registry,
312 const char* path,
313 int default_message_id) {
314 int val = 0;
315 bool success = base::StringToInt(l10n_util::GetStringUTF8(
316 default_message_id), &val);
317 DCHECK(success);
318 registry->RegisterIntegerPref(path, val);
321 } // namespace
323 // Watching all these settings per tab is slow when a user has a lot of tabs and
324 // and they use session restore. So watch them once per profile.
325 // http://crbug.com/452693
326 class PrefWatcher : public KeyedService {
327 public:
328 explicit PrefWatcher(Profile* profile) : profile_(profile) {
329 pref_change_registrar_.Init(profile_->GetPrefs());
331 base::Closure renderer_callback = base::Bind(
332 &PrefWatcher::UpdateRendererPreferences, base::Unretained(this));
333 pref_change_registrar_.Add(prefs::kAcceptLanguages, renderer_callback);
334 pref_change_registrar_.Add(prefs::kEnableDoNotTrack, renderer_callback);
335 pref_change_registrar_.Add(prefs::kEnableReferrers, renderer_callback);
337 #if defined(ENABLE_WEBRTC)
338 pref_change_registrar_.Add(prefs::kWebRTCMultipleRoutesEnabled,
339 renderer_callback);
340 pref_change_registrar_.Add(prefs::kWebRTCNonProxiedUdpEnabled,
341 renderer_callback);
342 #endif
344 #if !defined(OS_MACOSX)
345 pref_change_registrar_.Add(prefs::kFullscreenAllowed, renderer_callback);
346 #endif
348 PrefChangeRegistrar::NamedChangeCallback webkit_callback = base::Bind(
349 &PrefWatcher::OnWebPrefChanged, base::Unretained(this));
350 for (int i = 0; i < kPrefsToObserveLength; ++i) {
351 const char* pref_name = kPrefsToObserve[i];
352 pref_change_registrar_.Add(pref_name, webkit_callback);
355 RegisterFontFamilyMapObserver(&pref_change_registrar_,
356 prefs::kWebKitStandardFontFamilyMap,
357 webkit_callback);
358 RegisterFontFamilyMapObserver(&pref_change_registrar_,
359 prefs::kWebKitFixedFontFamilyMap,
360 webkit_callback);
361 RegisterFontFamilyMapObserver(&pref_change_registrar_,
362 prefs::kWebKitSerifFontFamilyMap,
363 webkit_callback);
364 RegisterFontFamilyMapObserver(&pref_change_registrar_,
365 prefs::kWebKitSansSerifFontFamilyMap,
366 webkit_callback);
367 RegisterFontFamilyMapObserver(&pref_change_registrar_,
368 prefs::kWebKitCursiveFontFamilyMap,
369 webkit_callback);
370 RegisterFontFamilyMapObserver(&pref_change_registrar_,
371 prefs::kWebKitFantasyFontFamilyMap,
372 webkit_callback);
373 RegisterFontFamilyMapObserver(&pref_change_registrar_,
374 prefs::kWebKitPictographFontFamilyMap,
375 webkit_callback);
378 static PrefWatcher* Get(Profile* profile);
380 void RegisterHelper(PrefsTabHelper* helper) {
381 helpers_.insert(helper);
384 void UnregisterHelper(PrefsTabHelper* helper) {
385 helpers_.erase(helper);
388 private:
389 // KeyedService overrides:
390 void Shutdown() override {
391 pref_change_registrar_.RemoveAll();
394 void UpdateRendererPreferences() {
395 for (const auto& helper : helpers_)
396 helper->UpdateRendererPreferences();
399 void OnWebPrefChanged(const std::string& pref_name) {
400 for (const auto& helper : helpers_)
401 helper->OnWebPrefChanged(pref_name);
404 Profile* profile_;
405 PrefChangeRegistrar pref_change_registrar_;
406 std::set<PrefsTabHelper*> helpers_;
409 class PrefWatcherFactory : public BrowserContextKeyedServiceFactory {
410 public:
411 static PrefWatcher* GetForProfile(Profile* profile) {
412 return static_cast<PrefWatcher*>(
413 GetInstance()->GetServiceForBrowserContext(profile, true));
416 static PrefWatcherFactory* GetInstance() {
417 return base::Singleton<PrefWatcherFactory>::get();
420 private:
421 friend struct base::DefaultSingletonTraits<PrefWatcherFactory>;
423 PrefWatcherFactory() : BrowserContextKeyedServiceFactory(
424 "PrefWatcher",
425 BrowserContextDependencyManager::GetInstance()) {
428 ~PrefWatcherFactory() override {}
430 // BrowserContextKeyedServiceFactory:
431 KeyedService* BuildServiceInstanceFor(
432 content::BrowserContext* browser_context) const override {
433 return new PrefWatcher(Profile::FromBrowserContext(browser_context));
436 content::BrowserContext* GetBrowserContextToUse(
437 content::BrowserContext* context) const override {
438 return chrome::GetBrowserContextOwnInstanceInIncognito(context);
442 // static
443 PrefWatcher* PrefWatcher::Get(Profile* profile) {
444 return PrefWatcherFactory::GetForProfile(profile);
447 PrefsTabHelper::PrefsTabHelper(WebContents* contents)
448 : web_contents_(contents),
449 profile_(Profile::FromBrowserContext(web_contents_->GetBrowserContext())),
450 weak_ptr_factory_(this) {
451 PrefService* prefs = profile_->GetPrefs();
452 if (prefs) {
453 // If the tab is in an incognito profile, we track changes in the default
454 // zoom level of the parent profile instead.
455 Profile* profile_to_track = profile_->GetOriginalProfile();
456 ChromeZoomLevelPrefs* zoom_level_prefs =
457 profile_to_track->GetZoomLevelPrefs();
459 base::Closure renderer_callback = base::Bind(
460 &PrefsTabHelper::UpdateRendererPreferences, base::Unretained(this));
461 // Tests should not need to create a ZoomLevelPrefs.
462 if (zoom_level_prefs) {
463 default_zoom_level_subscription_ =
464 zoom_level_prefs->RegisterDefaultZoomLevelCallback(renderer_callback);
467 PrefWatcher::Get(profile_)->RegisterHelper(this);
470 content::RendererPreferences* render_prefs =
471 web_contents_->GetMutableRendererPrefs();
472 renderer_preferences_util::UpdateFromSystemSettings(render_prefs,
473 profile_,
474 web_contents_);
476 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES)
477 registrar_.Add(this,
478 chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
479 content::Source<ThemeService>(
480 ThemeServiceFactory::GetForProfile(profile_)));
481 #endif
482 #if defined(USE_AURA)
483 registrar_.Add(this,
484 chrome::NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED,
485 content::NotificationService::AllSources());
486 #endif
489 PrefsTabHelper::~PrefsTabHelper() {
490 PrefWatcher::Get(profile_)->UnregisterHelper(this);
493 // static
494 void PrefsTabHelper::RegisterProfilePrefs(
495 user_prefs::PrefRegistrySyncable* registry) {
496 WebPreferences pref_defaults;
497 registry->RegisterBooleanPref(prefs::kWebKitJavascriptEnabled,
498 pref_defaults.javascript_enabled);
499 registry->RegisterBooleanPref(prefs::kWebKitWebSecurityEnabled,
500 pref_defaults.web_security_enabled);
501 registry->RegisterBooleanPref(
502 prefs::kWebKitJavascriptCanOpenWindowsAutomatically, true);
503 registry->RegisterBooleanPref(prefs::kWebKitLoadsImagesAutomatically,
504 pref_defaults.loads_images_automatically);
505 registry->RegisterBooleanPref(prefs::kWebKitPluginsEnabled,
506 pref_defaults.plugins_enabled);
507 registry->RegisterBooleanPref(prefs::kWebKitDomPasteEnabled,
508 pref_defaults.dom_paste_enabled);
509 registry->RegisterBooleanPref(prefs::kWebKitTextAreasAreResizable,
510 pref_defaults.text_areas_are_resizable);
511 registry->RegisterBooleanPref(prefs::kWebkitTabsToLinks,
512 pref_defaults.tabs_to_links);
513 registry->RegisterBooleanPref(prefs::kWebKitAllowRunningInsecureContent,
514 false);
515 registry->RegisterBooleanPref(prefs::kWebKitAllowDisplayingInsecureContent,
516 true);
517 registry->RegisterBooleanPref(prefs::kEnableReferrers, true);
518 #if defined(OS_ANDROID)
519 registry->RegisterDoublePref(prefs::kWebKitFontScaleFactor, 1.0);
520 registry->RegisterBooleanPref(prefs::kWebKitForceEnableZoom,
521 pref_defaults.force_enable_zoom);
522 registry->RegisterBooleanPref(prefs::kWebKitPasswordEchoEnabled,
523 pref_defaults.password_echo_enabled);
524 #endif
525 registry->RegisterStringPref(
526 prefs::kAcceptLanguages,
527 l10n_util::GetStringUTF8(IDS_ACCEPT_LANGUAGES),
528 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
529 registry->RegisterStringPref(
530 prefs::kDefaultCharset,
531 l10n_util::GetStringUTF8(IDS_DEFAULT_ENCODING),
532 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
534 // Register font prefs that have defaults.
535 std::set<std::string> fonts_with_defaults;
536 UScriptCode browser_script = GetScriptOfBrowserLocale();
537 for (size_t i = 0; i < kFontDefaultsLength; ++i) {
538 FontDefault pref = kFontDefaults[i];
540 #if defined(OS_WIN)
541 if (pref.pref_name == prefs::kWebKitFixedFontFamily) {
542 if (ShouldUseAlternateDefaultFixedFont(
543 l10n_util::GetStringUTF8(pref.resource_id)))
544 pref.resource_id = IDS_FIXED_FONT_FAMILY_ALT_WIN;
546 #endif
548 UScriptCode pref_script = GetScriptOfFontPref(pref.pref_name);
550 // Suppress this default font pref value if it is for the primary script of
551 // the browser's UI locale. For example, if the pref is for the sans-serif
552 // font for the Cyrillic script, and the browser locale is "ru" (Russian),
553 // the default is suppressed. Otherwise, the default would override the
554 // user's font preferences when viewing pages in their native language.
555 // This is because users have no way yet of customizing their per-script
556 // font preferences. The font prefs accessible in the options UI are for
557 // the default, unknown script; these prefs have less priority than the
558 // per-script font prefs when the script of the content is known. This code
559 // can possibly be removed later if users can easily access per-script font
560 // prefs (e.g., via the extensions workflow), or the problem turns out to
561 // not be really critical after all.
562 if (browser_script != pref_script) {
563 registry->RegisterStringPref(pref.pref_name,
564 l10n_util::GetStringUTF8(pref.resource_id));
565 fonts_with_defaults.insert(pref.pref_name);
569 // Register per-script font prefs that don't have defaults.
570 #if !defined(OS_ANDROID)
571 RegisterFontFamilyPrefs(registry, fonts_with_defaults);
572 #endif
574 RegisterLocalizedFontPref(registry, prefs::kWebKitDefaultFontSize,
575 IDS_DEFAULT_FONT_SIZE);
576 RegisterLocalizedFontPref(registry, prefs::kWebKitDefaultFixedFontSize,
577 IDS_DEFAULT_FIXED_FONT_SIZE);
578 RegisterLocalizedFontPref(registry, prefs::kWebKitMinimumFontSize,
579 IDS_MINIMUM_FONT_SIZE);
580 RegisterLocalizedFontPref(registry, prefs::kWebKitMinimumLogicalFontSize,
581 IDS_MINIMUM_LOGICAL_FONT_SIZE);
582 registry->RegisterBooleanPref(
583 prefs::kWebKitUsesUniversalDetector,
584 l10n_util::GetStringUTF8(IDS_USES_UNIVERSAL_DETECTOR) == "true",
585 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
586 registry->RegisterStringPref(
587 prefs::kStaticEncodings,
588 l10n_util::GetStringUTF8(IDS_STATIC_ENCODING_LIST));
589 registry->RegisterStringPref(prefs::kRecentlySelectedEncoding, std::string());
592 // static
593 void PrefsTabHelper::GetServiceInstance() {
594 PrefWatcherFactory::GetInstance();
597 void PrefsTabHelper::Observe(int type,
598 const content::NotificationSource& source,
599 const content::NotificationDetails& details) {
600 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES)
601 if (type == chrome::NOTIFICATION_BROWSER_THEME_CHANGED) {
602 UpdateRendererPreferences();
603 return;
605 #endif
607 #if defined(USE_AURA)
608 if (type == chrome::NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED) {
609 UpdateRendererPreferences();
610 return;
612 #endif // defined(USE_AURA)
614 NOTREACHED();
617 void PrefsTabHelper::UpdateWebPreferences() {
618 web_contents_->GetRenderViewHost()->UpdateWebkitPreferences(
619 web_contents_->GetRenderViewHost()->GetWebkitPreferences());
622 void PrefsTabHelper::UpdateRendererPreferences() {
623 content::RendererPreferences* prefs =
624 web_contents_->GetMutableRendererPrefs();
625 renderer_preferences_util::UpdateFromSystemSettings(
626 prefs, profile_, web_contents_);
627 web_contents_->GetRenderViewHost()->SyncRendererPrefs();
629 void PrefsTabHelper::OnFontFamilyPrefChanged(const std::string& pref_name) {
630 // When a font family pref's value goes from non-empty to the empty string, we
631 // must add it to the usual WebPreferences struct passed to the renderer.
633 // The empty string means to fall back to the pref for the Common script
634 // ("Zyyy"). For example, if chrome.fonts.serif.Cyrl is the empty string, it
635 // means to use chrome.fonts.serif.Zyyy for Cyrillic script. Prefs that are
636 // the empty string are normally not passed to WebKit, since there are so many
637 // of them that it would cause a performance regression. Not passing the pref
638 // is normally okay since WebKit does the desired fallback behavior regardless
639 // of whether the empty string is passed or the pref is not passed at all. But
640 // if the pref has changed from non-empty to the empty string, we must let
641 // WebKit know.
642 std::string generic_family;
643 std::string script;
644 if (pref_names_util::ParseFontNamePrefPath(pref_name,
645 &generic_family,
646 &script)) {
647 PrefService* prefs = profile_->GetPrefs();
648 std::string pref_value = prefs->GetString(pref_name);
649 if (pref_value.empty()) {
650 WebPreferences web_prefs =
651 web_contents_->GetRenderViewHost()->GetWebkitPreferences();
652 OverrideFontFamily(&web_prefs, generic_family, script, std::string());
653 web_contents_->GetRenderViewHost()->UpdateWebkitPreferences(web_prefs);
654 return;
659 void PrefsTabHelper::OnWebPrefChanged(const std::string& pref_name) {
660 #if !defined(OS_ANDROID)
661 OnFontFamilyPrefChanged(pref_name);
662 #endif
664 web_contents_->GetRenderViewHost()->OnWebkitPreferencesChanged();