• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2010 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that can
3 // be found in the LICENSE file.
4 
5 #include "libcef/browser/prefs/renderer_prefs.h"
6 
7 #include <string>
8 
9 #include "libcef/browser/alloy/alloy_browser_host_impl.h"
10 #include "libcef/browser/context.h"
11 #include "libcef/browser/extensions/browser_extensions_util.h"
12 #include "libcef/common/cef_switches.h"
13 #include "libcef/common/extensions/extensions_util.h"
14 #include "libcef/features/runtime_checks.h"
15 
16 #include "base/command_line.h"
17 #include "base/i18n/character_encoding.h"
18 #include "base/memory/ptr_util.h"
19 #include "base/values.h"
20 #include "chrome/browser/accessibility/animation_policy_prefs.h"
21 #include "chrome/browser/defaults.h"
22 #include "chrome/browser/extensions/extension_webkit_preferences.h"
23 #include "chrome/browser/font_family_cache.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/ui/prefs/prefs_tab_helper.h"
26 #include "chrome/common/chrome_features.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/pref_names.h"
29 #include "components/pref_registry/pref_registry_syncable.h"
30 #include "components/prefs/command_line_pref_store.h"
31 #include "components/prefs/pref_service.h"
32 #include "components/prefs/pref_store.h"
33 #include "content/public/browser/render_process_host.h"
34 #include "content/public/browser/render_view_host.h"
35 #include "content/public/browser/site_instance.h"
36 #include "content/public/browser/web_contents.h"
37 #include "content/public/common/url_constants.h"
38 #include "extensions/browser/extension_registry.h"
39 #include "extensions/browser/view_type_utils.h"
40 #include "extensions/common/constants.h"
41 #include "media/media_buildflags.h"
42 #include "third_party/blink/public/common/peerconnection/webrtc_ip_handling_policy.h"
43 #include "third_party/blink/public/common/web_preferences/web_preferences.h"
44 #include "ui/native_theme/native_theme.h"
45 
46 namespace renderer_prefs {
47 
48 namespace {
49 
50 // Chrome preferences.
51 // Should match ChromeContentBrowserClient::OverrideWebkitPrefs.
SetChromePrefs(Profile * profile,blink::web_pref::WebPreferences & web)52 void SetChromePrefs(Profile* profile, blink::web_pref::WebPreferences& web) {
53   PrefService* prefs = profile->GetPrefs();
54 
55   // Fill per-script font preferences.
56   FontFamilyCache::FillFontFamilyMap(profile,
57                                      prefs::kWebKitStandardFontFamilyMap,
58                                      &web.standard_font_family_map);
59   FontFamilyCache::FillFontFamilyMap(profile, prefs::kWebKitFixedFontFamilyMap,
60                                      &web.fixed_font_family_map);
61   FontFamilyCache::FillFontFamilyMap(profile, prefs::kWebKitSerifFontFamilyMap,
62                                      &web.serif_font_family_map);
63   FontFamilyCache::FillFontFamilyMap(profile,
64                                      prefs::kWebKitSansSerifFontFamilyMap,
65                                      &web.sans_serif_font_family_map);
66   FontFamilyCache::FillFontFamilyMap(profile,
67                                      prefs::kWebKitCursiveFontFamilyMap,
68                                      &web.cursive_font_family_map);
69   FontFamilyCache::FillFontFamilyMap(profile,
70                                      prefs::kWebKitFantasyFontFamilyMap,
71                                      &web.fantasy_font_family_map);
72   FontFamilyCache::FillFontFamilyMap(profile,
73                                      prefs::kWebKitPictographFontFamilyMap,
74                                      &web.pictograph_font_family_map);
75 
76   web.default_font_size = prefs->GetInteger(prefs::kWebKitDefaultFontSize);
77   web.default_fixed_font_size =
78       prefs->GetInteger(prefs::kWebKitDefaultFixedFontSize);
79   web.minimum_font_size = prefs->GetInteger(prefs::kWebKitMinimumFontSize);
80   web.minimum_logical_font_size =
81       prefs->GetInteger(prefs::kWebKitMinimumLogicalFontSize);
82 
83   web.default_encoding = prefs->GetString(prefs::kDefaultCharset);
84 
85   web.dom_paste_enabled = prefs->GetBoolean(prefs::kWebKitDomPasteEnabled);
86   web.tabs_to_links = prefs->GetBoolean(prefs::kWebkitTabsToLinks);
87 
88   if (!prefs->GetBoolean(prefs::kWebKitJavascriptEnabled))
89     web.javascript_enabled = false;
90   if (!prefs->GetBoolean(prefs::kWebKitWebSecurityEnabled))
91     web.web_security_enabled = false;
92   if (!prefs->GetBoolean(prefs::kWebKitPluginsEnabled))
93     web.plugins_enabled = false;
94   web.loads_images_automatically =
95       prefs->GetBoolean(prefs::kWebKitLoadsImagesAutomatically);
96 
97   if (prefs->GetBoolean(prefs::kDisable3DAPIs)) {
98     web.webgl1_enabled = false;
99     web.webgl2_enabled = false;
100   }
101 
102   web.allow_running_insecure_content =
103       prefs->GetBoolean(prefs::kWebKitAllowRunningInsecureContent);
104 
105   web.password_echo_enabled = browser_defaults::kPasswordEchoEnabled;
106 
107   web.text_areas_are_resizable =
108       prefs->GetBoolean(prefs::kWebKitTextAreasAreResizable);
109   web.hyperlink_auditing_enabled =
110       prefs->GetBoolean(prefs::kEnableHyperlinkAuditing);
111 
112   if (extensions::ExtensionsEnabled()) {
113     std::string image_animation_policy =
114         prefs->GetString(prefs::kAnimationPolicy);
115     if (image_animation_policy == kAnimationPolicyOnce) {
116       web.animation_policy =
117           blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyAnimateOnce;
118     } else if (image_animation_policy == kAnimationPolicyNone) {
119       web.animation_policy =
120           blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyNoAnimation;
121     } else {
122       web.animation_policy =
123           blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyAllowed;
124     }
125   }
126 
127   // Make sure we will set the default_encoding with canonical encoding name.
128   web.default_encoding =
129       base::GetCanonicalEncodingNameByAliasName(web.default_encoding);
130   if (web.default_encoding.empty()) {
131     prefs->ClearPref(prefs::kDefaultCharset);
132     web.default_encoding = prefs->GetString(prefs::kDefaultCharset);
133   }
134   DCHECK(!web.default_encoding.empty());
135 
136   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
137           switches::kEnablePotentiallyAnnoyingSecurityFeatures)) {
138     web.disable_reading_from_canvas = true;
139     web.strict_mixed_content_checking = true;
140     web.strict_powerful_feature_restrictions = true;
141   }
142 }
143 
144 // Extension preferences.
145 // Should match ChromeContentBrowserClientExtensionsPart::OverrideWebkitPrefs.
SetExtensionPrefs(content::RenderViewHost * rvh,blink::web_pref::WebPreferences & web)146 void SetExtensionPrefs(content::RenderViewHost* rvh,
147                        blink::web_pref::WebPreferences& web) {
148   if (!extensions::ExtensionsEnabled())
149     return;
150 
151   const extensions::ExtensionRegistry* registry =
152       extensions::ExtensionRegistry::Get(
153           rvh->GetProcess()->GetBrowserContext());
154   if (!registry)
155     return;
156 
157   // Note: it's not possible for kExtensionsScheme to change during the lifetime
158   // of the process.
159   //
160   // Ensure that we are only granting extension preferences to URLs with the
161   // correct scheme. Without this check, chrome-guest:// schemes used by webview
162   // tags as well as hosts that happen to match the id of an installed extension
163   // would get the wrong preferences.
164   const GURL& site_url = rvh->GetMainFrame()->GetSiteInstance()->GetSiteURL();
165   if (!site_url.SchemeIs(extensions::kExtensionScheme))
166     return;
167 
168   const extensions::Extension* extension =
169       registry->enabled_extensions().GetByID(site_url.host());
170   extension_webkit_preferences::SetPreferences(extension, &web);
171 }
172 
SetString(CommandLinePrefStore * prefs,const std::string & key,const std::string & value)173 void SetString(CommandLinePrefStore* prefs,
174                const std::string& key,
175                const std::string& value) {
176   prefs->SetValue(key, base::WrapUnique(new base::Value(value)),
177                   WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
178 }
179 
SetBool(CommandLinePrefStore * prefs,const std::string & key,bool value)180 void SetBool(CommandLinePrefStore* prefs, const std::string& key, bool value) {
181   prefs->SetValue(key, base::WrapUnique(new base::Value(value)),
182                   WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
183 }
184 
ToBlinkPreferredColorScheme(ui::NativeTheme::PreferredColorScheme native_theme_scheme)185 blink::mojom::PreferredColorScheme ToBlinkPreferredColorScheme(
186     ui::NativeTheme::PreferredColorScheme native_theme_scheme) {
187   switch (native_theme_scheme) {
188     case ui::NativeTheme::PreferredColorScheme::kDark:
189       return blink::mojom::PreferredColorScheme::kDark;
190     case ui::NativeTheme::PreferredColorScheme::kLight:
191       return blink::mojom::PreferredColorScheme::kLight;
192   }
193 
194   NOTREACHED();
195 }
196 
197 // From chrome/browser/chrome_content_browser_client.cc
198 // Returns true if preferred color scheme is modified based on at least one of
199 // the following -
200 // |url| - Last committed url.
201 // |native_theme| - For other platforms based on native theme scheme.
UpdatePreferredColorScheme(blink::web_pref::WebPreferences * web_prefs,const GURL & url,const ui::NativeTheme * native_theme)202 bool UpdatePreferredColorScheme(blink::web_pref::WebPreferences* web_prefs,
203                                 const GURL& url,
204                                 const ui::NativeTheme* native_theme) {
205   auto old_preferred_color_scheme = web_prefs->preferred_color_scheme;
206 
207   // Update based on native theme scheme.
208   web_prefs->preferred_color_scheme =
209       ToBlinkPreferredColorScheme(native_theme->GetPreferredColorScheme());
210 
211   // Force a light preferred color scheme on certain URLs if kWebUIDarkMode is
212   // disabled; some of the UI is not yet correctly themed.
213   if (!base::FeatureList::IsEnabled(features::kWebUIDarkMode)) {
214     // Update based on last committed url.
215     bool force_light = url.SchemeIs(content::kChromeUIScheme);
216     if (!force_light) {
217       force_light = url.SchemeIs(extensions::kExtensionScheme) &&
218                     url.host_piece() == extension_misc::kPdfExtensionId;
219     }
220     if (force_light) {
221       web_prefs->preferred_color_scheme =
222           blink::mojom::PreferredColorScheme::kLight;
223     }
224   }
225 
226   return old_preferred_color_scheme != web_prefs->preferred_color_scheme;
227 }
228 
229 }  // namespace
230 
SetCommandLinePrefDefaults(CommandLinePrefStore * prefs)231 void SetCommandLinePrefDefaults(CommandLinePrefStore* prefs) {
232   const base::CommandLine* command_line =
233       base::CommandLine::ForCurrentProcess();
234 
235   if (command_line->HasSwitch(switches::kDefaultEncoding)) {
236     SetString(prefs, prefs::kDefaultCharset,
237               command_line->GetSwitchValueASCII(switches::kDefaultEncoding));
238   }
239 
240   if (command_line->HasSwitch(switches::kDisableJavascriptDomPaste))
241     SetBool(prefs, prefs::kWebKitDomPasteEnabled, false);
242   if (command_line->HasSwitch(switches::kDisableImageLoading))
243     SetBool(prefs, prefs::kWebKitLoadsImagesAutomatically, false);
244   if (command_line->HasSwitch(switches::kDisableTabToLinks))
245     SetBool(prefs, prefs::kWebkitTabsToLinks, false);
246   if (command_line->HasSwitch(switches::kDisablePlugins))
247     SetBool(prefs, prefs::kWebKitPluginsEnabled, false);
248 }
249 
SetDefaultPrefs(blink::web_pref::WebPreferences & web)250 void SetDefaultPrefs(blink::web_pref::WebPreferences& web) {
251   const base::CommandLine* command_line =
252       base::CommandLine::ForCurrentProcess();
253 
254   web.javascript_enabled =
255       !command_line->HasSwitch(switches::kDisableJavascript);
256   web.allow_scripts_to_close_windows =
257       !command_line->HasSwitch(switches::kDisableJavascriptCloseWindows);
258   web.javascript_can_access_clipboard =
259       !command_line->HasSwitch(switches::kDisableJavascriptAccessClipboard);
260   web.allow_universal_access_from_file_urls =
261       command_line->HasSwitch(switches::kAllowUniversalAccessFromFileUrls);
262   web.shrinks_standalone_images_to_fit =
263       command_line->HasSwitch(switches::kImageShrinkStandaloneToFit);
264   web.text_areas_are_resizable =
265       !command_line->HasSwitch(switches::kDisableTextAreaResize);
266 }
267 
268 // Helper macro for setting a WebPreferences variable based on the value of a
269 // CefBrowserSettings variable.
270 #define SET_STATE(cef_var, web_var)   \
271   if (cef_var == STATE_ENABLED)       \
272     web_var = true;                   \
273   else if (cef_var == STATE_DISABLED) \
274     web_var = false;
275 
SetCefPrefs(const CefBrowserSettings & cef,blink::web_pref::WebPreferences & web)276 void SetCefPrefs(const CefBrowserSettings& cef,
277                  blink::web_pref::WebPreferences& web) {
278   if (cef.standard_font_family.length > 0) {
279     web.standard_font_family_map[blink::web_pref::kCommonScript] =
280         CefString(&cef.standard_font_family);
281   }
282   if (cef.fixed_font_family.length > 0) {
283     web.fixed_font_family_map[blink::web_pref::kCommonScript] =
284         CefString(&cef.fixed_font_family);
285   }
286   if (cef.serif_font_family.length > 0) {
287     web.serif_font_family_map[blink::web_pref::kCommonScript] =
288         CefString(&cef.serif_font_family);
289   }
290   if (cef.sans_serif_font_family.length > 0) {
291     web.sans_serif_font_family_map[blink::web_pref::kCommonScript] =
292         CefString(&cef.sans_serif_font_family);
293   }
294   if (cef.cursive_font_family.length > 0) {
295     web.cursive_font_family_map[blink::web_pref::kCommonScript] =
296         CefString(&cef.cursive_font_family);
297   }
298   if (cef.fantasy_font_family.length > 0) {
299     web.fantasy_font_family_map[blink::web_pref::kCommonScript] =
300         CefString(&cef.fantasy_font_family);
301   }
302 
303   if (cef.default_font_size > 0)
304     web.default_font_size = cef.default_font_size;
305   if (cef.default_fixed_font_size > 0)
306     web.default_fixed_font_size = cef.default_fixed_font_size;
307   if (cef.minimum_font_size > 0)
308     web.minimum_font_size = cef.minimum_font_size;
309   if (cef.minimum_logical_font_size > 0)
310     web.minimum_logical_font_size = cef.minimum_logical_font_size;
311 
312   if (cef.default_encoding.length > 0)
313     web.default_encoding = CefString(&cef.default_encoding);
314 
315   SET_STATE(cef.remote_fonts, web.remote_fonts_enabled);
316   SET_STATE(cef.javascript, web.javascript_enabled);
317   SET_STATE(cef.javascript_close_windows, web.allow_scripts_to_close_windows);
318   SET_STATE(cef.javascript_access_clipboard,
319             web.javascript_can_access_clipboard);
320   SET_STATE(cef.javascript_dom_paste, web.dom_paste_enabled);
321   SET_STATE(cef.plugins, web.plugins_enabled);
322   SET_STATE(cef.universal_access_from_file_urls,
323             web.allow_universal_access_from_file_urls);
324   SET_STATE(cef.file_access_from_file_urls,
325             web.allow_file_access_from_file_urls);
326   SET_STATE(cef.image_loading, web.loads_images_automatically);
327   SET_STATE(cef.image_shrink_standalone_to_fit,
328             web.shrinks_standalone_images_to_fit);
329   SET_STATE(cef.text_area_resize, web.text_areas_are_resizable);
330   SET_STATE(cef.tab_to_links, web.tabs_to_links);
331   SET_STATE(cef.local_storage, web.local_storage_enabled);
332   SET_STATE(cef.databases, web.databases_enabled);
333   SET_STATE(cef.application_cache, web.application_cache_enabled);
334 
335   // Never explicitly enable GPU-related functions in this method because the
336   // GPU blacklist is not being checked here.
337   if (cef.webgl == STATE_DISABLED) {
338     web.webgl1_enabled = false;
339     web.webgl2_enabled = false;
340   }
341 }
342 
RegisterProfilePrefs(user_prefs::PrefRegistrySyncable * registry,const std::string & locale)343 void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry,
344                           const std::string& locale) {
345   PrefsTabHelper::RegisterProfilePrefs(registry, locale);
346   RegisterAnimationPolicyPrefs(registry);
347 
348   // From chrome/browser/ui/browser_ui_prefs.cc RegisterBrowserUserPrefs.
349   registry->RegisterBooleanPref(
350       prefs::kEnableDoNotTrack, false,
351       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
352   registry->RegisterBooleanPref(prefs::kCaretBrowsingEnabled, false);
353   registry->RegisterBooleanPref(prefs::kCloudPrintDeprecationWarningsSuppressed,
354                                 false);
355 
356   registry->RegisterStringPref(prefs::kWebRTCIPHandlingPolicy,
357                                blink::kWebRTCIPHandlingDefault);
358   registry->RegisterStringPref(prefs::kWebRTCUDPPortRange, std::string());
359 
360 #if !defined(OS_MAC)
361   registry->RegisterBooleanPref(prefs::kFullscreenAllowed, true);
362 #endif
363 
364   // From ChromeContentBrowserClient::RegisterProfilePrefs.
365   registry->RegisterBooleanPref(prefs::kDisable3DAPIs, false);
366   registry->RegisterBooleanPref(prefs::kEnableHyperlinkAuditing, true);
367 
368   // From Profile::RegisterProfilePrefs.
369   registry->RegisterDictionaryPref(prefs::kPartitionDefaultZoomLevel);
370   registry->RegisterDictionaryPref(prefs::kPartitionPerHostZoomLevels);
371 }
372 
PopulateWebPreferences(content::RenderViewHost * rvh,blink::web_pref::WebPreferences & web)373 void PopulateWebPreferences(content::RenderViewHost* rvh,
374                             blink::web_pref::WebPreferences& web) {
375   REQUIRE_ALLOY_RUNTIME();
376   CefRefPtr<AlloyBrowserHostImpl> browser = static_cast<AlloyBrowserHostImpl*>(
377       extensions::GetOwnerBrowserForHost(rvh, nullptr).get());
378 
379   // Set defaults for preferences that are not handled by PrefService.
380   SetDefaultPrefs(web);
381 
382   // Set preferences based on the context's PrefService.
383   if (browser) {
384     auto profile = Profile::FromBrowserContext(
385         browser->web_contents()->GetBrowserContext());
386     SetChromePrefs(profile, web);
387   }
388 
389   auto* native_theme = ui::NativeTheme::GetInstanceForWeb();
390   switch (native_theme->GetPreferredColorScheme()) {
391     case ui::NativeTheme::PreferredColorScheme::kDark:
392       web.preferred_color_scheme = blink::mojom::PreferredColorScheme::kDark;
393       break;
394     case ui::NativeTheme::PreferredColorScheme::kLight:
395       web.preferred_color_scheme = blink::mojom::PreferredColorScheme::kLight;
396       break;
397   }
398 
399   switch (native_theme->GetPreferredContrast()) {
400     case ui::NativeTheme::PreferredContrast::kNoPreference:
401       web.preferred_contrast = blink::mojom::PreferredContrast::kNoPreference;
402       break;
403     case ui::NativeTheme::PreferredContrast::kMore:
404       web.preferred_contrast = blink::mojom::PreferredContrast::kMore;
405       break;
406     case ui::NativeTheme::PreferredContrast::kLess:
407       web.preferred_contrast = blink::mojom::PreferredContrast::kLess;
408       break;
409   }
410 
411   UpdatePreferredColorScheme(
412       &web, rvh->GetMainFrame()->GetSiteInstance()->GetSiteURL(), native_theme);
413 
414   // Set preferences based on the extension.
415   SetExtensionPrefs(rvh, web);
416 
417   if (browser) {
418     // Set preferences based on CefBrowserSettings.
419     SetCefPrefs(browser->settings(), web);
420 
421     web.picture_in_picture_enabled = browser->IsPictureInPictureSupported();
422 
423     // Set the background color for the WebView.
424     web.base_background_color = browser->GetBackgroundColor();
425   } else {
426     // We don't know for sure that the browser will be windowless but assume
427     // that the global windowless state is likely to be accurate.
428     web.base_background_color =
429         CefContext::Get()->GetBackgroundColor(nullptr, STATE_DEFAULT);
430   }
431 }
432 
PopulateWebPreferencesAfterNavigation(content::WebContents * web_contents,blink::web_pref::WebPreferences & web)433 bool PopulateWebPreferencesAfterNavigation(
434     content::WebContents* web_contents,
435     blink::web_pref::WebPreferences& web) {
436   auto* native_theme = ui::NativeTheme::GetInstanceForWeb();
437   return UpdatePreferredColorScheme(&web, web_contents->GetLastCommittedURL(),
438                                     native_theme);
439 }
440 
441 }  // namespace renderer_prefs
442