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"
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"
49 #include "base/win/windows_version.h"
52 using content::WebContents
;
53 using content::WebPreferences
;
55 DEFINE_WEB_CONTENTS_USER_DATA_KEY(PrefsTabHelper
);
59 // The list of prefs we want to observe.
60 const char* kPrefsToObserve
[] = {
61 #if defined(ENABLE_EXTENSIONS)
62 prefs::kAnimationPolicy
,
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
,
77 prefs::kWebKitJavascriptCanOpenWindowsAutomatically
,
78 prefs::kWebKitJavascriptEnabled
,
79 prefs::kWebKitJavaEnabled
,
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::StartsWithASCII(map_name
, "webkit.webprefs.", true));
142 for (size_t i
= 0; i
< prefs::kWebKitScriptsForFontFamilyMapsLength
; ++i
) {
143 const char* script
= prefs::kWebKitScriptsForFontFamilyMaps
[i
];
144 registrar
->Add(base::StringPrintf("%s.%s", map_name
, script
), obs
);
149 // On Windows with antialising we want to use an alternate fixed font like
150 // Consolas, which looks much better than Courier New.
151 bool ShouldUseAlternateDefaultFixedFont(const std::string
& script
) {
152 if (!base::StartsWithASCII(script
, "courier", false))
154 UINT smooth_type
= 0;
155 SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE
, 0, &smooth_type
, 0);
156 return (base::win::GetVersion() >= base::win::VERSION_WIN7
) &&
157 (smooth_type
== FE_FONTSMOOTHINGCLEARTYPE
);
162 const char* pref_name
;
166 // Font pref defaults. The prefs that have defaults vary by platform, since not
167 // all platforms have fonts for all scripts for all generic families.
168 // TODO(falken): add proper defaults when possible for all
169 // platforms/scripts/generic families.
170 const FontDefault kFontDefaults
[] = {
171 { prefs::kWebKitStandardFontFamily
, IDS_STANDARD_FONT_FAMILY
},
172 { prefs::kWebKitFixedFontFamily
, IDS_FIXED_FONT_FAMILY
},
173 { prefs::kWebKitSerifFontFamily
, IDS_SERIF_FONT_FAMILY
},
174 { prefs::kWebKitSansSerifFontFamily
, IDS_SANS_SERIF_FONT_FAMILY
},
175 { prefs::kWebKitCursiveFontFamily
, IDS_CURSIVE_FONT_FAMILY
},
176 { prefs::kWebKitFantasyFontFamily
, IDS_FANTASY_FONT_FAMILY
},
177 { prefs::kWebKitPictographFontFamily
, IDS_PICTOGRAPH_FONT_FAMILY
},
178 #if defined(OS_CHROMEOS) || defined(OS_MACOSX) || defined(OS_WIN)
179 { prefs::kWebKitStandardFontFamilyJapanese
,
180 IDS_STANDARD_FONT_FAMILY_JAPANESE
},
181 { prefs::kWebKitFixedFontFamilyJapanese
, IDS_FIXED_FONT_FAMILY_JAPANESE
},
182 { prefs::kWebKitSerifFontFamilyJapanese
, IDS_SERIF_FONT_FAMILY_JAPANESE
},
183 { prefs::kWebKitSansSerifFontFamilyJapanese
,
184 IDS_SANS_SERIF_FONT_FAMILY_JAPANESE
},
185 { prefs::kWebKitStandardFontFamilyKorean
, IDS_STANDARD_FONT_FAMILY_KOREAN
},
186 { prefs::kWebKitSerifFontFamilyKorean
, IDS_SERIF_FONT_FAMILY_KOREAN
},
187 { prefs::kWebKitSansSerifFontFamilyKorean
,
188 IDS_SANS_SERIF_FONT_FAMILY_KOREAN
},
189 { prefs::kWebKitStandardFontFamilySimplifiedHan
,
190 IDS_STANDARD_FONT_FAMILY_SIMPLIFIED_HAN
},
191 { prefs::kWebKitSerifFontFamilySimplifiedHan
,
192 IDS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN
},
193 { prefs::kWebKitSansSerifFontFamilySimplifiedHan
,
194 IDS_SANS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN
},
195 { prefs::kWebKitStandardFontFamilyTraditionalHan
,
196 IDS_STANDARD_FONT_FAMILY_TRADITIONAL_HAN
},
197 { prefs::kWebKitSerifFontFamilyTraditionalHan
,
198 IDS_SERIF_FONT_FAMILY_TRADITIONAL_HAN
},
199 { prefs::kWebKitSansSerifFontFamilyTraditionalHan
,
200 IDS_SANS_SERIF_FONT_FAMILY_TRADITIONAL_HAN
},
202 #if defined(OS_CHROMEOS)
203 { prefs::kWebKitStandardFontFamilyArabic
, IDS_STANDARD_FONT_FAMILY_ARABIC
},
204 { prefs::kWebKitSerifFontFamilyArabic
, IDS_SERIF_FONT_FAMILY_ARABIC
},
205 { prefs::kWebKitSansSerifFontFamilyArabic
,
206 IDS_SANS_SERIF_FONT_FAMILY_ARABIC
},
207 { prefs::kWebKitFixedFontFamilyKorean
, IDS_FIXED_FONT_FAMILY_KOREAN
},
208 { prefs::kWebKitFixedFontFamilySimplifiedHan
,
209 IDS_FIXED_FONT_FAMILY_SIMPLIFIED_HAN
},
210 { prefs::kWebKitFixedFontFamilyTraditionalHan
,
211 IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN
},
212 #elif defined(OS_WIN)
213 { prefs::kWebKitFixedFontFamilyArabic
, IDS_FIXED_FONT_FAMILY_ARABIC
},
214 { prefs::kWebKitSansSerifFontFamilyArabic
,
215 IDS_SANS_SERIF_FONT_FAMILY_ARABIC
},
216 { prefs::kWebKitStandardFontFamilyCyrillic
,
217 IDS_STANDARD_FONT_FAMILY_CYRILLIC
},
218 { prefs::kWebKitFixedFontFamilyCyrillic
, IDS_FIXED_FONT_FAMILY_CYRILLIC
},
219 { prefs::kWebKitSerifFontFamilyCyrillic
, IDS_SERIF_FONT_FAMILY_CYRILLIC
},
220 { prefs::kWebKitSansSerifFontFamilyCyrillic
,
221 IDS_SANS_SERIF_FONT_FAMILY_CYRILLIC
},
222 { prefs::kWebKitStandardFontFamilyGreek
, IDS_STANDARD_FONT_FAMILY_GREEK
},
223 { prefs::kWebKitFixedFontFamilyGreek
, IDS_FIXED_FONT_FAMILY_GREEK
},
224 { prefs::kWebKitSerifFontFamilyGreek
, IDS_SERIF_FONT_FAMILY_GREEK
},
225 { prefs::kWebKitSansSerifFontFamilyGreek
, IDS_SANS_SERIF_FONT_FAMILY_GREEK
},
226 { prefs::kWebKitFixedFontFamilyKorean
, IDS_FIXED_FONT_FAMILY_KOREAN
},
227 { prefs::kWebKitCursiveFontFamilyKorean
, IDS_CURSIVE_FONT_FAMILY_KOREAN
},
228 { prefs::kWebKitFixedFontFamilySimplifiedHan
,
229 IDS_FIXED_FONT_FAMILY_SIMPLIFIED_HAN
},
230 { prefs::kWebKitFixedFontFamilyTraditionalHan
,
231 IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN
},
235 const size_t kFontDefaultsLength
= arraysize(kFontDefaults
);
237 // Returns the script of the font pref |pref_name|. For example, suppose
238 // |pref_name| is "webkit.webprefs.fonts.serif.Hant". Since the script code for
239 // the script name "Hant" is USCRIPT_TRADITIONAL_HAN, the function returns
240 // USCRIPT_TRADITIONAL_HAN. |pref_name| must be a valid font pref name.
241 UScriptCode
GetScriptOfFontPref(const char* pref_name
) {
242 // ICU script names are four letters.
243 static const size_t kScriptNameLength
= 4;
245 size_t len
= strlen(pref_name
);
246 DCHECK_GT(len
, kScriptNameLength
);
247 const char* scriptName
= &pref_name
[len
- kScriptNameLength
];
248 int32 code
= u_getPropertyValueEnum(UCHAR_SCRIPT
, scriptName
);
249 DCHECK(code
>= 0 && code
< USCRIPT_CODE_LIMIT
);
250 return static_cast<UScriptCode
>(code
);
253 // If |scriptCode| is a member of a family of "similar" script codes, returns
254 // the script code in that family that is used in font pref names. For example,
255 // USCRIPT_HANGUL and USCRIPT_KOREAN are considered equivalent for the purposes
256 // of font selection. Chrome uses the script code USCRIPT_HANGUL (script name
257 // "Hang") in Korean font pref names (for example,
258 // "webkit.webprefs.fonts.serif.Hang"). So, if |scriptCode| is USCRIPT_KOREAN,
259 // the function returns USCRIPT_HANGUL. If |scriptCode| is not a member of such
260 // a family, returns |scriptCode|.
261 UScriptCode
GetScriptForFontPrefMatching(UScriptCode scriptCode
) {
262 switch (scriptCode
) {
263 case USCRIPT_HIRAGANA
:
264 case USCRIPT_KATAKANA
:
265 case USCRIPT_KATAKANA_OR_HIRAGANA
:
266 return USCRIPT_JAPANESE
;
268 return USCRIPT_HANGUL
;
274 // Returns the primary script used by the browser's UI locale. For example, if
275 // the locale is "ru", the function returns USCRIPT_CYRILLIC, and if the locale
276 // is "en", the function returns USCRIPT_LATIN.
277 UScriptCode
GetScriptOfBrowserLocale() {
278 std::string locale
= g_browser_process
->GetApplicationLocale();
280 // For Chinese locales, uscript_getCode() just returns USCRIPT_HAN but our
281 // per-script fonts are for USCRIPT_SIMPLIFIED_HAN and
282 // USCRIPT_TRADITIONAL_HAN.
283 if (locale
== "zh-CN")
284 return USCRIPT_SIMPLIFIED_HAN
;
285 if (locale
== "zh-TW")
286 return USCRIPT_TRADITIONAL_HAN
;
288 UScriptCode code
= USCRIPT_INVALID_CODE
;
289 UErrorCode err
= U_ZERO_ERROR
;
290 uscript_getCode(locale
.c_str(), &code
, 1, &err
);
292 // Ignore the error that multiple scripts could be returned, since we only
294 if (U_FAILURE(err
) && err
!= U_BUFFER_OVERFLOW_ERROR
)
295 code
= USCRIPT_INVALID_CODE
;
296 return GetScriptForFontPrefMatching(code
);
299 // Sets a font family pref in |prefs| to |pref_value|.
300 void OverrideFontFamily(WebPreferences
* prefs
,
301 const std::string
& generic_family
,
302 const std::string
& script
,
303 const std::string
& pref_value
) {
304 content::ScriptFontFamilyMap
* map
= NULL
;
305 if (generic_family
== "standard")
306 map
= &prefs
->standard_font_family_map
;
307 else if (generic_family
== "fixed")
308 map
= &prefs
->fixed_font_family_map
;
309 else if (generic_family
== "serif")
310 map
= &prefs
->serif_font_family_map
;
311 else if (generic_family
== "sansserif")
312 map
= &prefs
->sans_serif_font_family_map
;
313 else if (generic_family
== "cursive")
314 map
= &prefs
->cursive_font_family_map
;
315 else if (generic_family
== "fantasy")
316 map
= &prefs
->fantasy_font_family_map
;
317 else if (generic_family
== "pictograph")
318 map
= &prefs
->pictograph_font_family_map
;
320 NOTREACHED() << "Unknown generic font family: " << generic_family
;
321 (*map
)[script
] = base::UTF8ToUTF16(pref_value
);
324 void RegisterLocalizedFontPref(user_prefs::PrefRegistrySyncable
* registry
,
326 int default_message_id
) {
328 bool success
= base::StringToInt(l10n_util::GetStringUTF8(
329 default_message_id
), &val
);
331 registry
->RegisterIntegerPref(path
, val
);
336 // Watching all these settings per tab is slow when a user has a lot of tabs and
337 // and they use session restore. So watch them once per profile.
338 // http://crbug.com/452693
339 class PrefWatcher
: public KeyedService
{
341 explicit PrefWatcher(Profile
* profile
) : profile_(profile
) {
342 pref_change_registrar_
.Init(profile_
->GetPrefs());
344 base::Closure renderer_callback
= base::Bind(
345 &PrefWatcher::UpdateRendererPreferences
, base::Unretained(this));
346 pref_change_registrar_
.Add(prefs::kAcceptLanguages
, renderer_callback
);
347 pref_change_registrar_
.Add(prefs::kEnableDoNotTrack
, renderer_callback
);
348 pref_change_registrar_
.Add(prefs::kEnableReferrers
, renderer_callback
);
350 #if defined(ENABLE_WEBRTC)
351 pref_change_registrar_
.Add(prefs::kWebRTCMultipleRoutesEnabled
,
355 #if !defined(OS_MACOSX)
356 pref_change_registrar_
.Add(prefs::kFullscreenAllowed
, renderer_callback
);
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
,
369 RegisterFontFamilyMapObserver(&pref_change_registrar_
,
370 prefs::kWebKitFixedFontFamilyMap
,
372 RegisterFontFamilyMapObserver(&pref_change_registrar_
,
373 prefs::kWebKitSerifFontFamilyMap
,
375 RegisterFontFamilyMapObserver(&pref_change_registrar_
,
376 prefs::kWebKitSansSerifFontFamilyMap
,
378 RegisterFontFamilyMapObserver(&pref_change_registrar_
,
379 prefs::kWebKitCursiveFontFamilyMap
,
381 RegisterFontFamilyMapObserver(&pref_change_registrar_
,
382 prefs::kWebKitFantasyFontFamilyMap
,
384 RegisterFontFamilyMapObserver(&pref_change_registrar_
,
385 prefs::kWebKitPictographFontFamilyMap
,
389 static PrefWatcher
* Get(Profile
* profile
);
391 void RegisterHelper(PrefsTabHelper
* helper
) {
392 helpers_
.insert(helper
);
395 void UnregisterHelper(PrefsTabHelper
* helper
) {
396 helpers_
.erase(helper
);
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
);
416 PrefChangeRegistrar pref_change_registrar_
;
417 std::set
<PrefsTabHelper
*> helpers_
;
420 class PrefWatcherFactory
: public BrowserContextKeyedServiceFactory
{
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();
432 friend struct DefaultSingletonTraits
<PrefWatcherFactory
>;
434 PrefWatcherFactory() : BrowserContextKeyedServiceFactory(
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
);
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();
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
,
487 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES)
489 chrome::NOTIFICATION_BROWSER_THEME_CHANGED
,
490 content::Source
<ThemeService
>(
491 ThemeServiceFactory::GetForProfile(profile_
)));
493 #if defined(USE_AURA)
495 chrome::NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED
,
496 content::NotificationService::AllSources());
500 PrefsTabHelper::~PrefsTabHelper() {
501 PrefWatcher::Get(profile_
)->UnregisterHelper(this);
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)
518 void PrefsTabHelper::RegisterProfilePrefs(
519 user_prefs::PrefRegistrySyncable
* registry
) {
520 WebPreferences pref_defaults
;
521 registry
->RegisterBooleanPref(prefs::kWebKitJavascriptEnabled
,
522 pref_defaults
.javascript_enabled
);
523 registry
->RegisterBooleanPref(prefs::kWebKitWebSecurityEnabled
,
524 pref_defaults
.web_security_enabled
);
525 registry
->RegisterBooleanPref(
526 prefs::kWebKitJavascriptCanOpenWindowsAutomatically
, true);
527 registry
->RegisterBooleanPref(prefs::kWebKitLoadsImagesAutomatically
,
528 pref_defaults
.loads_images_automatically
);
529 registry
->RegisterBooleanPref(prefs::kWebKitPluginsEnabled
,
530 pref_defaults
.plugins_enabled
);
531 registry
->RegisterBooleanPref(prefs::kWebKitDomPasteEnabled
,
532 pref_defaults
.dom_paste_enabled
);
533 registry
->RegisterBooleanPref(prefs::kWebKitTextAreasAreResizable
,
534 pref_defaults
.text_areas_are_resizable
);
535 registry
->RegisterBooleanPref(prefs::kWebKitJavaEnabled
,
536 pref_defaults
.java_enabled
);
537 registry
->RegisterBooleanPref(prefs::kWebkitTabsToLinks
,
538 pref_defaults
.tabs_to_links
);
539 registry
->RegisterBooleanPref(prefs::kWebKitAllowRunningInsecureContent
,
541 registry
->RegisterBooleanPref(prefs::kWebKitAllowDisplayingInsecureContent
,
543 registry
->RegisterBooleanPref(prefs::kEnableReferrers
, true);
544 #if defined(OS_ANDROID)
545 registry
->RegisterDoublePref(prefs::kWebKitFontScaleFactor
, 1.0);
546 registry
->RegisterBooleanPref(prefs::kWebKitForceEnableZoom
,
547 pref_defaults
.force_enable_zoom
);
548 registry
->RegisterBooleanPref(prefs::kWebKitPasswordEchoEnabled
,
549 pref_defaults
.password_echo_enabled
);
551 registry
->RegisterStringPref(
552 prefs::kAcceptLanguages
,
553 l10n_util::GetStringUTF8(IDS_ACCEPT_LANGUAGES
),
554 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
555 registry
->RegisterStringPref(
556 prefs::kDefaultCharset
,
557 l10n_util::GetStringUTF8(IDS_DEFAULT_ENCODING
),
558 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
560 // Register font prefs that have defaults.
561 std::set
<std::string
> fonts_with_defaults
;
562 UScriptCode browser_script
= GetScriptOfBrowserLocale();
563 for (size_t i
= 0; i
< kFontDefaultsLength
; ++i
) {
564 FontDefault pref
= kFontDefaults
[i
];
567 if (pref
.pref_name
== prefs::kWebKitFixedFontFamily
) {
568 if (ShouldUseAlternateDefaultFixedFont(
569 l10n_util::GetStringUTF8(pref
.resource_id
)))
570 pref
.resource_id
= IDS_FIXED_FONT_FAMILY_ALT_WIN
;
574 UScriptCode pref_script
= GetScriptOfFontPref(pref
.pref_name
);
576 // Suppress this default font pref value if it is for the primary script of
577 // the browser's UI locale. For example, if the pref is for the sans-serif
578 // font for the Cyrillic script, and the browser locale is "ru" (Russian),
579 // the default is suppressed. Otherwise, the default would override the
580 // user's font preferences when viewing pages in their native language.
581 // This is because users have no way yet of customizing their per-script
582 // font preferences. The font prefs accessible in the options UI are for
583 // the default, unknown script; these prefs have less priority than the
584 // per-script font prefs when the script of the content is known. This code
585 // can possibly be removed later if users can easily access per-script font
586 // prefs (e.g., via the extensions workflow), or the problem turns out to
587 // not be really critical after all.
588 if (browser_script
!= pref_script
) {
589 registry
->RegisterStringPref(pref
.pref_name
,
590 l10n_util::GetStringUTF8(pref
.resource_id
));
591 fonts_with_defaults
.insert(pref
.pref_name
);
595 // Register per-script font prefs that don't have defaults.
596 #if !defined(OS_ANDROID)
597 RegisterFontFamilyPrefs(registry
, fonts_with_defaults
);
600 RegisterLocalizedFontPref(registry
, prefs::kWebKitDefaultFontSize
,
601 IDS_DEFAULT_FONT_SIZE
);
602 RegisterLocalizedFontPref(registry
, prefs::kWebKitDefaultFixedFontSize
,
603 IDS_DEFAULT_FIXED_FONT_SIZE
);
604 RegisterLocalizedFontPref(registry
, prefs::kWebKitMinimumFontSize
,
605 IDS_MINIMUM_FONT_SIZE
);
606 RegisterLocalizedFontPref(registry
, prefs::kWebKitMinimumLogicalFontSize
,
607 IDS_MINIMUM_LOGICAL_FONT_SIZE
);
608 registry
->RegisterBooleanPref(
609 prefs::kWebKitUsesUniversalDetector
,
610 l10n_util::GetStringUTF8(IDS_USES_UNIVERSAL_DETECTOR
) == "true",
611 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
612 registry
->RegisterStringPref(
613 prefs::kStaticEncodings
,
614 l10n_util::GetStringUTF8(IDS_STATIC_ENCODING_LIST
));
615 registry
->RegisterStringPref(prefs::kRecentlySelectedEncoding
, std::string());
619 void PrefsTabHelper::GetServiceInstance() {
620 PrefWatcherFactory::GetInstance();
623 void PrefsTabHelper::Observe(int type
,
624 const content::NotificationSource
& source
,
625 const content::NotificationDetails
& details
) {
626 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES)
627 if (type
== chrome::NOTIFICATION_BROWSER_THEME_CHANGED
) {
628 UpdateRendererPreferences();
633 #if defined(USE_AURA)
634 if (type
== chrome::NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED
) {
635 UpdateRendererPreferences();
638 #endif // defined(USE_AURA)
643 void PrefsTabHelper::UpdateWebPreferences() {
644 web_contents_
->GetRenderViewHost()->UpdateWebkitPreferences(
645 web_contents_
->GetRenderViewHost()->GetWebkitPreferences());
648 void PrefsTabHelper::UpdateRendererPreferences() {
649 content::RendererPreferences
* prefs
=
650 web_contents_
->GetMutableRendererPrefs();
651 renderer_preferences_util::UpdateFromSystemSettings(
652 prefs
, profile_
, web_contents_
);
653 web_contents_
->GetRenderViewHost()->SyncRendererPrefs();
655 void PrefsTabHelper::OnFontFamilyPrefChanged(const std::string
& pref_name
) {
656 // When a font family pref's value goes from non-empty to the empty string, we
657 // must add it to the usual WebPreferences struct passed to the renderer.
659 // The empty string means to fall back to the pref for the Common script
660 // ("Zyyy"). For example, if chrome.fonts.serif.Cyrl is the empty string, it
661 // means to use chrome.fonts.serif.Zyyy for Cyrillic script. Prefs that are
662 // the empty string are normally not passed to WebKit, since there are so many
663 // of them that it would cause a performance regression. Not passing the pref
664 // is normally okay since WebKit does the desired fallback behavior regardless
665 // of whether the empty string is passed or the pref is not passed at all. But
666 // if the pref has changed from non-empty to the empty string, we must let
668 std::string generic_family
;
670 if (pref_names_util::ParseFontNamePrefPath(pref_name
,
673 PrefService
* prefs
= profile_
->GetPrefs();
674 std::string pref_value
= prefs
->GetString(pref_name
);
675 if (pref_value
.empty()) {
676 WebPreferences web_prefs
=
677 web_contents_
->GetRenderViewHost()->GetWebkitPreferences();
678 OverrideFontFamily(&web_prefs
, generic_family
, script
, std::string());
679 web_contents_
->GetRenderViewHost()->UpdateWebkitPreferences(web_prefs
);
685 void PrefsTabHelper::OnWebPrefChanged(const std::string
& pref_name
) {
686 #if !defined(OS_ANDROID)
687 OnFontFamilyPrefChanged(pref_name
);
690 web_contents_
->GetRenderViewHost()->OnWebkitPreferencesChanged();