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