| // Copyright (c) 2010 The Chromium Embedded Framework Authors. All rights |
| // reserved. Use of this source code is governed by a BSD-style license that can |
| // be found in the LICENSE file. |
| |
| #include "libcef/browser/prefs/renderer_prefs.h" |
| |
| #include <string> |
| |
| #include "libcef/browser/browser_context.h" |
| #include "libcef/browser/context.h" |
| #include "libcef/browser/extensions/browser_extensions_util.h" |
| #include "libcef/common/cef_switches.h" |
| #include "libcef/common/extensions/extensions_util.h" |
| |
| #include "base/command_line.h" |
| #include "base/i18n/character_encoding.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/values.h" |
| #include "chrome/browser/accessibility/animation_policy_prefs.h" |
| #include "chrome/browser/defaults.h" |
| #include "chrome/browser/extensions/extension_webkit_preferences.h" |
| #include "chrome/browser/font_family_cache.h" |
| #include "chrome/browser/ui/prefs/prefs_tab_helper.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/pref_names.h" |
| #include "components/pref_registry/pref_registry_syncable.h" |
| #include "components/prefs/command_line_pref_store.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/prefs/pref_store.h" |
| #include "content/public/browser/render_process_host.h" |
| #include "content/public/browser/render_view_host.h" |
| #include "content/public/browser/site_instance.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/common/web_preferences.h" |
| #include "extensions/browser/extension_registry.h" |
| #include "extensions/browser/view_type_utils.h" |
| #include "extensions/common/constants.h" |
| #include "media/media_buildflags.h" |
| #include "third_party/blink/public/common/peerconnection/webrtc_ip_handling_policy.h" |
| |
| namespace renderer_prefs { |
| |
| namespace { |
| |
| // Set default values based on CEF command-line flags for preferences that are |
| // not available via the PrefService. Chromium command-line flags should not |
| // exist for these preferences. |
| void SetDefaultPrefs(content::WebPreferences& web) { |
| const base::CommandLine* command_line = |
| base::CommandLine::ForCurrentProcess(); |
| |
| web.javascript_enabled = |
| !command_line->HasSwitch(switches::kDisableJavascript); |
| web.allow_scripts_to_close_windows = |
| !command_line->HasSwitch(switches::kDisableJavascriptCloseWindows); |
| web.javascript_can_access_clipboard = |
| !command_line->HasSwitch(switches::kDisableJavascriptAccessClipboard); |
| web.allow_universal_access_from_file_urls = |
| command_line->HasSwitch(switches::kAllowUniversalAccessFromFileUrls); |
| web.shrinks_standalone_images_to_fit = |
| command_line->HasSwitch(switches::kImageShrinkStandaloneToFit); |
| web.text_areas_are_resizable = |
| !command_line->HasSwitch(switches::kDisableTextAreaResize); |
| } |
| |
| // Chrome preferences. |
| // Should match ChromeContentBrowserClient::OverrideWebkitPrefs. |
| void SetChromePrefs(CefBrowserContext* profile, content::WebPreferences& web) { |
| PrefService* prefs = profile->GetPrefs(); |
| |
| // Fill per-script font preferences. |
| FontFamilyCache::FillFontFamilyMap(profile, |
| prefs::kWebKitStandardFontFamilyMap, |
| &web.standard_font_family_map); |
| FontFamilyCache::FillFontFamilyMap(profile, prefs::kWebKitFixedFontFamilyMap, |
| &web.fixed_font_family_map); |
| FontFamilyCache::FillFontFamilyMap(profile, prefs::kWebKitSerifFontFamilyMap, |
| &web.serif_font_family_map); |
| FontFamilyCache::FillFontFamilyMap(profile, |
| prefs::kWebKitSansSerifFontFamilyMap, |
| &web.sans_serif_font_family_map); |
| FontFamilyCache::FillFontFamilyMap(profile, |
| prefs::kWebKitCursiveFontFamilyMap, |
| &web.cursive_font_family_map); |
| FontFamilyCache::FillFontFamilyMap(profile, |
| prefs::kWebKitFantasyFontFamilyMap, |
| &web.fantasy_font_family_map); |
| FontFamilyCache::FillFontFamilyMap(profile, |
| prefs::kWebKitPictographFontFamilyMap, |
| &web.pictograph_font_family_map); |
| |
| web.default_font_size = prefs->GetInteger(prefs::kWebKitDefaultFontSize); |
| web.default_fixed_font_size = |
| prefs->GetInteger(prefs::kWebKitDefaultFixedFontSize); |
| web.minimum_font_size = prefs->GetInteger(prefs::kWebKitMinimumFontSize); |
| web.minimum_logical_font_size = |
| prefs->GetInteger(prefs::kWebKitMinimumLogicalFontSize); |
| |
| web.default_encoding = prefs->GetString(prefs::kDefaultCharset); |
| |
| web.dom_paste_enabled = prefs->GetBoolean(prefs::kWebKitDomPasteEnabled); |
| web.tabs_to_links = prefs->GetBoolean(prefs::kWebkitTabsToLinks); |
| |
| if (!prefs->GetBoolean(prefs::kWebKitJavascriptEnabled)) |
| web.javascript_enabled = false; |
| if (!prefs->GetBoolean(prefs::kWebKitWebSecurityEnabled)) |
| web.web_security_enabled = false; |
| if (!prefs->GetBoolean(prefs::kWebKitPluginsEnabled)) |
| web.plugins_enabled = false; |
| web.loads_images_automatically = |
| prefs->GetBoolean(prefs::kWebKitLoadsImagesAutomatically); |
| |
| if (prefs->GetBoolean(prefs::kDisable3DAPIs)) { |
| web.webgl1_enabled = false; |
| web.webgl2_enabled = false; |
| } |
| |
| web.allow_running_insecure_content = |
| prefs->GetBoolean(prefs::kWebKitAllowRunningInsecureContent); |
| |
| web.password_echo_enabled = browser_defaults::kPasswordEchoEnabled; |
| |
| web.text_areas_are_resizable = |
| prefs->GetBoolean(prefs::kWebKitTextAreasAreResizable); |
| web.hyperlink_auditing_enabled = |
| prefs->GetBoolean(prefs::kEnableHyperlinkAuditing); |
| |
| if (extensions::ExtensionsEnabled()) { |
| std::string image_animation_policy = |
| prefs->GetString(prefs::kAnimationPolicy); |
| if (image_animation_policy == kAnimationPolicyOnce) |
| web.animation_policy = content::IMAGE_ANIMATION_POLICY_ANIMATION_ONCE; |
| else if (image_animation_policy == kAnimationPolicyNone) |
| web.animation_policy = content::IMAGE_ANIMATION_POLICY_NO_ANIMATION; |
| else |
| web.animation_policy = content::IMAGE_ANIMATION_POLICY_ALLOWED; |
| } |
| |
| // Make sure we will set the default_encoding with canonical encoding name. |
| web.default_encoding = |
| base::GetCanonicalEncodingNameByAliasName(web.default_encoding); |
| if (web.default_encoding.empty()) { |
| prefs->ClearPref(prefs::kDefaultCharset); |
| web.default_encoding = prefs->GetString(prefs::kDefaultCharset); |
| } |
| DCHECK(!web.default_encoding.empty()); |
| |
| if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kEnablePotentiallyAnnoyingSecurityFeatures)) { |
| web.disable_reading_from_canvas = true; |
| web.strict_mixed_content_checking = true; |
| web.strict_powerful_feature_restrictions = true; |
| } |
| } |
| |
| // Extension preferences. |
| // Should match ChromeContentBrowserClientExtensionsPart::OverrideWebkitPrefs. |
| void SetExtensionPrefs(content::RenderViewHost* rvh, |
| content::WebPreferences& web) { |
| if (!extensions::ExtensionsEnabled()) |
| return; |
| |
| const extensions::ExtensionRegistry* registry = |
| extensions::ExtensionRegistry::Get( |
| rvh->GetProcess()->GetBrowserContext()); |
| if (!registry) |
| return; |
| |
| // Note: it's not possible for kExtensionsScheme to change during the lifetime |
| // of the process. |
| // |
| // Ensure that we are only granting extension preferences to URLs with the |
| // correct scheme. Without this check, chrome-guest:// schemes used by webview |
| // tags as well as hosts that happen to match the id of an installed extension |
| // would get the wrong preferences. |
| const GURL& site_url = rvh->GetSiteInstance()->GetSiteURL(); |
| if (!site_url.SchemeIs(extensions::kExtensionScheme)) |
| return; |
| |
| content::WebContents* web_contents = |
| content::WebContents::FromRenderViewHost(rvh); |
| extensions::ViewType view_type = extensions::GetViewType(web_contents); |
| const extensions::Extension* extension = |
| registry->enabled_extensions().GetByID(site_url.host()); |
| extension_webkit_preferences::SetPreferences(extension, view_type, &web); |
| } |
| |
| // Helper macro for setting a WebPreferences variable based on the value of a |
| // CefBrowserSettings variable. |
| #define SET_STATE(cef_var, web_var) \ |
| if (cef_var == STATE_ENABLED) \ |
| web_var = true; \ |
| else if (cef_var == STATE_DISABLED) \ |
| web_var = false; |
| |
| // Set preferences based on CefBrowserSettings. |
| void SetCefPrefs(const CefBrowserSettings& cef, content::WebPreferences& web) { |
| if (cef.standard_font_family.length > 0) { |
| web.standard_font_family_map[content::kCommonScript] = |
| CefString(&cef.standard_font_family); |
| } |
| if (cef.fixed_font_family.length > 0) { |
| web.fixed_font_family_map[content::kCommonScript] = |
| CefString(&cef.fixed_font_family); |
| } |
| if (cef.serif_font_family.length > 0) { |
| web.serif_font_family_map[content::kCommonScript] = |
| CefString(&cef.serif_font_family); |
| } |
| if (cef.sans_serif_font_family.length > 0) { |
| web.sans_serif_font_family_map[content::kCommonScript] = |
| CefString(&cef.sans_serif_font_family); |
| } |
| if (cef.cursive_font_family.length > 0) { |
| web.cursive_font_family_map[content::kCommonScript] = |
| CefString(&cef.cursive_font_family); |
| } |
| if (cef.fantasy_font_family.length > 0) { |
| web.fantasy_font_family_map[content::kCommonScript] = |
| CefString(&cef.fantasy_font_family); |
| } |
| |
| if (cef.default_font_size > 0) |
| web.default_font_size = cef.default_font_size; |
| if (cef.default_fixed_font_size > 0) |
| web.default_fixed_font_size = cef.default_fixed_font_size; |
| if (cef.minimum_font_size > 0) |
| web.minimum_font_size = cef.minimum_font_size; |
| if (cef.minimum_logical_font_size > 0) |
| web.minimum_logical_font_size = cef.minimum_logical_font_size; |
| |
| if (cef.default_encoding.length > 0) |
| web.default_encoding = CefString(&cef.default_encoding); |
| |
| SET_STATE(cef.remote_fonts, web.remote_fonts_enabled); |
| SET_STATE(cef.javascript, web.javascript_enabled); |
| SET_STATE(cef.javascript_close_windows, web.allow_scripts_to_close_windows); |
| SET_STATE(cef.javascript_access_clipboard, |
| web.javascript_can_access_clipboard); |
| SET_STATE(cef.javascript_dom_paste, web.dom_paste_enabled); |
| SET_STATE(cef.plugins, web.plugins_enabled); |
| SET_STATE(cef.universal_access_from_file_urls, |
| web.allow_universal_access_from_file_urls); |
| SET_STATE(cef.file_access_from_file_urls, |
| web.allow_file_access_from_file_urls); |
| SET_STATE(cef.web_security, web.web_security_enabled); |
| SET_STATE(cef.image_loading, web.loads_images_automatically); |
| SET_STATE(cef.image_shrink_standalone_to_fit, |
| web.shrinks_standalone_images_to_fit); |
| SET_STATE(cef.text_area_resize, web.text_areas_are_resizable); |
| SET_STATE(cef.tab_to_links, web.tabs_to_links); |
| SET_STATE(cef.local_storage, web.local_storage_enabled); |
| SET_STATE(cef.databases, web.databases_enabled); |
| SET_STATE(cef.application_cache, web.application_cache_enabled); |
| |
| // Never explicitly enable GPU-related functions in this method because the |
| // GPU blacklist is not being checked here. |
| if (cef.webgl == STATE_DISABLED) { |
| web.webgl1_enabled = false; |
| web.webgl2_enabled = false; |
| } |
| } |
| |
| void SetString(CommandLinePrefStore* prefs, |
| const std::string& key, |
| const std::string& value) { |
| prefs->SetValue(key, base::WrapUnique(new base::Value(value)), |
| WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); |
| } |
| |
| void SetBool(CommandLinePrefStore* prefs, const std::string& key, bool value) { |
| prefs->SetValue(key, base::WrapUnique(new base::Value(value)), |
| WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); |
| } |
| |
| } // namespace |
| |
| void SetCommandLinePrefDefaults(CommandLinePrefStore* prefs) { |
| const base::CommandLine* command_line = |
| base::CommandLine::ForCurrentProcess(); |
| |
| if (command_line->HasSwitch(switches::kDefaultEncoding)) { |
| SetString(prefs, prefs::kDefaultCharset, |
| command_line->GetSwitchValueASCII(switches::kDefaultEncoding)); |
| } |
| |
| if (command_line->HasSwitch(switches::kDisableJavascriptDomPaste)) |
| SetBool(prefs, prefs::kWebKitDomPasteEnabled, false); |
| if (command_line->HasSwitch(switches::kDisableImageLoading)) |
| SetBool(prefs, prefs::kWebKitLoadsImagesAutomatically, false); |
| if (command_line->HasSwitch(switches::kDisableTabToLinks)) |
| SetBool(prefs, prefs::kWebkitTabsToLinks, false); |
| if (command_line->HasSwitch(switches::kDisablePlugins)) |
| SetBool(prefs, prefs::kWebKitPluginsEnabled, false); |
| } |
| |
| void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry, |
| const std::string& locale) { |
| PrefsTabHelper::RegisterProfilePrefs(registry, locale); |
| RegisterAnimationPolicyPrefs(registry); |
| |
| // From chrome::RegisterBrowserUserPrefs. |
| registry->RegisterBooleanPref( |
| prefs::kEnableDoNotTrack, false, |
| user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); |
| |
| // TODO(guoweis): Remove next 2 options at M50. |
| registry->RegisterBooleanPref(prefs::kWebRTCMultipleRoutesEnabled, true); |
| registry->RegisterBooleanPref(prefs::kWebRTCNonProxiedUdpEnabled, true); |
| registry->RegisterStringPref(prefs::kWebRTCIPHandlingPolicy, |
| blink::kWebRTCIPHandlingDefault); |
| registry->RegisterStringPref(prefs::kWebRTCUDPPortRange, std::string()); |
| |
| #if !defined(OS_MACOSX) |
| registry->RegisterBooleanPref(prefs::kFullscreenAllowed, true); |
| #endif |
| |
| // From ChromeContentBrowserClient::RegisterProfilePrefs. |
| registry->RegisterBooleanPref(prefs::kDisable3DAPIs, false); |
| registry->RegisterBooleanPref(prefs::kEnableHyperlinkAuditing, true); |
| |
| // From Profile::RegisterProfilePrefs. |
| registry->RegisterDictionaryPref(prefs::kPartitionDefaultZoomLevel); |
| registry->RegisterDictionaryPref(prefs::kPartitionPerHostZoomLevels); |
| } |
| |
| void PopulateWebPreferences(content::RenderViewHost* rvh, |
| content::WebPreferences& web) { |
| CefRefPtr<CefBrowserHostImpl> browser = |
| extensions::GetOwnerBrowserForHost(rvh, nullptr); |
| |
| // Set defaults for preferences that are not handled by PrefService. |
| SetDefaultPrefs(web); |
| |
| // Set preferences based on the context's PrefService. |
| if (browser) { |
| CefBrowserContext* profile = static_cast<CefBrowserContext*>( |
| browser->web_contents()->GetBrowserContext()); |
| SetChromePrefs(profile, web); |
| } |
| |
| // Set preferences based on the extension. |
| SetExtensionPrefs(rvh, web); |
| |
| if (browser) { |
| // Set preferences based on CefBrowserSettings. |
| SetCefPrefs(browser->settings(), web); |
| |
| web.picture_in_picture_enabled = browser->IsPictureInPictureSupported(); |
| |
| // Set the background color for the WebView. |
| web.base_background_color = browser->GetBackgroundColor(); |
| } else { |
| // We don't know for sure that the browser will be windowless but assume |
| // that the global windowless state is likely to be accurate. |
| web.base_background_color = |
| CefContext::Get()->GetBackgroundColor(nullptr, STATE_DEFAULT); |
| } |
| } |
| |
| } // namespace renderer_prefs |