ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / ui / prefs / prefs_tab_helper.cc
blobb1c23df4a8bd482a36eb1ed74f70b1e4c567ab19
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 "content/public/browser/notification_details.h"
33 #include "content/public/browser/notification_service.h"
34 #include "content/public/browser/render_view_host.h"
35 #include "content/public/browser/web_contents.h"
36 #include "content/public/common/renderer_preferences.h"
37 #include "content/public/common/web_preferences.h"
38 #include "grit/platform_locale_settings.h"
39 #include "third_party/icu/source/common/unicode/uchar.h"
40 #include "third_party/icu/source/common/unicode/uscript.h"
41 #include "ui/base/l10n/l10n_util.h"
43 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES)
44 #include "chrome/browser/themes/theme_service.h"
45 #include "chrome/browser/themes/theme_service_factory.h"
46 #endif
48 #if defined(OS_WIN)
49 #include "base/win/windows_version.h"
50 #endif
52 using content::WebContents;
53 using content::WebPreferences;
55 DEFINE_WEB_CONTENTS_USER_DATA_KEY(PrefsTabHelper);
57 namespace {
59 // The list of prefs we want to observe.
60 const char* kPrefsToObserve[] = {
61 #if defined(ENABLE_EXTENSIONS)
62 prefs::kAnimationPolicy,
63 #endif
64 prefs::kDefaultCharset,
65 prefs::kDisable3DAPIs,
66 prefs::kEnableHyperlinkAuditing,
67 prefs::kWebKitAllowDisplayingInsecureContent,
68 prefs::kWebKitAllowRunningInsecureContent,
69 prefs::kWebKitDefaultFixedFontSize,
70 prefs::kWebKitDefaultFontSize,
71 prefs::kWebKitDomPasteEnabled,
72 #if defined(OS_ANDROID)
73 prefs::kWebKitFontScaleFactor,
74 prefs::kWebKitForceEnableZoom,
75 prefs::kWebKitPasswordEchoEnabled,
76 #endif
77 prefs::kWebKitJavascriptCanOpenWindowsAutomatically,
78 prefs::kWebKitJavascriptEnabled,
79 prefs::kWebKitJavaEnabled,
80 prefs::kWebKitLoadsImagesAutomatically,
81 prefs::kWebKitMinimumFontSize,
82 prefs::kWebKitMinimumLogicalFontSize,
83 prefs::kWebKitPluginsEnabled,
84 prefs::kWebKitShrinksStandaloneImagesToFit,
85 prefs::kWebkitTabsToLinks,
86 prefs::kWebKitTextAreasAreResizable,
87 prefs::kWebKitUsesUniversalDetector,
88 prefs::kWebKitWebSecurityEnabled,
91 const int kPrefsToObserveLength = arraysize(kPrefsToObserve);
93 #if !defined(OS_ANDROID)
94 // Registers a preference under the path |pref_name| for each script used for
95 // per-script font prefs.
96 // For example, for WEBKIT_WEBPREFS_FONTS_SERIF ("fonts.serif"):
97 // "fonts.serif.Arab", "fonts.serif.Hang", etc. are registered.
98 // |fonts_with_defaults| contains all |pref_names| already registered since they
99 // have a specified default value.
100 // On Android there are no default values for these properties and there is no
101 // way to set them (because extensions are not supported so the Font Settings
102 // API cannot be used), so we can avoid registering them altogether.
103 void RegisterFontFamilyPrefs(user_prefs::PrefRegistrySyncable* registry,
104 const std::set<std::string>& fonts_with_defaults) {
105 // Expand the font concatenated with script name so this stays at RO memory
106 // rather than allocated in heap.
107 static const char* const kFontFamilyMap[] = {
108 #define EXPAND_SCRIPT_FONT(map_name, script_name) map_name "." script_name,
110 #include "chrome/common/pref_font_script_names-inl.h"
111 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_CURSIVE)
112 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_FANTASY)
113 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_FIXED)
114 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_PICTOGRAPH)
115 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_SANSERIF)
116 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_SERIF)
117 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_STANDARD)
119 #undef EXPAND_SCRIPT_FONT
122 for (size_t i = 0; i < arraysize(kFontFamilyMap); ++i) {
123 const char* pref_name = kFontFamilyMap[i];
124 if (fonts_with_defaults.find(pref_name) == fonts_with_defaults.end()) {
125 // We haven't already set a default value for this font preference, so set
126 // an empty string as the default.
127 registry->RegisterStringPref(
128 pref_name,
129 std::string(),
130 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
134 #endif // !defined(OS_ANDROID)
136 // Registers |obs| to observe per-script font prefs under the path |map_name|.
137 // On android, there's no exposed way to change these prefs, so we can save
138 // ~715KB of heap and some startup cycles by avoiding observing these prefs
139 // since they will never change.
140 void RegisterFontFamilyMapObserver(
141 PrefChangeRegistrar* registrar,
142 const char* map_name,
143 const PrefChangeRegistrar::NamedChangeCallback& obs) {
144 DCHECK(StartsWithASCII(map_name, "webkit.webprefs.", true));
146 for (size_t i = 0; i < prefs::kWebKitScriptsForFontFamilyMapsLength; ++i) {
147 const char* script = prefs::kWebKitScriptsForFontFamilyMaps[i];
148 registrar->Add(base::StringPrintf("%s.%s", map_name, script), obs);
152 #if defined(OS_WIN)
153 // On Windows with antialising we want to use an alternate fixed font like
154 // Consolas, which looks much better than Courier New.
155 bool ShouldUseAlternateDefaultFixedFont(const std::string& script) {
156 if (!StartsWithASCII(script, "courier", false))
157 return false;
158 UINT smooth_type = 0;
159 SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &smooth_type, 0);
160 return (base::win::GetVersion() >= base::win::VERSION_WIN7) &&
161 (smooth_type == FE_FONTSMOOTHINGCLEARTYPE);
163 #endif
165 struct FontDefault {
166 const char* pref_name;
167 int resource_id;
170 // Font pref defaults. The prefs that have defaults vary by platform, since not
171 // all platforms have fonts for all scripts for all generic families.
172 // TODO(falken): add proper defaults when possible for all
173 // platforms/scripts/generic families.
174 const FontDefault kFontDefaults[] = {
175 { prefs::kWebKitStandardFontFamily, IDS_STANDARD_FONT_FAMILY },
176 { prefs::kWebKitFixedFontFamily, IDS_FIXED_FONT_FAMILY },
177 { prefs::kWebKitSerifFontFamily, IDS_SERIF_FONT_FAMILY },
178 { prefs::kWebKitSansSerifFontFamily, IDS_SANS_SERIF_FONT_FAMILY },
179 { prefs::kWebKitCursiveFontFamily, IDS_CURSIVE_FONT_FAMILY },
180 { prefs::kWebKitFantasyFontFamily, IDS_FANTASY_FONT_FAMILY },
181 { prefs::kWebKitPictographFontFamily, IDS_PICTOGRAPH_FONT_FAMILY },
182 #if defined(OS_CHROMEOS) || defined(OS_MACOSX) || defined(OS_WIN)
183 { prefs::kWebKitStandardFontFamilyJapanese,
184 IDS_STANDARD_FONT_FAMILY_JAPANESE },
185 { prefs::kWebKitFixedFontFamilyJapanese, IDS_FIXED_FONT_FAMILY_JAPANESE },
186 { prefs::kWebKitSerifFontFamilyJapanese, IDS_SERIF_FONT_FAMILY_JAPANESE },
187 { prefs::kWebKitSansSerifFontFamilyJapanese,
188 IDS_SANS_SERIF_FONT_FAMILY_JAPANESE },
189 { prefs::kWebKitStandardFontFamilyKorean, IDS_STANDARD_FONT_FAMILY_KOREAN },
190 { prefs::kWebKitSerifFontFamilyKorean, IDS_SERIF_FONT_FAMILY_KOREAN },
191 { prefs::kWebKitSansSerifFontFamilyKorean,
192 IDS_SANS_SERIF_FONT_FAMILY_KOREAN },
193 { prefs::kWebKitStandardFontFamilySimplifiedHan,
194 IDS_STANDARD_FONT_FAMILY_SIMPLIFIED_HAN },
195 { prefs::kWebKitSerifFontFamilySimplifiedHan,
196 IDS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN },
197 { prefs::kWebKitSansSerifFontFamilySimplifiedHan,
198 IDS_SANS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN },
199 { prefs::kWebKitStandardFontFamilyTraditionalHan,
200 IDS_STANDARD_FONT_FAMILY_TRADITIONAL_HAN },
201 { prefs::kWebKitSerifFontFamilyTraditionalHan,
202 IDS_SERIF_FONT_FAMILY_TRADITIONAL_HAN },
203 { prefs::kWebKitSansSerifFontFamilyTraditionalHan,
204 IDS_SANS_SERIF_FONT_FAMILY_TRADITIONAL_HAN },
205 #endif
206 #if defined(OS_CHROMEOS)
207 { prefs::kWebKitStandardFontFamilyArabic, IDS_STANDARD_FONT_FAMILY_ARABIC },
208 { prefs::kWebKitSerifFontFamilyArabic, IDS_SERIF_FONT_FAMILY_ARABIC },
209 { prefs::kWebKitSansSerifFontFamilyArabic,
210 IDS_SANS_SERIF_FONT_FAMILY_ARABIC },
211 { prefs::kWebKitFixedFontFamilyKorean, IDS_FIXED_FONT_FAMILY_KOREAN },
212 { prefs::kWebKitFixedFontFamilySimplifiedHan,
213 IDS_FIXED_FONT_FAMILY_SIMPLIFIED_HAN },
214 { prefs::kWebKitFixedFontFamilyTraditionalHan,
215 IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN },
216 #elif defined(OS_WIN)
217 { prefs::kWebKitSansSerifFontFamilyArabic,
218 IDS_SANS_SERIF_FONT_FAMILY_ARABIC },
219 { prefs::kWebKitStandardFontFamilyCyrillic,
220 IDS_STANDARD_FONT_FAMILY_CYRILLIC },
221 { prefs::kWebKitFixedFontFamilyCyrillic, IDS_FIXED_FONT_FAMILY_CYRILLIC },
222 { prefs::kWebKitSerifFontFamilyCyrillic, IDS_SERIF_FONT_FAMILY_CYRILLIC },
223 { prefs::kWebKitSansSerifFontFamilyCyrillic,
224 IDS_SANS_SERIF_FONT_FAMILY_CYRILLIC },
225 { prefs::kWebKitStandardFontFamilyGreek, IDS_STANDARD_FONT_FAMILY_GREEK },
226 { prefs::kWebKitFixedFontFamilyGreek, IDS_FIXED_FONT_FAMILY_GREEK },
227 { prefs::kWebKitSerifFontFamilyGreek, IDS_SERIF_FONT_FAMILY_GREEK },
228 { prefs::kWebKitSansSerifFontFamilyGreek, IDS_SANS_SERIF_FONT_FAMILY_GREEK },
229 { prefs::kWebKitFixedFontFamilyKorean, IDS_FIXED_FONT_FAMILY_KOREAN },
230 { prefs::kWebKitCursiveFontFamilyKorean, IDS_CURSIVE_FONT_FAMILY_KOREAN },
231 { prefs::kWebKitFixedFontFamilySimplifiedHan,
232 IDS_FIXED_FONT_FAMILY_SIMPLIFIED_HAN },
233 { prefs::kWebKitFixedFontFamilyTraditionalHan,
234 IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN },
235 #endif
238 const size_t kFontDefaultsLength = arraysize(kFontDefaults);
240 // Returns the script of the font pref |pref_name|. For example, suppose
241 // |pref_name| is "webkit.webprefs.fonts.serif.Hant". Since the script code for
242 // the script name "Hant" is USCRIPT_TRADITIONAL_HAN, the function returns
243 // USCRIPT_TRADITIONAL_HAN. |pref_name| must be a valid font pref name.
244 UScriptCode GetScriptOfFontPref(const char* pref_name) {
245 // ICU script names are four letters.
246 static const size_t kScriptNameLength = 4;
248 size_t len = strlen(pref_name);
249 DCHECK_GT(len, kScriptNameLength);
250 const char* scriptName = &pref_name[len - kScriptNameLength];
251 int32 code = u_getPropertyValueEnum(UCHAR_SCRIPT, scriptName);
252 DCHECK(code >= 0 && code < USCRIPT_CODE_LIMIT);
253 return static_cast<UScriptCode>(code);
256 // If |scriptCode| is a member of a family of "similar" script codes, returns
257 // the script code in that family that is used in font pref names. For example,
258 // USCRIPT_HANGUL and USCRIPT_KOREAN are considered equivalent for the purposes
259 // of font selection. Chrome uses the script code USCRIPT_HANGUL (script name
260 // "Hang") in Korean font pref names (for example,
261 // "webkit.webprefs.fonts.serif.Hang"). So, if |scriptCode| is USCRIPT_KOREAN,
262 // the function returns USCRIPT_HANGUL. If |scriptCode| is not a member of such
263 // a family, returns |scriptCode|.
264 UScriptCode GetScriptForFontPrefMatching(UScriptCode scriptCode) {
265 switch (scriptCode) {
266 case USCRIPT_HIRAGANA:
267 case USCRIPT_KATAKANA:
268 case USCRIPT_KATAKANA_OR_HIRAGANA:
269 return USCRIPT_JAPANESE;
270 case USCRIPT_KOREAN:
271 return USCRIPT_HANGUL;
272 default:
273 return scriptCode;
277 // Returns the primary script used by the browser's UI locale. For example, if
278 // the locale is "ru", the function returns USCRIPT_CYRILLIC, and if the locale
279 // is "en", the function returns USCRIPT_LATIN.
280 UScriptCode GetScriptOfBrowserLocale() {
281 std::string locale = g_browser_process->GetApplicationLocale();
283 // For Chinese locales, uscript_getCode() just returns USCRIPT_HAN but our
284 // per-script fonts are for USCRIPT_SIMPLIFIED_HAN and
285 // USCRIPT_TRADITIONAL_HAN.
286 if (locale == "zh-CN")
287 return USCRIPT_SIMPLIFIED_HAN;
288 if (locale == "zh-TW")
289 return USCRIPT_TRADITIONAL_HAN;
291 UScriptCode code = USCRIPT_INVALID_CODE;
292 UErrorCode err = U_ZERO_ERROR;
293 uscript_getCode(locale.c_str(), &code, 1, &err);
295 // Ignore the error that multiple scripts could be returned, since we only
296 // want one script.
297 if (U_FAILURE(err) && err != U_BUFFER_OVERFLOW_ERROR)
298 code = USCRIPT_INVALID_CODE;
299 return GetScriptForFontPrefMatching(code);
302 // Sets a font family pref in |prefs| to |pref_value|.
303 void OverrideFontFamily(WebPreferences* prefs,
304 const std::string& generic_family,
305 const std::string& script,
306 const std::string& pref_value) {
307 content::ScriptFontFamilyMap* map = NULL;
308 if (generic_family == "standard")
309 map = &prefs->standard_font_family_map;
310 else if (generic_family == "fixed")
311 map = &prefs->fixed_font_family_map;
312 else if (generic_family == "serif")
313 map = &prefs->serif_font_family_map;
314 else if (generic_family == "sansserif")
315 map = &prefs->sans_serif_font_family_map;
316 else if (generic_family == "cursive")
317 map = &prefs->cursive_font_family_map;
318 else if (generic_family == "fantasy")
319 map = &prefs->fantasy_font_family_map;
320 else if (generic_family == "pictograph")
321 map = &prefs->pictograph_font_family_map;
322 else
323 NOTREACHED() << "Unknown generic font family: " << generic_family;
324 (*map)[script] = base::UTF8ToUTF16(pref_value);
327 void RegisterLocalizedFontPref(
328 user_prefs::PrefRegistrySyncable* registry,
329 const char* path,
330 int default_message_id,
331 user_prefs::PrefRegistrySyncable::PrefSyncStatus status) {
332 int val = 0;
333 bool success = base::StringToInt(l10n_util::GetStringUTF8(
334 default_message_id), &val);
335 DCHECK(success);
336 registry->RegisterIntegerPref(path, val, status);
339 } // namespace
341 // Watching all these settings per tab is slow when a user has a lot of tabs and
342 // and they use session restore. So watch them once per profile.
343 // http://crbug.com/452693
344 class PrefWatcher : public KeyedService {
345 public:
346 explicit PrefWatcher(Profile* profile) : profile_(profile) {
347 pref_change_registrar_.Init(profile_->GetPrefs());
349 base::Closure renderer_callback = base::Bind(
350 &PrefWatcher::UpdateRendererPreferences, base::Unretained(this));
351 pref_change_registrar_.Add(prefs::kAcceptLanguages, renderer_callback);
352 pref_change_registrar_.Add(prefs::kEnableDoNotTrack, renderer_callback);
353 pref_change_registrar_.Add(prefs::kEnableReferrers, renderer_callback);
355 #if !defined(OS_MACOSX)
356 pref_change_registrar_.Add(prefs::kFullscreenAllowed, renderer_callback);
357 #endif
359 PrefChangeRegistrar::NamedChangeCallback webkit_callback = base::Bind(
360 &PrefWatcher::OnWebPrefChanged, base::Unretained(this));
361 for (int i = 0; i < kPrefsToObserveLength; ++i) {
362 const char* pref_name = kPrefsToObserve[i];
363 pref_change_registrar_.Add(pref_name, webkit_callback);
366 RegisterFontFamilyMapObserver(&pref_change_registrar_,
367 prefs::kWebKitStandardFontFamilyMap,
368 webkit_callback);
369 RegisterFontFamilyMapObserver(&pref_change_registrar_,
370 prefs::kWebKitFixedFontFamilyMap,
371 webkit_callback);
372 RegisterFontFamilyMapObserver(&pref_change_registrar_,
373 prefs::kWebKitSerifFontFamilyMap,
374 webkit_callback);
375 RegisterFontFamilyMapObserver(&pref_change_registrar_,
376 prefs::kWebKitSansSerifFontFamilyMap,
377 webkit_callback);
378 RegisterFontFamilyMapObserver(&pref_change_registrar_,
379 prefs::kWebKitCursiveFontFamilyMap,
380 webkit_callback);
381 RegisterFontFamilyMapObserver(&pref_change_registrar_,
382 prefs::kWebKitFantasyFontFamilyMap,
383 webkit_callback);
384 RegisterFontFamilyMapObserver(&pref_change_registrar_,
385 prefs::kWebKitPictographFontFamilyMap,
386 webkit_callback);
389 static PrefWatcher* Get(Profile* profile);
391 void RegisterHelper(PrefsTabHelper* helper) {
392 helpers_.insert(helper);
395 void UnregisterHelper(PrefsTabHelper* helper) {
396 helpers_.erase(helper);
399 private:
400 // KeyedService overrides:
401 void Shutdown() override {
402 pref_change_registrar_.RemoveAll();
405 void UpdateRendererPreferences() {
406 for (const auto& helper : helpers_)
407 helper->UpdateRendererPreferences();
410 void OnWebPrefChanged(const std::string& pref_name) {
411 for (const auto& helper : helpers_)
412 helper->OnWebPrefChanged(pref_name);
415 Profile* profile_;
416 PrefChangeRegistrar pref_change_registrar_;
417 std::set<PrefsTabHelper*> helpers_;
420 class PrefWatcherFactory : public BrowserContextKeyedServiceFactory {
421 public:
422 static PrefWatcher* GetForProfile(Profile* profile) {
423 return static_cast<PrefWatcher*>(
424 GetInstance()->GetServiceForBrowserContext(profile, true));
427 static PrefWatcherFactory* GetInstance() {
428 return Singleton<PrefWatcherFactory>::get();
431 private:
432 friend struct DefaultSingletonTraits<PrefWatcherFactory>;
434 PrefWatcherFactory() : BrowserContextKeyedServiceFactory(
435 "PrefWatcher",
436 BrowserContextDependencyManager::GetInstance()) {
439 ~PrefWatcherFactory() override {}
441 // BrowserContextKeyedServiceFactory:
442 KeyedService* BuildServiceInstanceFor(
443 content::BrowserContext* browser_context) const override {
444 return new PrefWatcher(Profile::FromBrowserContext(browser_context));
447 content::BrowserContext* GetBrowserContextToUse(
448 content::BrowserContext* context) const override {
449 return chrome::GetBrowserContextOwnInstanceInIncognito(context);
453 // static
454 PrefWatcher* PrefWatcher::Get(Profile* profile) {
455 return PrefWatcherFactory::GetForProfile(profile);
458 PrefsTabHelper::PrefsTabHelper(WebContents* contents)
459 : web_contents_(contents),
460 profile_(Profile::FromBrowserContext(web_contents_->GetBrowserContext())),
461 weak_ptr_factory_(this) {
462 PrefService* prefs = profile_->GetPrefs();
463 if (prefs) {
464 // If the tab is in an incognito profile, we track changes in the default
465 // zoom level of the parent profile instead.
466 Profile* profile_to_track = profile_->GetOriginalProfile();
467 chrome::ChromeZoomLevelPrefs* zoom_level_prefs =
468 profile_to_track->GetZoomLevelPrefs();
470 base::Closure renderer_callback = base::Bind(
471 &PrefsTabHelper::UpdateRendererPreferences, base::Unretained(this));
472 // Tests should not need to create a ZoomLevelPrefs.
473 if (zoom_level_prefs) {
474 default_zoom_level_subscription_ =
475 zoom_level_prefs->RegisterDefaultZoomLevelCallback(renderer_callback);
478 PrefWatcher::Get(profile_)->RegisterHelper(this);
481 content::RendererPreferences* render_prefs =
482 web_contents_->GetMutableRendererPrefs();
483 renderer_preferences_util::UpdateFromSystemSettings(render_prefs,
484 profile_,
485 web_contents_);
487 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES)
488 registrar_.Add(this,
489 chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
490 content::Source<ThemeService>(
491 ThemeServiceFactory::GetForProfile(profile_)));
492 #endif
493 #if defined(USE_AURA)
494 registrar_.Add(this,
495 chrome::NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED,
496 content::NotificationService::AllSources());
497 #endif
500 PrefsTabHelper::~PrefsTabHelper() {
501 PrefWatcher::Get(profile_)->UnregisterHelper(this);
504 // static
505 void PrefsTabHelper::InitIncognitoUserPrefStore(
506 OverlayUserPrefStore* pref_store) {
507 // List of keys that cannot be changed in the user prefs file by the incognito
508 // profile. All preferences that store information about the browsing history
509 // or behavior of the user should have this property.
510 pref_store->RegisterOverlayPref(prefs::kBrowserWindowPlacement);
511 pref_store->RegisterOverlayPref(prefs::kSaveFileDefaultDirectory);
512 #if defined(OS_ANDROID) || defined(OS_IOS)
513 pref_store->RegisterOverlayPref(prefs::kProxy);
514 #endif // defined(OS_ANDROID) || defined(OS_IOS)
517 // static
518 void PrefsTabHelper::RegisterProfilePrefs(
519 user_prefs::PrefRegistrySyncable* registry) {
520 WebPreferences pref_defaults;
521 registry->RegisterBooleanPref(
522 prefs::kWebKitJavascriptEnabled,
523 pref_defaults.javascript_enabled,
524 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
525 registry->RegisterBooleanPref(
526 prefs::kWebKitWebSecurityEnabled,
527 pref_defaults.web_security_enabled,
528 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
529 registry->RegisterBooleanPref(
530 prefs::kWebKitJavascriptCanOpenWindowsAutomatically,
531 true,
532 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
533 registry->RegisterBooleanPref(
534 prefs::kWebKitLoadsImagesAutomatically,
535 pref_defaults.loads_images_automatically,
536 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
537 registry->RegisterBooleanPref(
538 prefs::kWebKitPluginsEnabled,
539 pref_defaults.plugins_enabled,
540 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
541 registry->RegisterBooleanPref(
542 prefs::kWebKitDomPasteEnabled,
543 pref_defaults.dom_paste_enabled,
544 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
545 registry->RegisterBooleanPref(
546 prefs::kWebKitShrinksStandaloneImagesToFit,
547 pref_defaults.shrinks_standalone_images_to_fit,
548 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
549 registry->RegisterBooleanPref(
550 prefs::kWebKitTextAreasAreResizable,
551 pref_defaults.text_areas_are_resizable,
552 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
553 registry->RegisterBooleanPref(
554 prefs::kWebKitJavaEnabled,
555 pref_defaults.java_enabled,
556 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
557 registry->RegisterBooleanPref(
558 prefs::kWebkitTabsToLinks,
559 pref_defaults.tabs_to_links,
560 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
561 registry->RegisterBooleanPref(
562 prefs::kWebKitAllowRunningInsecureContent,
563 false,
564 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
565 registry->RegisterBooleanPref(
566 prefs::kWebKitAllowDisplayingInsecureContent,
567 true,
568 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
569 registry->RegisterBooleanPref(
570 prefs::kEnableReferrers,
571 true,
572 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
573 #if defined(OS_ANDROID)
574 registry->RegisterDoublePref(
575 prefs::kWebKitFontScaleFactor,
576 1.0,
577 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
578 registry->RegisterBooleanPref(
579 prefs::kWebKitForceEnableZoom,
580 pref_defaults.force_enable_zoom,
581 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
582 registry->RegisterBooleanPref(
583 prefs::kWebKitPasswordEchoEnabled,
584 pref_defaults.password_echo_enabled,
585 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
586 #endif
587 registry->RegisterStringPref(
588 prefs::kAcceptLanguages,
589 l10n_util::GetStringUTF8(IDS_ACCEPT_LANGUAGES),
590 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
591 registry->RegisterStringPref(
592 prefs::kDefaultCharset,
593 l10n_util::GetStringUTF8(IDS_DEFAULT_ENCODING),
594 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
596 // Register font prefs that have defaults.
597 std::set<std::string> fonts_with_defaults;
598 UScriptCode browser_script = GetScriptOfBrowserLocale();
599 for (size_t i = 0; i < kFontDefaultsLength; ++i) {
600 FontDefault pref = kFontDefaults[i];
602 #if defined(OS_WIN)
603 if (pref.pref_name == prefs::kWebKitFixedFontFamily) {
604 if (ShouldUseAlternateDefaultFixedFont(
605 l10n_util::GetStringUTF8(pref.resource_id)))
606 pref.resource_id = IDS_FIXED_FONT_FAMILY_ALT_WIN;
608 #endif
610 UScriptCode pref_script = GetScriptOfFontPref(pref.pref_name);
612 // Suppress this default font pref value if it is for the primary script of
613 // the browser's UI locale. For example, if the pref is for the sans-serif
614 // font for the Cyrillic script, and the browser locale is "ru" (Russian),
615 // the default is suppressed. Otherwise, the default would override the
616 // user's font preferences when viewing pages in their native language.
617 // This is because users have no way yet of customizing their per-script
618 // font preferences. The font prefs accessible in the options UI are for
619 // the default, unknown script; these prefs have less priority than the
620 // per-script font prefs when the script of the content is known. This code
621 // can possibly be removed later if users can easily access per-script font
622 // prefs (e.g., via the extensions workflow), or the problem turns out to
623 // not be really critical after all.
624 if (browser_script != pref_script) {
625 registry->RegisterStringPref(
626 pref.pref_name,
627 l10n_util::GetStringUTF8(pref.resource_id),
628 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
629 fonts_with_defaults.insert(pref.pref_name);
633 // Register per-script font prefs that don't have defaults.
634 #if !defined(OS_ANDROID)
635 RegisterFontFamilyPrefs(registry, fonts_with_defaults);
636 #endif
638 RegisterLocalizedFontPref(
639 registry,
640 prefs::kWebKitDefaultFontSize,
641 IDS_DEFAULT_FONT_SIZE,
642 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
643 RegisterLocalizedFontPref(
644 registry,
645 prefs::kWebKitDefaultFixedFontSize,
646 IDS_DEFAULT_FIXED_FONT_SIZE,
647 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
648 RegisterLocalizedFontPref(
649 registry,
650 prefs::kWebKitMinimumFontSize,
651 IDS_MINIMUM_FONT_SIZE,
652 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
653 RegisterLocalizedFontPref(
654 registry,
655 prefs::kWebKitMinimumLogicalFontSize,
656 IDS_MINIMUM_LOGICAL_FONT_SIZE,
657 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
658 registry->RegisterBooleanPref(
659 prefs::kWebKitUsesUniversalDetector,
660 l10n_util::GetStringUTF8(IDS_USES_UNIVERSAL_DETECTOR) == "true",
661 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
662 registry->RegisterStringPref(
663 prefs::kStaticEncodings,
664 l10n_util::GetStringUTF8(IDS_STATIC_ENCODING_LIST),
665 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
666 registry->RegisterStringPref(
667 prefs::kRecentlySelectedEncoding,
668 std::string(),
669 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
672 // static
673 void PrefsTabHelper::GetServiceInstance() {
674 PrefWatcherFactory::GetInstance();
677 void PrefsTabHelper::Observe(int type,
678 const content::NotificationSource& source,
679 const content::NotificationDetails& details) {
680 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES)
681 if (type == chrome::NOTIFICATION_BROWSER_THEME_CHANGED) {
682 UpdateRendererPreferences();
683 return;
685 #endif
687 #if defined(USE_AURA)
688 if (type == chrome::NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED) {
689 UpdateRendererPreferences();
690 return;
692 #endif // defined(USE_AURA)
694 NOTREACHED();
697 void PrefsTabHelper::UpdateWebPreferences() {
698 web_contents_->GetRenderViewHost()->UpdateWebkitPreferences(
699 web_contents_->GetRenderViewHost()->GetWebkitPreferences());
702 void PrefsTabHelper::UpdateRendererPreferences() {
703 content::RendererPreferences* prefs =
704 web_contents_->GetMutableRendererPrefs();
705 renderer_preferences_util::UpdateFromSystemSettings(
706 prefs, profile_, web_contents_);
707 web_contents_->GetRenderViewHost()->SyncRendererPrefs();
709 void PrefsTabHelper::OnFontFamilyPrefChanged(const std::string& pref_name) {
710 // When a font family pref's value goes from non-empty to the empty string, we
711 // must add it to the usual WebPreferences struct passed to the renderer.
713 // The empty string means to fall back to the pref for the Common script
714 // ("Zyyy"). For example, if chrome.fonts.serif.Cyrl is the empty string, it
715 // means to use chrome.fonts.serif.Zyyy for Cyrillic script. Prefs that are
716 // the empty string are normally not passed to WebKit, since there are so many
717 // of them that it would cause a performance regression. Not passing the pref
718 // is normally okay since WebKit does the desired fallback behavior regardless
719 // of whether the empty string is passed or the pref is not passed at all. But
720 // if the pref has changed from non-empty to the empty string, we must let
721 // WebKit know.
722 std::string generic_family;
723 std::string script;
724 if (pref_names_util::ParseFontNamePrefPath(pref_name,
725 &generic_family,
726 &script)) {
727 PrefService* prefs = profile_->GetPrefs();
728 std::string pref_value = prefs->GetString(pref_name);
729 if (pref_value.empty()) {
730 WebPreferences web_prefs =
731 web_contents_->GetRenderViewHost()->GetWebkitPreferences();
732 OverrideFontFamily(&web_prefs, generic_family, script, std::string());
733 web_contents_->GetRenderViewHost()->UpdateWebkitPreferences(web_prefs);
734 return;
739 void PrefsTabHelper::OnWebPrefChanged(const std::string& pref_name) {
740 #if !defined(OS_ANDROID)
741 OnFontFamilyPrefChanged(pref_name);
742 #endif
744 web_contents_->GetRenderViewHost()->OnWebkitPreferencesChanged();