• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2013 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/browser_prefs.h"
6 
7 #include "libcef/browser/browser_context.h"
8 #include "libcef/browser/browser_host_base.h"
9 #include "libcef/browser/context.h"
10 #include "libcef/browser/media_capture_devices_dispatcher.h"
11 #include "libcef/browser/prefs/pref_store.h"
12 #include "libcef/browser/prefs/renderer_prefs.h"
13 #include "libcef/common/cef_switches.h"
14 #include "libcef/common/extensions/extensions_util.h"
15 
16 #include "base/command_line.h"
17 #include "base/files/file_path.h"
18 #include "base/strings/string_number_conversions.h"
19 #include "base/task/post_task.h"
20 #include "base/task/thread_pool.h"
21 #include "base/values.h"
22 #include "chrome/browser/accessibility/accessibility_ui.h"
23 #include "chrome/browser/download/download_prefs.h"
24 #include "chrome/browser/media/media_device_id_salt.h"
25 #include "chrome/browser/media/router/media_router_feature.h"
26 #include "chrome/browser/net/profile_network_context_service.h"
27 #include "chrome/browser/net/system_network_context_manager.h"
28 #include "chrome/browser/plugins/plugin_info_host_impl.h"
29 #include "chrome/browser/prefetch/prefetch_prefs.h"
30 #include "chrome/browser/prefs/chrome_command_line_pref_store.h"
31 #include "chrome/browser/printing/print_preview_sticky_settings.h"
32 #include "chrome/browser/profiles/profile.h"
33 #include "chrome/browser/ssl/ssl_config_service_manager.h"
34 #include "chrome/browser/themes/theme_service.h"
35 #include "chrome/browser/ui/webui/print_preview/policy_settings.h"
36 #include "chrome/common/buildflags.h"
37 #include "chrome/common/chrome_switches.h"
38 #include "chrome/common/net/safe_search_util.h"
39 #include "chrome/common/pref_names.h"
40 #include "chrome/grit/locale_settings.h"
41 #include "components/certificate_transparency/pref_names.h"
42 #include "components/component_updater/component_updater_service.h"
43 #include "components/content_settings/core/browser/cookie_settings.h"
44 #include "components/content_settings/core/browser/host_content_settings_map.h"
45 #include "components/flags_ui/pref_service_flags_storage.h"
46 #include "components/keyed_service/content/browser_context_dependency_manager.h"
47 #include "components/language/core/browser/language_prefs.h"
48 #include "components/language/core/browser/pref_names.h"
49 #include "components/pref_registry/pref_registry_syncable.h"
50 #include "components/prefs/json_pref_store.h"
51 #include "components/prefs/pref_filter.h"
52 #include "components/prefs/pref_registry_simple.h"
53 #include "components/prefs/pref_service.h"
54 #include "components/proxy_config/pref_proxy_config_tracker_impl.h"
55 #include "components/proxy_config/proxy_config_dictionary.h"
56 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
57 #include "components/spellcheck/browser/pref_names.h"
58 #include "components/sync_preferences/pref_service_syncable.h"
59 #include "components/sync_preferences/pref_service_syncable_factory.h"
60 #include "components/update_client/update_client.h"
61 #include "content/public/browser/browser_thread.h"
62 #include "extensions/browser/extension_prefs.h"
63 #include "extensions/buildflags/buildflags.h"
64 #include "net/http/http_util.h"
65 #include "ui/base/l10n/l10n_util.h"
66 #include "ui/base/ui_base_switches.h"
67 
68 #if BUILDFLAG(IS_WIN)
69 #include "components/os_crypt/os_crypt.h"
70 #endif
71 
72 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
73 #include "chrome/browser/supervised_user/supervised_user_pref_store.h"
74 #include "chrome/browser/supervised_user/supervised_user_settings_service.h"
75 #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
76 #endif
77 
78 namespace browser_prefs {
79 
80 namespace {
81 
82 // Match the logic in chrome/browser/net/profile_network_context_service.cc.
ComputeAcceptLanguageFromPref(const std::string & language_pref)83 std::string ComputeAcceptLanguageFromPref(const std::string& language_pref) {
84   std::string accept_languages_str =
85       net::HttpUtil::ExpandLanguageList(language_pref);
86   return net::HttpUtil::GenerateAcceptLanguageHeader(accept_languages_str);
87 }
88 
89 // Return the most relevant setting based on |browser_context| and |browser|.
GetAcceptLanguageListSetting(CefBrowserContext * browser_context,CefBrowserHostBase * browser)90 std::string GetAcceptLanguageListSetting(CefBrowserContext* browser_context,
91                                          CefBrowserHostBase* browser) {
92   if (browser) {
93     const auto& settings = browser->settings();
94     if (settings.accept_language_list.length > 0) {
95       return CefString(&settings.accept_language_list);
96     }
97   }
98 
99   if (browser_context) {
100     const auto& settings = browser_context->settings();
101     if (settings.accept_language_list.length > 0) {
102       return CefString(&settings.accept_language_list);
103     }
104   }
105 
106   const auto& settings = CefContext::Get()->settings();
107   if (settings.accept_language_list.length > 0) {
108     return CefString(&settings.accept_language_list);
109   }
110 
111   return std::string();
112 }
113 
114 }  // namespace
115 
116 const char kUserPrefsFileName[] = "UserPrefs.json";
117 const char kLocalPrefsFileName[] = "LocalPrefs.json";
118 
RegisterProfilePrefs(PrefRegistrySimple * registry)119 void RegisterProfilePrefs(PrefRegistrySimple* registry) {
120   const base::CommandLine* command_line =
121       base::CommandLine::ForCurrentProcess();
122   if (command_line->HasSwitch(switches::kEnablePreferenceTesting)) {
123     // Preferences used with unit tests.
124     registry->RegisterBooleanPref("test.bool", true);
125     registry->RegisterIntegerPref("test.int", 2);
126     registry->RegisterDoublePref("test.double", 5.0);
127     registry->RegisterStringPref("test.string", "default");
128     registry->RegisterListPref("test.list");
129     registry->RegisterDictionaryPref("test.dict");
130   }
131 }
132 
CreatePrefService(Profile * profile,const base::FilePath & cache_path,bool persist_user_preferences)133 std::unique_ptr<PrefService> CreatePrefService(Profile* profile,
134                                                const base::FilePath& cache_path,
135                                                bool persist_user_preferences) {
136   const base::CommandLine* command_line =
137       base::CommandLine::ForCurrentProcess();
138 
139   // Use of PrefServiceSyncable is required by Chrome code such as
140   // HostContentSettingsMapFactory that calls PrefServiceSyncableFromProfile.
141   sync_preferences::PrefServiceSyncableFactory factory;
142 
143   // Used to store command-line preferences, most of which will be evaluated in
144   // the CommandLinePrefStore constructor. Preferences set in this manner cannot
145   // be overridden by the user.
146   scoped_refptr<ChromeCommandLinePrefStore> command_line_pref_store(
147       new ChromeCommandLinePrefStore(command_line));
148   renderer_prefs::SetCommandLinePrefDefaults(command_line_pref_store.get());
149   factory.set_command_line_prefs(command_line_pref_store);
150 
151   // True if preferences will be stored on disk.
152   const bool store_on_disk = !cache_path.empty() && persist_user_preferences;
153 
154   scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner;
155   if (store_on_disk) {
156     // Get sequenced task runner for making sure that file operations are
157     // executed in expected order (what was previously assured by the FILE
158     // thread).
159     sequenced_task_runner = base::ThreadPool::CreateSequencedTaskRunner(
160         {base::MayBlock(), base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
161   }
162 
163   // Used to store user preferences.
164   scoped_refptr<PersistentPrefStore> user_pref_store;
165   if (store_on_disk) {
166     const base::FilePath& pref_path = cache_path.AppendASCII(
167         profile ? kUserPrefsFileName : kLocalPrefsFileName);
168     scoped_refptr<JsonPrefStore> json_pref_store = new JsonPrefStore(
169         pref_path, std::unique_ptr<PrefFilter>(), sequenced_task_runner);
170     factory.set_user_prefs(json_pref_store.get());
171   } else {
172     scoped_refptr<CefPrefStore> cef_pref_store = new CefPrefStore();
173     cef_pref_store->SetInitializationCompleted();
174     factory.set_user_prefs(cef_pref_store.get());
175   }
176 
177 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
178   if (profile) {
179     // Used to store supervised user preferences.
180     SupervisedUserSettingsService* supervised_user_settings =
181         SupervisedUserSettingsServiceFactory::GetForKey(
182             profile->GetProfileKey());
183 
184     if (store_on_disk) {
185       supervised_user_settings->Init(cache_path, sequenced_task_runner.get(),
186                                      true);
187     } else {
188       scoped_refptr<CefPrefStore> cef_pref_store = new CefPrefStore();
189       cef_pref_store->SetInitializationCompleted();
190       supervised_user_settings->Init(cef_pref_store);
191     }
192 
193     scoped_refptr<PrefStore> supervised_user_prefs =
194         base::MakeRefCounted<SupervisedUserPrefStore>(supervised_user_settings);
195     DCHECK(supervised_user_prefs->IsInitializationComplete());
196     factory.set_supervised_user_prefs(supervised_user_prefs);
197   }
198 #endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS)
199 
200   // Registry that will be populated with all known preferences. Preferences
201   // are registered with default values that may be changed via a *PrefStore.
202   scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
203       new user_prefs::PrefRegistrySyncable());
204 
205   // Some preferences are specific to CEF and others are defined in Chromium.
206   // The preferred approach for registering preferences defined in Chromium is
207   // as follows:
208   //
209   // 1. If a non-static RegisterProfilePrefs() method exists in a *Factory
210   //    class then add a *Factory::GetInstance() call in
211   //    EnsureBrowserContextKeyedServiceFactoriesBuilt().
212   // 2. If a static RegisterPrefs() method exists then call that method in the
213   //    "Default preferences" section below.
214   // 3. If the default values are not appropriate but the set of registered
215   //    preferences is otherwise fine then change the defaults by calling
216   //    SetDefaultPrefValue after calling the existing registration method.
217   // 4. If the original registration method contains many unused preferences or
218   //    otherwise inappropiate logic (e.g. calls to objects that CEF doesn't
219   //    use) then register the preferences directly instead of calling the
220   //    existing registration method.
221 
222   // Default preferences.
223   CefMediaCaptureDevicesDispatcher::RegisterPrefs(registry.get());
224   certificate_transparency::prefs::RegisterPrefs(registry.get());
225   flags_ui::PrefServiceFlagsStorage::RegisterPrefs(registry.get());
226   media_router::RegisterLocalStatePrefs(registry.get());
227   PluginInfoHostImpl::RegisterUserPrefs(registry.get());
228   PrefProxyConfigTrackerImpl::RegisterPrefs(registry.get());
229   ProfileNetworkContextService::RegisterLocalStatePrefs(registry.get());
230   SSLConfigServiceManager::RegisterPrefs(registry.get());
231   update_client::RegisterPrefs(registry.get());
232 
233   if (!profile) {
234     component_updater::RegisterComponentUpdateServicePrefs(registry.get());
235     SystemNetworkContextManager::RegisterPrefs(registry.get());
236 #if BUILDFLAG(IS_WIN)
237     OSCrypt::RegisterLocalPrefs(registry.get());
238 #endif
239   }
240 
241   // Browser process preferences.
242   // Based on chrome/browser/browser_process_impl.cc RegisterPrefs.
243   registry->RegisterBooleanPref(prefs::kAllowCrossOriginAuthPrompt, false);
244 
245   // Browser UI preferences.
246   // Based on chrome/browser/ui/browser_ui_prefs.cc RegisterBrowserPrefs.
247   registry->RegisterBooleanPref(prefs::kAllowFileSelectionDialogs, true);
248 
249   // Based on chrome/browser/ui/browser_ui_prefs.cc RegisterBrowserUserPrefs.
250   registry->RegisterBooleanPref(prefs::kPrintPreviewUseSystemDefaultPrinter,
251                                 false);
252   registry->RegisterBooleanPref(prefs::kWebRTCAllowLegacyTLSProtocols, false);
253 
254   // Profile preferences.
255   // Based on chrome/browser/profiles/profiles_state.cc RegisterPrefs.
256   registry->RegisterStringPref(prefs::kProfileLastUsed, std::string());
257 
258   if (profile) {
259     // Call RegisterProfilePrefs() for all services listed by
260     // EnsureBrowserContextKeyedServiceFactoriesBuilt().
261     BrowserContextDependencyManager::GetInstance()
262         ->RegisterProfilePrefsForServices(registry.get());
263 
264     // Default profile preferences.
265     AccessibilityUIMessageHandler::RegisterProfilePrefs(registry.get());
266     extensions::ExtensionPrefs::RegisterProfilePrefs(registry.get());
267     HostContentSettingsMap::RegisterProfilePrefs(registry.get());
268     language::LanguagePrefs::RegisterProfilePrefs(registry.get());
269     media_router::RegisterProfilePrefs(registry.get());
270     MediaDeviceIDSalt::RegisterProfilePrefs(registry.get());
271     prefetch::RegisterPredictionOptionsProfilePrefs(registry.get());
272     ProfileNetworkContextService::RegisterProfilePrefs(registry.get());
273     safe_browsing::RegisterProfilePrefs(registry.get());
274     RegisterProfilePrefs(registry.get());
275 
276     const std::string& locale =
277         command_line->GetSwitchValueASCII(switches::kLang);
278     DCHECK(!locale.empty());
279     renderer_prefs::RegisterProfilePrefs(registry.get(), locale);
280 
281     // Print preferences.
282     // Based on ProfileImpl::RegisterProfilePrefs.
283     registry->RegisterBooleanPref(prefs::kForceGoogleSafeSearch, false);
284     registry->RegisterIntegerPref(prefs::kForceYouTubeRestrict,
285                                   safe_search_util::YOUTUBE_RESTRICT_OFF);
286     registry->RegisterStringPref(prefs::kAllowedDomainsForApps, std::string());
287     registry->RegisterBooleanPref(prefs::kPrintingEnabled, true);
288     registry->RegisterBooleanPref(prefs::kPrintPreviewDisabled,
289                                   !extensions::PrintPreviewEnabled());
290     registry->RegisterStringPref(
291         prefs::kPrintPreviewDefaultDestinationSelectionRules, std::string());
292     registry->RegisterBooleanPref(prefs::kCloudPrintSubmitEnabled, false);
293     registry->RegisterBooleanPref(prefs::kEnableMediaRouter, true);
294     printing::PolicySettings::RegisterProfilePrefs(registry.get());
295     printing::PrintPreviewStickySettings::RegisterProfilePrefs(registry.get());
296     DownloadPrefs::RegisterProfilePrefs(registry.get());
297 
298     // Cache preferences.
299     // Based on ProfileImpl::RegisterProfilePrefs.
300     registry->RegisterFilePathPref(prefs::kDiskCacheDir, cache_path);
301     registry->RegisterIntegerPref(prefs::kDiskCacheSize, 0);
302 
303     // Based on Profile::RegisterProfilePrefs.
304     registry->RegisterBooleanPref(prefs::kSearchSuggestEnabled, false);
305     registry->RegisterStringPref(prefs::kSessionExitType, std::string());
306 
307     // Spell checking preferences.
308     // Modify defaults from SpellcheckServiceFactory::RegisterProfilePrefs.
309     std::string spellcheck_lang =
310         command_line->GetSwitchValueASCII(switches::kOverrideSpellCheckLang);
311     if (!spellcheck_lang.empty()) {
312       registry->SetDefaultPrefValue(spellcheck::prefs::kSpellCheckDictionary,
313                                     base::Value(spellcheck_lang));
314     }
315     const bool enable_spelling_service_ =
316         command_line->HasSwitch(switches::kEnableSpellingService);
317     registry->SetDefaultPrefValue(
318         spellcheck::prefs::kSpellCheckUseSpellingService,
319         base::Value(enable_spelling_service_));
320     registry->SetDefaultPrefValue(spellcheck::prefs::kSpellCheckEnable,
321                                   base::Value(!enable_spelling_service_));
322 
323     // DevTools preferences.
324     // Based on DevToolsWindow::RegisterProfilePrefs.
325     registry->RegisterDictionaryPref(prefs::kDevToolsPreferences);
326     registry->RegisterDictionaryPref(prefs::kDevToolsEditedFiles);
327 
328     // Language preferences. Used by ProfileNetworkContextService and
329     // InterceptedRequestHandlerWrapper.
330     const std::string& accept_language_list = GetAcceptLanguageListSetting(
331         CefBrowserContext::FromProfile(profile), /*browser=*/nullptr);
332     if (!accept_language_list.empty()) {
333       registry->SetDefaultPrefValue(language::prefs::kAcceptLanguages,
334                                     base::Value(accept_language_list));
335     }
336     registry->RegisterListPref(prefs::kWebRtcLocalIpsAllowedUrls);
337   }
338 
339   // Build the PrefService that manages the PrefRegistry and PrefStores.
340   return factory.CreateSyncable(registry.get());
341 }
342 
GetAcceptLanguageList(CefBrowserContext * browser_context,CefBrowserHostBase * browser,bool expand)343 std::string GetAcceptLanguageList(CefBrowserContext* browser_context,
344                                   CefBrowserHostBase* browser,
345                                   bool expand) {
346   // Always prefer to the CEF settings configuration, if specified.
347   std::string accept_language_list =
348       GetAcceptLanguageListSetting(browser_context, browser);
349   if (accept_language_list.empty() && browser_context) {
350     // Fall back to the preference value. For the Alloy runtime the default
351     // value comes from browser_prefs::CreatePrefService() above. For the Chrome
352     // runtime the default value comes from the configured locale
353     // (IDS_ACCEPT_LANGUAGES) which is then overridden by the user preference in
354     // chrome://settings/languages, all managed by language::LanguagePrefs.
355     auto prefs = browser_context->AsProfile()->GetPrefs();
356     accept_language_list = prefs->GetString(language::prefs::kAcceptLanguages);
357   }
358 
359   if (!accept_language_list.empty() && expand) {
360     return ComputeAcceptLanguageFromPref(accept_language_list);
361   }
362   return std::string();
363 }
364 
365 }  // namespace browser_prefs
366