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