Revert of Merge apps/pref* to extensions/browser/pref* (patchset #1 of https://codere...
[chromium-blink-merge.git] / chrome / browser / chrome_content_browser_client.cc
blob5c89f1bf39326dd1f8cd960e1b7ff5a5935f7c91
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.
5 #include "chrome/browser/chrome_content_browser_client.h"
7 #include <set>
8 #include <utility>
9 #include <vector>
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/lazy_instance.h"
14 #include "base/path_service.h"
15 #include "base/prefs/pref_service.h"
16 #include "base/prefs/scoped_user_pref_update.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/threading/sequenced_worker_pool.h"
20 #include "chrome/browser/browser_about_handler.h"
21 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/browser_shutdown.h"
23 #include "chrome/browser/browsing_data/browsing_data_helper.h"
24 #include "chrome/browser/browsing_data/browsing_data_remover.h"
25 #include "chrome/browser/character_encoding.h"
26 #include "chrome/browser/chrome_content_browser_client_parts.h"
27 #include "chrome/browser/chrome_net_benchmarking_message_filter.h"
28 #include "chrome/browser/chrome_quota_permission_context.h"
29 #include "chrome/browser/content_settings/content_settings_utils.h"
30 #include "chrome/browser/content_settings/cookie_settings.h"
31 #include "chrome/browser/content_settings/host_content_settings_map.h"
32 #include "chrome/browser/content_settings/permission_request_id.h"
33 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
34 #include "chrome/browser/defaults.h"
35 #include "chrome/browser/devtools/chrome_devtools_manager_delegate.h"
36 #include "chrome/browser/download/download_prefs.h"
37 #include "chrome/browser/font_family_cache.h"
38 #include "chrome/browser/geolocation/chrome_access_token_store.h"
39 #include "chrome/browser/geolocation/geolocation_permission_context.h"
40 #include "chrome/browser/geolocation/geolocation_permission_context_factory.h"
41 #include "chrome/browser/media/cast_transport_host_filter.h"
42 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
43 #include "chrome/browser/media/midi_permission_context.h"
44 #include "chrome/browser/media/midi_permission_context_factory.h"
45 #include "chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.h"
46 #include "chrome/browser/nacl_host/nacl_browser_delegate_impl.h"
47 #include "chrome/browser/net/chrome_net_log.h"
48 #include "chrome/browser/notifications/desktop_notification_service.h"
49 #include "chrome/browser/notifications/desktop_notification_service_factory.h"
50 #include "chrome/browser/platform_util.h"
51 #include "chrome/browser/plugins/plugin_info_message_filter.h"
52 #include "chrome/browser/prerender/prerender_final_status.h"
53 #include "chrome/browser/prerender/prerender_manager.h"
54 #include "chrome/browser/prerender/prerender_manager_factory.h"
55 #include "chrome/browser/prerender/prerender_message_filter.h"
56 #include "chrome/browser/prerender/prerender_tracker.h"
57 #include "chrome/browser/printing/printing_message_filter.h"
58 #include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h"
59 #include "chrome/browser/profiles/profile.h"
60 #include "chrome/browser/profiles/profile_io_data.h"
61 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
62 #include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
63 #include "chrome/browser/search/instant_service.h"
64 #include "chrome/browser/search/instant_service_factory.h"
65 #include "chrome/browser/search/search.h"
66 #include "chrome/browser/search_engines/search_provider_install_state_message_filter.h"
67 #include "chrome/browser/signin/principals_message_filter.h"
68 #include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h"
69 #include "chrome/browser/speech/extension_api/tts_engine_extension_api.h"
70 #include "chrome/browser/speech/tts_controller.h"
71 #include "chrome/browser/speech/tts_message_filter.h"
72 #include "chrome/browser/ssl/ssl_add_certificate.h"
73 #include "chrome/browser/ssl/ssl_blocking_page.h"
74 #include "chrome/browser/ssl/ssl_client_certificate_selector.h"
75 #include "chrome/browser/tab_contents/tab_util.h"
76 #include "chrome/browser/ui/blocked_content/blocked_window_params.h"
77 #include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h"
78 #include "chrome/browser/ui/chrome_select_file_policy.h"
79 #include "chrome/browser/ui/sync/sync_promo_ui.h"
80 #include "chrome/browser/ui/tab_contents/chrome_web_contents_view_delegate.h"
81 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
82 #include "chrome/common/chrome_constants.h"
83 #include "chrome/common/chrome_paths.h"
84 #include "chrome/common/chrome_switches.h"
85 #include "chrome/common/content_settings.h"
86 #include "chrome/common/env_vars.h"
87 #include "chrome/common/logging_chrome.h"
88 #include "chrome/common/pepper_permission_util.h"
89 #include "chrome/common/pref_names.h"
90 #include "chrome/common/render_messages.h"
91 #include "chrome/common/url_constants.h"
92 #include "chrome/grit/generated_resources.h"
93 #include "chrome/installer/util/google_update_settings.h"
94 #include "chromeos/chromeos_constants.h"
95 #include "components/cdm/browser/cdm_message_filter_android.h"
96 #include "components/cloud_devices/common/cloud_devices_switches.h"
97 #include "components/dom_distiller/core/url_constants.h"
98 #include "components/google/core/browser/google_util.h"
99 #include "components/metrics/client_info.h"
100 #include "components/pref_registry/pref_registry_syncable.h"
101 #include "components/signin/core/common/profile_management_switches.h"
102 #include "components/translate/core/common/translate_switches.h"
103 #include "content/public/browser/browser_child_process_host.h"
104 #include "content/public/browser/browser_main_parts.h"
105 #include "content/public/browser/browser_ppapi_host.h"
106 #include "content/public/browser/browser_thread.h"
107 #include "content/public/browser/browser_url_handler.h"
108 #include "content/public/browser/child_process_data.h"
109 #include "content/public/browser/child_process_security_policy.h"
110 #include "content/public/browser/desktop_notification_delegate.h"
111 #include "content/public/browser/render_frame_host.h"
112 #include "content/public/browser/render_process_host.h"
113 #include "content/public/browser/render_view_host.h"
114 #include "content/public/browser/resource_context.h"
115 #include "content/public/browser/site_instance.h"
116 #include "content/public/browser/web_contents.h"
117 #include "content/public/common/child_process_host.h"
118 #include "content/public/common/content_descriptors.h"
119 #include "content/public/common/show_desktop_notification_params.h"
120 #include "content/public/common/url_utils.h"
121 #include "content/public/common/web_preferences.h"
122 #include "extensions/browser/extension_system.h"
123 #include "extensions/common/constants.h"
124 #include "extensions/common/extension.h"
125 #include "extensions/common/extension_set.h"
126 #include "extensions/common/manifest_handlers/shared_module_info.h"
127 #include "extensions/common/permissions/permissions_data.h"
128 #include "extensions/common/permissions/socket_permission.h"
129 #include "extensions/common/switches.h"
130 #include "net/base/mime_util.h"
131 #include "net/cookies/canonical_cookie.h"
132 #include "net/cookies/cookie_options.h"
133 #include "net/ssl/ssl_cert_request_info.h"
134 #include "ppapi/host/ppapi_host.h"
135 #include "ppapi/shared_impl/ppapi_switches.h"
136 #include "ui/base/l10n/l10n_util.h"
137 #include "ui/base/resource/resource_bundle.h"
138 #include "ui/resources/grit/ui_resources.h"
139 #include "webkit/browser/fileapi/external_mount_points.h"
141 #if defined(OS_WIN)
142 #include "base/win/windows_version.h"
143 #include "chrome/browser/chrome_browser_main_win.h"
144 #include "sandbox/win/src/sandbox_policy.h"
145 #elif defined(OS_MACOSX)
146 #include "chrome/browser/chrome_browser_main_mac.h"
147 #include "chrome/browser/spellchecker/spellcheck_message_filter_mac.h"
148 #include "components/breakpad/app/breakpad_mac.h"
149 #elif defined(OS_CHROMEOS)
150 #include "chrome/browser/chromeos/chrome_browser_main_chromeos.h"
151 #include "chrome/browser/chromeos/drive/fileapi/file_system_backend_delegate.h"
152 #include "chrome/browser/chromeos/file_manager/app_id.h"
153 #include "chrome/browser/chromeos/file_system_provider/fileapi/backend_delegate.h"
154 #include "chrome/browser/chromeos/fileapi/file_system_backend.h"
155 #include "chrome/browser/chromeos/fileapi/mtp_file_system_backend_delegate.h"
156 #include "chrome/browser/chromeos/login/startup_utils.h"
157 #include "chrome/browser/chromeos/system/input_device_settings.h"
158 #include "chromeos/chromeos_switches.h"
159 #include "components/user_manager/user_manager.h"
160 #elif defined(OS_LINUX)
161 #include "chrome/browser/chrome_browser_main_linux.h"
162 #elif defined(OS_ANDROID)
163 #include "chrome/browser/android/new_tab_page_url_handler.h"
164 #include "chrome/browser/android/webapps/single_tab_mode_tab_helper.h"
165 #include "chrome/browser/chrome_browser_main_android.h"
166 #include "chrome/browser/media/protected_media_identifier_permission_context.h"
167 #include "chrome/browser/media/protected_media_identifier_permission_context_factory.h"
168 #include "chrome/common/descriptors_android.h"
169 #include "components/breakpad/browser/crash_dump_manager_android.h"
170 #elif defined(OS_POSIX)
171 #include "chrome/browser/chrome_browser_main_posix.h"
172 #endif
174 #if defined(OS_POSIX) && !defined(OS_MACOSX)
175 #include "base/debug/leak_annotations.h"
176 #include "components/breakpad/app/breakpad_linux.h"
177 #include "components/breakpad/browser/crash_handler_host_linux.h"
178 #endif
180 #if defined(OS_ANDROID)
181 #include "ui/base/ui_base_paths.h"
182 #include "ui/gfx/android/device_display_info.h"
183 #endif
185 #if !defined(OS_CHROMEOS)
186 #include "chrome/browser/signin/chrome_signin_client.h"
187 #include "chrome/browser/signin/chrome_signin_client_factory.h"
188 #include "chrome/browser/signin/signin_manager_factory.h"
189 #include "components/signin/core/browser/signin_manager.h"
190 #endif
192 #if defined(TOOLKIT_VIEWS)
193 #include "chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h"
194 #endif
196 #if defined(USE_ASH)
197 #include "chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.h"
198 #endif
200 #if defined(USE_AURA)
201 #include "chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.h"
202 #endif
204 #if defined(USE_X11)
205 #include "chrome/browser/chrome_browser_main_extra_parts_x11.h"
206 #endif
208 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
209 #include "chrome/browser/captive_portal/captive_portal_tab_helper.h"
210 #endif
212 #if !defined(DISABLE_NACL)
213 #include "components/nacl/browser/nacl_browser.h"
214 #include "components/nacl/browser/nacl_host_message_filter.h"
215 #include "components/nacl/browser/nacl_process_host.h"
216 #include "components/nacl/common/nacl_process_type.h"
217 #include "components/nacl/common/nacl_switches.h"
218 #endif
220 #if defined(ENABLE_EXTENSIONS)
221 #include "chrome/browser/extensions/chrome_content_browser_client_extensions_part.h"
222 #include "chrome/browser/extensions/extension_service.h"
223 #include "chrome/browser/extensions/extension_util.h"
224 #include "chrome/browser/guest_view/web_view/web_view_guest.h"
225 #include "chrome/browser/guest_view/web_view/web_view_permission_helper.h"
226 #include "chrome/browser/guest_view/web_view/web_view_renderer_state.h"
227 #include "extensions/browser/guest_view/guest_view_base.h"
228 #include "extensions/browser/guest_view/guest_view_constants.h"
229 #include "extensions/browser/guest_view/guest_view_manager.h"
230 #include "extensions/browser/suggest_permission_util.h"
231 #include "extensions/common/manifest_handlers/background_info.h"
232 #endif
234 #if defined(ENABLE_SPELLCHECK)
235 #include "chrome/browser/spellchecker/spellcheck_message_filter.h"
236 #endif
238 #if defined(ENABLE_SERVICE_DISCOVERY)
239 #include "chrome/browser/local_discovery/storage/privet_filesystem_backend.h"
240 #endif
242 #if defined(ENABLE_WEBRTC)
243 #include "chrome/browser/media/webrtc_logging_handler_host.h"
244 #endif
246 using base::FileDescriptor;
247 using blink::WebWindowFeatures;
248 using content::AccessTokenStore;
249 using content::BrowserThread;
250 using content::BrowserURLHandler;
251 using content::ChildProcessSecurityPolicy;
252 using content::QuotaPermissionContext;
253 using content::RenderFrameHost;
254 using content::RenderViewHost;
255 using content::ResourceType;
256 using content::SiteInstance;
257 using content::WebContents;
258 using content::WebPreferences;
259 using extensions::APIPermission;
260 using extensions::Extension;
261 using extensions::InfoMap;
262 using extensions::Manifest;
263 using message_center::NotifierId;
265 #if defined(OS_POSIX)
266 using content::FileDescriptorInfo;
267 #endif
269 #if defined(ENABLE_EXTENSIONS)
270 using extensions::ChromeContentBrowserClientExtensionsPart;
271 #endif
273 namespace {
275 // Cached version of the locale so we can return the locale on the I/O
276 // thread.
277 base::LazyInstance<std::string> g_io_thread_application_locale;
279 #if defined(ENABLE_PLUGINS)
280 // TODO(teravest): Add renderer-side API-specific checking for these APIs so
281 // that blanket permission isn't granted to all dev channel APIs for these.
282 // http://crbug.com/386743
283 const char* const kPredefinedAllowedDevChannelOrigins[] = {
284 "6EAED1924DB611B6EEF2A664BD077BE7EAD33B8F", // see crbug.com/383937
285 "4EB74897CB187C7633357C2FE832E0AD6A44883A" // see crbug.com/383937
288 const char* const kPredefinedAllowedFileHandleOrigins[] = {
289 "6EAED1924DB611B6EEF2A664BD077BE7EAD33B8F", // see crbug.com/234789
290 "4EB74897CB187C7633357C2FE832E0AD6A44883A" // see crbug.com/234789
293 const char* const kPredefinedAllowedSocketOrigins[] = {
294 "okddffdblfhhnmhodogpojmfkjmhinfp", // Test SSH Client
295 "pnhechapfaindjhompbnflcldabbghjo", // HTerm App (SSH Client)
296 "bglhmjfplikpjnfoegeomebmfnkjomhe", // see crbug.com/122126
297 "gbchcmhmhahfdphkhkmpfmihenigjmpp", // Chrome Remote Desktop
298 "kgngmbheleoaphbjbaiobfdepmghbfah", // Pre-release Chrome Remote Desktop
299 "odkaodonbgfohohmklejpjiejmcipmib", // Dogfood Chrome Remote Desktop
300 "ojoimpklfciegopdfgeenehpalipignm", // Chromoting canary
301 "cbkkbcmdlboombapidmoeolnmdacpkch", // see crbug.com/129089
302 "hhnbmknkdabfoieppbbljkhkfjcmcbjh", // see crbug.com/134099
303 "mablfbjkhmhkmefkjjacnbaikjkipphg", // see crbug.com/134099
304 "pdeelgamlgannhelgoegilelnnojegoh", // see crbug.com/134099
305 "cabapfdbkniadpollkckdnedaanlciaj", // see crbug.com/134099
306 "mapljbgnjledlpdmlchihnmeclmefbba", // see crbug.com/134099
307 "ghbfeebgmiidnnmeobbbaiamklmpbpii", // see crbug.com/134099
308 "jdfhpkjeckflbbleddjlpimecpbjdeep", // see crbug.com/142514
309 "iabmpiboiopbgfabjmgeedhcmjenhbla", // see crbug.com/165080
310 "B7CF8A292249681AF81771650BA4CEEAF19A4560", // see crbug.com/165080
311 "6EAED1924DB611B6EEF2A664BD077BE7EAD33B8F", // see crbug.com/234789
312 "4EB74897CB187C7633357C2FE832E0AD6A44883A", // see crbug.com/234789
313 "7525AF4F66763A70A883C4700529F647B470E4D2", // see crbug.com/238084
314 "0B549507088E1564D672F7942EB87CA4DAD73972", // see crbug.com/238084
315 "864288364E239573E777D3E0E36864E590E95C74" // see crbug.com/238084
317 #endif
319 // Returns a copy of the given url with its host set to given host and path set
320 // to given path. Other parts of the url will be the same.
321 GURL ReplaceURLHostAndPath(const GURL& url,
322 const std::string& host,
323 const std::string& path) {
324 url::Replacements<char> replacements;
325 replacements.SetHost(host.c_str(), url::Component(0, host.length()));
326 replacements.SetPath(path.c_str(), url::Component(0, path.length()));
327 return url.ReplaceComponents(replacements);
330 // Maps "foo://bar/baz/" to "foo://chrome/bar/baz/".
331 GURL AddUberHost(const GURL& url) {
332 const std::string uber_host = chrome::kChromeUIUberHost;
333 const std::string new_path = url.host() + url.path();
335 return ReplaceURLHostAndPath(url, uber_host, new_path);
338 // If url->host() is "chrome" and url->path() has characters other than the
339 // first slash, changes the url from "foo://chrome/bar/" to "foo://bar/" and
340 // returns true. Otherwise returns false.
341 bool RemoveUberHost(GURL* url) {
342 if (url->host() != chrome::kChromeUIUberHost)
343 return false;
345 if (url->path().empty() || url->path() == "/")
346 return false;
348 const std::string old_path = url->path();
350 const std::string::size_type separator = old_path.find('/', 1);
351 std::string new_host;
352 std::string new_path;
353 if (separator == std::string::npos) {
354 new_host = old_path.substr(1);
355 } else {
356 new_host = old_path.substr(1, separator - 1);
357 new_path = old_path.substr(separator);
360 // Do not allow URLs with paths empty before the first slash since we can't
361 // have an empty host. (e.g "foo://chrome//")
362 if (new_host.empty())
363 return false;
365 *url = ReplaceURLHostAndPath(*url, new_host, new_path);
367 DCHECK(url->is_valid());
369 return true;
372 // Handles rewriting Web UI URLs.
373 bool HandleWebUI(GURL* url, content::BrowserContext* browser_context) {
374 // Do not handle special URLs such as "about:foo"
375 if (!url->host().empty()) {
376 const GURL chrome_url = AddUberHost(*url);
378 // Handle valid "chrome://chrome/foo" URLs so the reverse handler will
379 // be called.
380 if (ChromeWebUIControllerFactory::GetInstance()->UseWebUIForURL(
381 browser_context, chrome_url))
382 return true;
385 if (!ChromeWebUIControllerFactory::GetInstance()->UseWebUIForURL(
386 browser_context, *url))
387 return false;
389 #if defined(OS_CHROMEOS)
390 // Special case : in ChromeOS in Guest mode bookmarks and history are
391 // disabled for security reasons. New tab page explains the reasons, so
392 // we redirect user to new tab page.
393 if (user_manager::UserManager::Get()->IsLoggedInAsGuest()) {
394 if (url->SchemeIs(content::kChromeUIScheme) &&
395 (url->DomainIs(chrome::kChromeUIBookmarksHost) ||
396 url->DomainIs(chrome::kChromeUIHistoryHost))) {
397 // Rewrite with new tab URL
398 *url = GURL(chrome::kChromeUINewTabURL);
401 #endif
403 return true;
406 // Reverse URL handler for Web UI. Maps "chrome://chrome/foo/" to
407 // "chrome://foo/".
408 bool HandleWebUIReverse(GURL* url, content::BrowserContext* browser_context) {
409 if (!url->is_valid() || !url->SchemeIs(content::kChromeUIScheme))
410 return false;
412 return RemoveUberHost(url);
415 bool CertMatchesFilter(const net::X509Certificate& cert,
416 const base::DictionaryValue& filter) {
417 // TODO(markusheintz): This is the minimal required filter implementation.
418 // Implement a better matcher.
420 // An empty filter matches any client certificate since no requirements are
421 // specified at all.
422 if (filter.empty())
423 return true;
425 std::string common_name;
426 if (filter.GetString("ISSUER.CN", &common_name) &&
427 (cert.issuer().common_name == common_name)) {
428 return true;
430 return false;
433 #if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
434 breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost(
435 const std::string& process_type) {
436 base::FilePath dumps_path;
437 PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path);
439 ANNOTATE_SCOPED_MEMORY_LEAK;
440 bool upload = (getenv(env_vars::kHeadless) == NULL);
441 breakpad::CrashHandlerHostLinux* crash_handler =
442 new breakpad::CrashHandlerHostLinux(process_type, dumps_path, upload);
443 crash_handler->StartUploaderThread();
444 return crash_handler;
448 int GetCrashSignalFD(const CommandLine& command_line) {
449 // Extensions have the same process type as renderers.
450 if (command_line.HasSwitch(extensions::switches::kExtensionProcess)) {
451 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
452 if (!crash_handler)
453 crash_handler = CreateCrashHandlerHost("extension");
454 return crash_handler->GetDeathSignalSocket();
457 std::string process_type =
458 command_line.GetSwitchValueASCII(switches::kProcessType);
460 if (process_type == switches::kRendererProcess) {
461 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
462 if (!crash_handler)
463 crash_handler = CreateCrashHandlerHost(process_type);
464 return crash_handler->GetDeathSignalSocket();
467 if (process_type == switches::kPluginProcess) {
468 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
469 if (!crash_handler)
470 crash_handler = CreateCrashHandlerHost(process_type);
471 return crash_handler->GetDeathSignalSocket();
474 if (process_type == switches::kPpapiPluginProcess) {
475 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
476 if (!crash_handler)
477 crash_handler = CreateCrashHandlerHost(process_type);
478 return crash_handler->GetDeathSignalSocket();
481 if (process_type == switches::kGpuProcess) {
482 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
483 if (!crash_handler)
484 crash_handler = CreateCrashHandlerHost(process_type);
485 return crash_handler->GetDeathSignalSocket();
488 return -1;
490 #endif // defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
492 #if !defined(OS_CHROMEOS)
493 GURL GetEffectiveURLForSignin(const GURL& url) {
494 CHECK(SigninManager::IsWebBasedSigninFlowURL(url));
496 GURL effective_url(SigninManager::kChromeSigninEffectiveSite);
497 // Copy the path because the argument to SetPathStr must outlive
498 // the Replacements object.
499 const std::string path_copy(url.path());
500 GURL::Replacements replacements;
501 replacements.SetPathStr(path_copy);
502 effective_url = effective_url.ReplaceComponents(replacements);
503 return effective_url;
505 #endif
507 void SetApplicationLocaleOnIOThread(const std::string& locale) {
508 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
509 g_io_thread_application_locale.Get() = locale;
512 void HandleBlockedPopupOnUIThread(const BlockedWindowParams& params) {
513 WebContents* tab = tab_util::GetWebContentsByID(params.render_process_id(),
514 params.opener_id());
515 if (!tab)
516 return;
518 prerender::PrerenderContents* prerender_contents =
519 prerender::PrerenderContents::FromWebContents(tab);
520 if (prerender_contents) {
521 prerender_contents->Destroy(prerender::FINAL_STATUS_CREATE_NEW_WINDOW);
522 return;
525 PopupBlockerTabHelper* popup_helper =
526 PopupBlockerTabHelper::FromWebContents(tab);
527 if (!popup_helper)
528 return;
529 popup_helper->AddBlockedPopup(params);
532 #if defined(OS_ANDROID)
534 void HandleSingleTabModeBlockOnUIThread(const BlockedWindowParams& params) {
535 WebContents* web_contents =
536 tab_util::GetWebContentsByID(params.render_process_id(),
537 params.opener_id());
538 if (!web_contents)
539 return;
541 SingleTabModeTabHelper::FromWebContents(web_contents)->HandleOpenUrl(params);
544 float GetDeviceScaleAdjustment() {
545 static const float kMinFSM = 1.05f;
546 static const int kWidthForMinFSM = 320;
547 static const float kMaxFSM = 1.3f;
548 static const int kWidthForMaxFSM = 800;
550 gfx::DeviceDisplayInfo info;
551 int minWidth = info.GetSmallestDIPWidth();
553 if (minWidth <= kWidthForMinFSM)
554 return kMinFSM;
555 if (minWidth >= kWidthForMaxFSM)
556 return kMaxFSM;
558 // The font scale multiplier varies linearly between kMinFSM and kMaxFSM.
559 float ratio = static_cast<float>(minWidth - kWidthForMinFSM) /
560 (kWidthForMaxFSM - kWidthForMinFSM);
561 return ratio * (kMaxFSM - kMinFSM) + kMinFSM;
564 #endif // defined(OS_ANDROID)
566 #if defined(ENABLE_EXTENSIONS)
567 // By default, JavaScript and images are enabled in guest content.
568 void GetGuestViewDefaultContentSettingRules(
569 bool incognito,
570 RendererContentSettingRules* rules) {
571 rules->image_rules.push_back(
572 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
573 ContentSettingsPattern::Wildcard(),
574 CONTENT_SETTING_ALLOW,
575 std::string(),
576 incognito));
578 rules->script_rules.push_back(
579 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
580 ContentSettingsPattern::Wildcard(),
581 CONTENT_SETTING_ALLOW,
582 std::string(),
583 incognito));
585 #endif // defined(ENALBE_EXTENSIONS)
587 } // namespace
589 namespace chrome {
591 ChromeContentBrowserClient::ChromeContentBrowserClient()
592 : prerender_tracker_(NULL),
593 weak_factory_(this) {
594 #if defined(ENABLE_PLUGINS)
595 for (size_t i = 0; i < arraysize(kPredefinedAllowedDevChannelOrigins); ++i)
596 allowed_dev_channel_origins_.insert(kPredefinedAllowedDevChannelOrigins[i]);
597 for (size_t i = 0; i < arraysize(kPredefinedAllowedFileHandleOrigins); ++i)
598 allowed_file_handle_origins_.insert(kPredefinedAllowedFileHandleOrigins[i]);
599 for (size_t i = 0; i < arraysize(kPredefinedAllowedSocketOrigins); ++i)
600 allowed_socket_origins_.insert(kPredefinedAllowedSocketOrigins[i]);
601 #endif
603 #if !defined(OS_ANDROID)
604 TtsExtensionEngine* tts_extension_engine = TtsExtensionEngine::GetInstance();
605 TtsController::GetInstance()->SetTtsEngineDelegate(tts_extension_engine);
606 #endif
608 #if defined(ENABLE_EXTENSIONS)
609 extra_parts_.push_back(new ChromeContentBrowserClientExtensionsPart);
610 #endif
613 ChromeContentBrowserClient::~ChromeContentBrowserClient() {
614 for (int i = static_cast<int>(extra_parts_.size()) - 1; i >= 0; --i)
615 delete extra_parts_[i];
616 extra_parts_.clear();
619 // static
620 void ChromeContentBrowserClient::RegisterProfilePrefs(
621 user_prefs::PrefRegistrySyncable* registry) {
622 registry->RegisterBooleanPref(
623 prefs::kDisable3DAPIs,
624 false,
625 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
626 registry->RegisterBooleanPref(
627 prefs::kEnableHyperlinkAuditing,
628 true,
629 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
630 registry->RegisterListPref(
631 prefs::kEnableDeprecatedWebPlatformFeatures,
632 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
635 // static
636 void ChromeContentBrowserClient::SetApplicationLocale(
637 const std::string& locale) {
638 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
640 // This object is guaranteed to outlive all threads so we don't have to
641 // worry about the lack of refcounting and can just post as Unretained.
643 // The common case is that this function is called early in Chrome startup
644 // before any threads are created (it will also be called later if the user
645 // changes the pref). In this case, there will be no threads created and
646 // posting will fail. When there are no threads, we can just set the string
647 // without worrying about threadsafety.
648 if (!BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
649 base::Bind(&SetApplicationLocaleOnIOThread, locale))) {
650 g_io_thread_application_locale.Get() = locale;
654 content::BrowserMainParts* ChromeContentBrowserClient::CreateBrowserMainParts(
655 const content::MainFunctionParams& parameters) {
656 ChromeBrowserMainParts* main_parts;
657 // Construct the Main browser parts based on the OS type.
658 #if defined(OS_WIN)
659 main_parts = new ChromeBrowserMainPartsWin(parameters);
660 #elif defined(OS_MACOSX)
661 main_parts = new ChromeBrowserMainPartsMac(parameters);
662 #elif defined(OS_CHROMEOS)
663 main_parts = new chromeos::ChromeBrowserMainPartsChromeos(parameters);
664 #elif defined(OS_LINUX)
665 main_parts = new ChromeBrowserMainPartsLinux(parameters);
666 #elif defined(OS_ANDROID)
667 main_parts = new ChromeBrowserMainPartsAndroid(parameters);
668 #elif defined(OS_POSIX)
669 main_parts = new ChromeBrowserMainPartsPosix(parameters);
670 #else
671 NOTREACHED();
672 main_parts = new ChromeBrowserMainParts(parameters);
673 #endif
675 chrome::AddProfilesExtraParts(main_parts);
677 // Construct additional browser parts. Stages are called in the order in
678 // which they are added.
679 #if defined(TOOLKIT_VIEWS)
680 main_parts->AddParts(new ChromeBrowserMainExtraPartsViews());
681 #endif
683 #if defined(USE_ASH)
684 main_parts->AddParts(new ChromeBrowserMainExtraPartsAsh());
685 #endif
687 #if defined(USE_AURA)
688 main_parts->AddParts(new ChromeBrowserMainExtraPartsAura());
689 #endif
691 #if defined(USE_X11)
692 main_parts->AddParts(new ChromeBrowserMainExtraPartsX11());
693 #endif
695 chrome::AddMetricsExtraParts(main_parts);
697 return main_parts;
700 std::string ChromeContentBrowserClient::GetStoragePartitionIdForSite(
701 content::BrowserContext* browser_context,
702 const GURL& site) {
703 std::string partition_id;
705 // The partition ID for webview guest processes is the string value of its
706 // SiteInstance URL - "chrome-guest://app_id/persist?partition".
707 if (site.SchemeIs(content::kGuestScheme)) {
708 partition_id = site.spec();
709 } else if (site.GetOrigin().spec() == kChromeUIChromeSigninURL) {
710 // Chrome signin page has an embedded iframe of extension and web content,
711 // thus it must be isolated from other webUI pages.
712 partition_id = site.GetOrigin().spec();
715 DCHECK(IsValidStoragePartitionId(browser_context, partition_id));
716 return partition_id;
719 bool ChromeContentBrowserClient::IsValidStoragePartitionId(
720 content::BrowserContext* browser_context,
721 const std::string& partition_id) {
722 // The default ID is empty and is always valid.
723 if (partition_id.empty())
724 return true;
726 return GURL(partition_id).is_valid();
729 void ChromeContentBrowserClient::GetStoragePartitionConfigForSite(
730 content::BrowserContext* browser_context,
731 const GURL& site,
732 bool can_be_default,
733 std::string* partition_domain,
734 std::string* partition_name,
735 bool* in_memory) {
736 // Default to the browser-wide storage partition and override based on |site|
737 // below.
738 partition_domain->clear();
739 partition_name->clear();
740 *in_memory = false;
742 bool success = false;
743 #if defined(ENABLE_EXTENSIONS)
744 success = extensions::WebViewGuest::GetGuestPartitionConfigForSite(
745 site, partition_domain, partition_name, in_memory);
747 if (!success && site.SchemeIs(extensions::kExtensionScheme)) {
748 // If |can_be_default| is false, the caller is stating that the |site|
749 // should be parsed as if it had isolated storage. In particular it is
750 // important to NOT check ExtensionService for the is_storage_isolated()
751 // attribute because this code path is run during Extension uninstall
752 // to do cleanup after the Extension has already been unloaded from the
753 // ExtensionService.
754 bool is_isolated = !can_be_default;
755 if (can_be_default) {
756 if (extensions::util::SiteHasIsolatedStorage(site, browser_context))
757 is_isolated = true;
760 if (is_isolated) {
761 CHECK(site.has_host());
762 // For extensions with isolated storage, the the host of the |site| is
763 // the |partition_domain|. The |in_memory| and |partition_name| are only
764 // used in guest schemes so they are cleared here.
765 *partition_domain = site.host();
766 *in_memory = false;
767 partition_name->clear();
769 success = true;
771 #endif
773 if (!success && (site.GetOrigin().spec() == kChromeUIChromeSigninURL)) {
774 // Chrome signin page has an embedded iframe of extension and web content,
775 // thus it must be isolated from other webUI pages.
776 *partition_domain = chrome::kChromeUIChromeSigninHost;
779 // Assert that if |can_be_default| is false, the code above must have found a
780 // non-default partition. If this fails, the caller has a serious logic
781 // error about which StoragePartition they expect to be in and it is not
782 // safe to continue.
783 CHECK(can_be_default || !partition_domain->empty());
786 content::WebContentsViewDelegate*
787 ChromeContentBrowserClient::GetWebContentsViewDelegate(
788 content::WebContents* web_contents) {
789 return chrome::CreateWebContentsViewDelegate(web_contents);
792 void ChromeContentBrowserClient::RenderProcessWillLaunch(
793 content::RenderProcessHost* host) {
794 int id = host->GetID();
795 Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext());
796 net::URLRequestContextGetter* context =
797 profile->GetRequestContextForRenderProcess(id);
799 host->AddFilter(new ChromeRenderMessageFilter(id, profile));
800 #if defined(ENABLE_PLUGINS)
801 host->AddFilter(new PluginInfoMessageFilter(id, profile));
802 #endif
803 host->AddFilter(new cast::CastTransportHostFilter);
804 #if defined(ENABLE_PRINTING)
805 host->AddFilter(new printing::PrintingMessageFilter(id, profile));
806 #endif
807 host->AddFilter(new SearchProviderInstallStateMessageFilter(id, profile));
808 #if defined(ENABLE_SPELLCHECK)
809 host->AddFilter(new SpellCheckMessageFilter(id));
810 #endif
811 #if defined(OS_MACOSX)
812 host->AddFilter(new SpellCheckMessageFilterMac(id));
813 #endif
814 host->AddFilter(new ChromeNetBenchmarkingMessageFilter(profile, context));
815 host->AddFilter(new prerender::PrerenderMessageFilter(id, profile));
816 host->AddFilter(new TtsMessageFilter(id, host->GetBrowserContext()));
817 #if defined(ENABLE_WEBRTC)
818 WebRtcLoggingHandlerHost* webrtc_logging_handler_host =
819 new WebRtcLoggingHandlerHost(profile);
820 host->SetWebRtcLogMessageCallback(base::Bind(
821 &WebRtcLoggingHandlerHost::LogMessage, webrtc_logging_handler_host));
822 host->AddFilter(webrtc_logging_handler_host);
823 host->SetUserData(host, new base::UserDataAdapter<WebRtcLoggingHandlerHost>(
824 webrtc_logging_handler_host));
825 #endif
826 #if !defined(DISABLE_NACL)
827 host->AddFilter(new nacl::NaClHostMessageFilter(
828 id, profile->IsOffTheRecord(),
829 profile->GetPath(),
830 context));
831 #endif
832 #if defined(OS_ANDROID)
833 host->AddFilter(new cdm::CdmMessageFilterAndroid());
834 #endif
835 if (switches::IsEnableAccountConsistency())
836 host->AddFilter(new PrincipalsMessageFilter(id));
838 host->Send(new ChromeViewMsg_SetIsIncognitoProcess(
839 profile->IsOffTheRecord()));
841 for (size_t i = 0; i < extra_parts_.size(); ++i)
842 extra_parts_[i]->RenderProcessWillLaunch(host);
844 RendererContentSettingRules rules;
845 if (host->IsIsolatedGuest()) {
846 #if defined(ENABLE_EXTENSIONS)
847 GetGuestViewDefaultContentSettingRules(profile->IsOffTheRecord(), &rules);
848 #else
849 NOTREACHED();
850 #endif
851 } else {
852 GetRendererContentSettingRules(
853 profile->GetHostContentSettingsMap(), &rules);
855 host->Send(new ChromeViewMsg_SetContentSettingRules(rules));
858 GURL ChromeContentBrowserClient::GetEffectiveURL(
859 content::BrowserContext* browser_context, const GURL& url) {
860 Profile* profile = Profile::FromBrowserContext(browser_context);
861 if (!profile)
862 return url;
864 // If the input |url| should be assigned to the Instant renderer, make its
865 // effective URL distinct from other URLs on the search provider's domain.
866 if (chrome::ShouldAssignURLToInstantRenderer(url, profile))
867 return chrome::GetEffectiveURLForInstant(url, profile);
869 #if !defined(OS_CHROMEOS)
870 // If the input |url| should be assigned to the Signin renderer, make its
871 // effective URL distinct from other URLs on the signin service's domain.
872 // Note that the signin renderer will be allowed to sign the user in to
873 // Chrome.
874 if (SigninManager::IsWebBasedSigninFlowURL(url))
875 return GetEffectiveURLForSignin(url);
876 #endif
878 #if defined(ENABLE_EXTENSIONS)
879 return ChromeContentBrowserClientExtensionsPart::GetEffectiveURL(
880 profile, url);
881 #else
882 return url;
883 #endif
886 bool ChromeContentBrowserClient::ShouldUseProcessPerSite(
887 content::BrowserContext* browser_context, const GURL& effective_url) {
888 // Non-extension, non-Instant URLs should generally use
889 // process-per-site-instance. Because we expect to use the effective URL,
890 // URLs for hosted apps (apart from bookmark apps) should have an extension
891 // scheme by now.
893 Profile* profile = Profile::FromBrowserContext(browser_context);
894 if (!profile)
895 return false;
897 if (chrome::ShouldUseProcessPerSiteForInstantURL(effective_url, profile))
898 return true;
900 #if !defined(OS_CHROMEOS)
901 if (SigninManager::IsWebBasedSigninFlowURL(effective_url))
902 return true;
903 #endif
905 #if defined(ENABLE_EXTENSIONS)
906 return ChromeContentBrowserClientExtensionsPart::ShouldUseProcessPerSite(
907 profile, effective_url);
908 #else
909 return false;
910 #endif
913 // These are treated as WebUI schemes but do not get WebUI bindings. Also,
914 // view-source is allowed for these schemes.
915 void ChromeContentBrowserClient::GetAdditionalWebUISchemes(
916 std::vector<std::string>* additional_schemes) {
917 additional_schemes->push_back(chrome::kChromeSearchScheme);
918 additional_schemes->push_back(dom_distiller::kDomDistillerScheme);
921 void ChromeContentBrowserClient::GetAdditionalWebUIHostsToIgnoreParititionCheck(
922 std::vector<std::string>* hosts) {
923 hosts->push_back(chrome::kChromeUIExtensionIconHost);
924 hosts->push_back(chrome::kChromeUIFaviconHost);
925 hosts->push_back(chrome::kChromeUIThemeHost);
926 hosts->push_back(chrome::kChromeUIThumbnailHost);
927 hosts->push_back(chrome::kChromeUIThumbnailHost2);
928 hosts->push_back(chrome::kChromeUIThumbnailListHost);
931 net::URLRequestContextGetter*
932 ChromeContentBrowserClient::CreateRequestContext(
933 content::BrowserContext* browser_context,
934 content::ProtocolHandlerMap* protocol_handlers,
935 content::URLRequestInterceptorScopedVector request_interceptors) {
936 Profile* profile = Profile::FromBrowserContext(browser_context);
937 return profile->CreateRequestContext(protocol_handlers,
938 request_interceptors.Pass());
941 net::URLRequestContextGetter*
942 ChromeContentBrowserClient::CreateRequestContextForStoragePartition(
943 content::BrowserContext* browser_context,
944 const base::FilePath& partition_path,
945 bool in_memory,
946 content::ProtocolHandlerMap* protocol_handlers,
947 content::URLRequestInterceptorScopedVector request_interceptors) {
948 Profile* profile = Profile::FromBrowserContext(browser_context);
949 return profile->CreateRequestContextForStoragePartition(
950 partition_path,
951 in_memory,
952 protocol_handlers,
953 request_interceptors.Pass());
956 bool ChromeContentBrowserClient::IsHandledURL(const GURL& url) {
957 return ProfileIOData::IsHandledURL(url);
960 bool ChromeContentBrowserClient::CanCommitURL(
961 content::RenderProcessHost* process_host,
962 const GURL& url) {
963 #if defined(ENABLE_EXTENSIONS)
964 return ChromeContentBrowserClientExtensionsPart::CanCommitURL(
965 process_host, url);
966 #else
967 return true;
968 #endif
971 bool ChromeContentBrowserClient::ShouldAllowOpenURL(
972 content::SiteInstance* site_instance, const GURL& url) {
973 GURL from_url = site_instance->GetSiteURL();
975 #if defined(ENABLE_EXTENSIONS)
976 bool result;
977 if (ChromeContentBrowserClientExtensionsPart::ShouldAllowOpenURL(
978 site_instance, from_url, url, &result))
979 return result;
980 #endif
982 // Do not allow chrome://chrome-signin navigate to other chrome:// URLs, since
983 // the signin page may host untrusted web content.
984 if (from_url.GetOrigin().spec() == chrome::kChromeUIChromeSigninURL &&
985 url.SchemeIs(content::kChromeUIScheme) &&
986 url.host() != chrome::kChromeUIChromeSigninHost) {
987 VLOG(1) << "Blocked navigation to " << url.spec() << " from "
988 << chrome::kChromeUIChromeSigninURL;
989 return false;
992 return true;
995 bool ChromeContentBrowserClient::IsSuitableHost(
996 content::RenderProcessHost* process_host,
997 const GURL& site_url) {
998 Profile* profile =
999 Profile::FromBrowserContext(process_host->GetBrowserContext());
1000 // This may be NULL during tests. In that case, just assume any site can
1001 // share any host.
1002 if (!profile)
1003 return true;
1005 // Instant URLs should only be in the instant process and instant process
1006 // should only have Instant URLs.
1007 InstantService* instant_service =
1008 InstantServiceFactory::GetForProfile(profile);
1009 if (instant_service) {
1010 bool is_instant_process = instant_service->IsInstantProcess(
1011 process_host->GetID());
1012 bool should_be_in_instant_process =
1013 chrome::ShouldAssignURLToInstantRenderer(site_url, profile);
1014 if (is_instant_process || should_be_in_instant_process)
1015 return is_instant_process && should_be_in_instant_process;
1018 #if !defined(OS_CHROMEOS)
1019 SigninClient* signin_client =
1020 ChromeSigninClientFactory::GetForProfile(profile);
1021 if (signin_client && signin_client->IsSigninProcess(process_host->GetID()))
1022 return SigninManager::IsWebBasedSigninFlowURL(site_url);
1023 #endif
1025 #if defined(ENABLE_EXTENSIONS)
1026 return ChromeContentBrowserClientExtensionsPart::IsSuitableHost(
1027 profile, process_host, site_url);
1028 #else
1029 return true;
1030 #endif
1033 bool ChromeContentBrowserClient::MayReuseHost(
1034 content::RenderProcessHost* process_host) {
1035 // If there is currently a prerender in progress for the host provided,
1036 // it may not be shared. We require prerenders to be by themselves in a
1037 // separate process, so that we can monitor their resource usage, and so that
1038 // we can track the cookies that they change.
1039 Profile* profile = Profile::FromBrowserContext(
1040 process_host->GetBrowserContext());
1041 prerender::PrerenderManager* prerender_manager =
1042 prerender::PrerenderManagerFactory::GetForProfile(profile);
1043 if (prerender_manager &&
1044 !prerender_manager->MayReuseProcessHost(process_host)) {
1045 return false;
1048 return true;
1051 bool ChromeContentBrowserClient::ShouldTryToUseExistingProcessHost(
1052 content::BrowserContext* browser_context, const GURL& url) {
1053 // It has to be a valid URL for us to check for an extension.
1054 if (!url.is_valid())
1055 return false;
1057 #if defined(ENABLE_EXTENSIONS)
1058 Profile* profile = Profile::FromBrowserContext(browser_context);
1059 return ChromeContentBrowserClientExtensionsPart::
1060 ShouldTryToUseExistingProcessHost(
1061 profile, url);
1062 #else
1063 return false;
1064 #endif
1067 void ChromeContentBrowserClient::SiteInstanceGotProcess(
1068 SiteInstance* site_instance) {
1069 CHECK(site_instance->HasProcess());
1071 Profile* profile = Profile::FromBrowserContext(
1072 site_instance->GetBrowserContext());
1073 if (!profile)
1074 return;
1076 // Remember the ID of the Instant process to signal the renderer process
1077 // on startup in |AppendExtraCommandLineSwitches| below.
1078 if (chrome::ShouldAssignURLToInstantRenderer(
1079 site_instance->GetSiteURL(), profile)) {
1080 InstantService* instant_service =
1081 InstantServiceFactory::GetForProfile(profile);
1082 if (instant_service)
1083 instant_service->AddInstantProcess(site_instance->GetProcess()->GetID());
1086 #if !defined(OS_CHROMEOS)
1087 // We only expect there to be one signin process as we use process-per-site
1088 // for signin URLs. The signin process will be cleared from SigninManager
1089 // when the renderer is destroyed.
1090 if (SigninManager::IsWebBasedSigninFlowURL(site_instance->GetSiteURL())) {
1091 SigninClient* signin_client =
1092 ChromeSigninClientFactory::GetForProfile(profile);
1093 if (signin_client)
1094 signin_client->SetSigninProcess(site_instance->GetProcess()->GetID());
1095 #if defined(ENABLE_EXTENSIONS)
1096 ChromeContentBrowserClientExtensionsPart::SetSigninProcess(site_instance);
1097 #endif
1099 #endif
1101 for (size_t i = 0; i < extra_parts_.size(); ++i)
1102 extra_parts_[i]->SiteInstanceGotProcess(site_instance);
1105 void ChromeContentBrowserClient::SiteInstanceDeleting(
1106 SiteInstance* site_instance) {
1107 if (!site_instance->HasProcess())
1108 return;
1110 for (size_t i = 0; i < extra_parts_.size(); ++i)
1111 extra_parts_[i]->SiteInstanceDeleting(site_instance);
1114 bool ChromeContentBrowserClient::ShouldSwapBrowsingInstancesForNavigation(
1115 SiteInstance* site_instance,
1116 const GURL& current_url,
1117 const GURL& new_url) {
1118 #if defined(ENABLE_EXTENSIONS)
1119 return ChromeContentBrowserClientExtensionsPart::
1120 ShouldSwapBrowsingInstancesForNavigation(
1121 site_instance, current_url, new_url);
1122 #else
1123 return false;
1124 #endif
1127 bool ChromeContentBrowserClient::ShouldSwapProcessesForRedirect(
1128 content::ResourceContext* resource_context, const GURL& current_url,
1129 const GURL& new_url) {
1130 #if defined(ENABLE_EXTENSIONS)
1131 return ChromeContentBrowserClientExtensionsPart::
1132 ShouldSwapProcessesForRedirect(resource_context, current_url, new_url);
1133 #else
1134 return false;
1135 #endif
1138 bool ChromeContentBrowserClient::ShouldAssignSiteForURL(const GURL& url) {
1139 return !url.SchemeIs(chrome::kChromeNativeScheme);
1142 std::string ChromeContentBrowserClient::GetCanonicalEncodingNameByAliasName(
1143 const std::string& alias_name) {
1144 return CharacterEncoding::GetCanonicalEncodingNameByAliasName(alias_name);
1147 namespace {
1149 bool IsAutoReloadEnabled() {
1150 // Fetch the field trial, even though we don't use it. Calling FindFullName()
1151 // causes the field-trial mechanism to report which group we're in, which
1152 // might reflect a hard disable or hard enable via flag, both of which have
1153 // their own field trial groups. This lets us know what percentage of users
1154 // manually enable or disable auto-reload.
1155 std::string group = base::FieldTrialList::FindFullName(
1156 "AutoReloadExperiment");
1157 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
1158 if (browser_command_line.HasSwitch(switches::kEnableOfflineAutoReload))
1159 return true;
1160 if (browser_command_line.HasSwitch(switches::kDisableOfflineAutoReload))
1161 return false;
1162 return true;
1165 bool IsAutoReloadVisibleOnlyEnabled() {
1166 // See the block comment in IsAutoReloadEnabled().
1167 std::string group = base::FieldTrialList::FindFullName(
1168 "AutoReloadVisibleOnlyExperiment");
1169 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
1170 if (browser_command_line.HasSwitch(
1171 switches::kEnableOfflineAutoReloadVisibleOnly)) {
1172 return true;
1174 if (browser_command_line.HasSwitch(
1175 switches::kDisableOfflineAutoReloadVisibleOnly)) {
1176 return false;
1178 return true;
1181 } // namespace
1183 void ChromeContentBrowserClient::AppendExtraCommandLineSwitches(
1184 CommandLine* command_line, int child_process_id) {
1185 #if defined(OS_POSIX)
1186 if (breakpad::IsCrashReporterEnabled()) {
1187 scoped_ptr<metrics::ClientInfo> client_info =
1188 GoogleUpdateSettings::LoadMetricsClientInfo();
1189 command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
1190 client_info ? client_info->client_id
1191 : std::string());
1193 #endif // defined(OS_POSIX)
1195 if (logging::DialogsAreSuppressed())
1196 command_line->AppendSwitch(switches::kNoErrorDialogs);
1198 std::string process_type =
1199 command_line->GetSwitchValueASCII(switches::kProcessType);
1200 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
1202 static const char* const kCommonSwitchNames[] = {
1203 switches::kUserAgent,
1204 switches::kUserDataDir, // Make logs go to the right file.
1206 command_line->CopySwitchesFrom(browser_command_line, kCommonSwitchNames,
1207 arraysize(kCommonSwitchNames));
1209 #if defined(ENABLE_IPC_FUZZER)
1210 static const char* const kIpcFuzzerSwitches[] = {
1211 switches::kIpcFuzzerTestcase,
1213 command_line->CopySwitchesFrom(browser_command_line, kIpcFuzzerSwitches,
1214 arraysize(kIpcFuzzerSwitches));
1215 #endif
1217 #if defined(OS_CHROMEOS)
1218 // On Chrome OS need to pass primary user homedir (in multi-profiles session).
1219 base::FilePath homedir;
1220 PathService::Get(base::DIR_HOME, &homedir);
1221 command_line->AppendSwitchASCII(chromeos::switches::kHomedir,
1222 homedir.value().c_str());
1223 #endif
1225 if (process_type == switches::kRendererProcess) {
1226 content::RenderProcessHost* process =
1227 content::RenderProcessHost::FromID(child_process_id);
1228 Profile* profile =
1229 process ? Profile::FromBrowserContext(process->GetBrowserContext())
1230 : NULL;
1231 for (size_t i = 0; i < extra_parts_.size(); ++i) {
1232 extra_parts_[i]->AppendExtraRendererCommandLineSwitches(
1233 command_line, process, profile);
1236 #if defined(OS_CHROMEOS)
1237 const std::string& login_profile =
1238 browser_command_line.GetSwitchValueASCII(
1239 chromeos::switches::kLoginProfile);
1240 if (!login_profile.empty())
1241 command_line->AppendSwitchASCII(
1242 chromeos::switches::kLoginProfile, login_profile);
1243 #endif
1245 #if defined(ENABLE_WEBRTC)
1246 MaybeCopyDisableWebRtcEncryptionSwitch(command_line,
1247 browser_command_line,
1248 VersionInfo::GetChannel());
1249 #endif
1251 if (process) {
1252 PrefService* prefs = profile->GetPrefs();
1253 // Currently this pref is only registered if applied via a policy.
1254 if (prefs->HasPrefPath(prefs::kDisable3DAPIs) &&
1255 prefs->GetBoolean(prefs::kDisable3DAPIs)) {
1256 // Turn this policy into a command line switch.
1257 command_line->AppendSwitch(switches::kDisable3DAPIs);
1260 const base::ListValue* switches =
1261 prefs->GetList(prefs::kEnableDeprecatedWebPlatformFeatures);
1262 if (switches) {
1263 // Enable any deprecated features that have been re-enabled by policy.
1264 for (base::ListValue::const_iterator it = switches->begin();
1265 it != switches->end(); ++it) {
1266 std::string switch_to_enable;
1267 if ((*it)->GetAsString(&switch_to_enable))
1268 command_line->AppendSwitch(switch_to_enable);
1272 // Disable client-side phishing detection in the renderer if it is
1273 // disabled in the Profile preferences or the browser process.
1274 if (!prefs->GetBoolean(prefs::kSafeBrowsingEnabled) ||
1275 !g_browser_process->safe_browsing_detection_service()) {
1276 command_line->AppendSwitch(
1277 switches::kDisableClientSidePhishingDetection);
1280 InstantService* instant_service =
1281 InstantServiceFactory::GetForProfile(profile);
1282 if (instant_service &&
1283 instant_service->IsInstantProcess(process->GetID()))
1284 command_line->AppendSwitch(switches::kInstantProcess);
1286 #if !defined(OS_CHROMEOS)
1287 SigninClient* signin_client =
1288 ChromeSigninClientFactory::GetForProfile(profile);
1289 if (signin_client && signin_client->IsSigninProcess(process->GetID()))
1290 command_line->AppendSwitch(switches::kSigninProcess);
1291 #endif
1294 if (IsAutoReloadEnabled())
1295 command_line->AppendSwitch(switches::kEnableOfflineAutoReload);
1296 if (IsAutoReloadVisibleOnlyEnabled()) {
1297 command_line->AppendSwitch(
1298 switches::kEnableOfflineAutoReloadVisibleOnly);
1302 // Enable load stale cache if this session is in the field trial or
1303 // the user explicitly enabled it. Note that as far as the renderer
1304 // is concerned, the feature is enabled if-and-only-if the
1305 // kEnableOfflineLoadStaleCache flag is on the command line;
1306 // the yes/no/default behavior is only at the browser command line
1307 // level.
1309 // Command line switches override
1310 if (browser_command_line.HasSwitch(
1311 switches::kEnableOfflineLoadStaleCache)) {
1312 command_line->AppendSwitch(switches::kEnableOfflineLoadStaleCache);
1313 } else if (!browser_command_line.HasSwitch(
1314 switches::kDisableOfflineLoadStaleCache)) {
1315 std::string group =
1316 base::FieldTrialList::FindFullName("LoadStaleCacheExperiment");
1318 if (group == "Enabled")
1319 command_line->AppendSwitch(switches::kEnableOfflineLoadStaleCache);
1323 // Please keep this in alphabetical order.
1324 static const char* const kSwitchNames[] = {
1325 autofill::switches::kDisableIgnoreAutocompleteOff,
1326 autofill::switches::kDisablePasswordGeneration,
1327 autofill::switches::kEnablePasswordGeneration,
1328 autofill::switches::kLocalHeuristicsOnlyForPasswordGeneration,
1329 extensions::switches::kAllowHTTPBackgroundPage,
1330 extensions::switches::kAllowLegacyExtensionManifests,
1331 extensions::switches::kEnableAppView,
1332 extensions::switches::kEnableEmbeddedExtensionOptions,
1333 extensions::switches::kEnableExperimentalExtensionApis,
1334 extensions::switches::kEnableScriptsRequireAction,
1335 extensions::switches::kExtensionsOnChromeURLs,
1336 extensions::switches::kWhitelistedExtensionID,
1337 switches::kAppsCheckoutURL,
1338 switches::kAppsGalleryURL,
1339 switches::kCloudPrintURL,
1340 switches::kCloudPrintXmppEndpoint,
1341 switches::kDisableBundledPpapiFlash,
1342 switches::kEnableAppWindowControls,
1343 switches::kEnableBenchmarking,
1344 switches::kEnableNaCl,
1345 #if !defined(DISABLE_NACL)
1346 switches::kEnableNaClDebug,
1347 switches::kEnableNaClNonSfiMode,
1348 #endif
1349 switches::kEnableNetBenchmarking,
1350 switches::kEnableShowModalDialog,
1351 switches::kEnableStreamlinedHostedApps,
1352 switches::kEnableWebBasedSignin,
1353 switches::kMessageLoopHistogrammer,
1354 switches::kOutOfProcessPdf,
1355 switches::kPlaybackMode,
1356 switches::kPpapiFlashArgs,
1357 switches::kPpapiFlashPath,
1358 switches::kPpapiFlashVersion,
1359 switches::kProfilingAtStart,
1360 switches::kProfilingFile,
1361 switches::kProfilingFlush,
1362 switches::kRecordMode,
1363 translate::switches::kTranslateSecurityOrigin,
1366 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
1367 arraysize(kSwitchNames));
1368 } else if (process_type == switches::kUtilityProcess) {
1369 static const char* const kSwitchNames[] = {
1370 extensions::switches::kAllowHTTPBackgroundPage,
1371 extensions::switches::kEnableExperimentalExtensionApis,
1372 extensions::switches::kExtensionsOnChromeURLs,
1373 extensions::switches::kWhitelistedExtensionID,
1376 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
1377 arraysize(kSwitchNames));
1378 } else if (process_type == switches::kPluginProcess) {
1379 #if defined(OS_CHROMEOS)
1380 static const char* const kSwitchNames[] = {
1381 chromeos::switches::kLoginProfile,
1384 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
1385 arraysize(kSwitchNames));
1386 #endif
1387 } else if (process_type == switches::kZygoteProcess) {
1388 static const char* const kSwitchNames[] = {
1389 // Load (in-process) Pepper plugins in-process in the zygote pre-sandbox.
1390 switches::kDisableBundledPpapiFlash,
1391 #if !defined(DISABLE_NACL)
1392 switches::kEnableNaClNonSfiMode,
1393 switches::kNaClDangerousNoSandboxNonSfi,
1394 #endif
1395 switches::kPpapiFlashPath,
1396 switches::kPpapiFlashVersion,
1399 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
1400 arraysize(kSwitchNames));
1401 } else if (process_type == switches::kGpuProcess) {
1402 // If --ignore-gpu-blacklist is passed in, don't send in crash reports
1403 // because GPU is expected to be unreliable.
1404 if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) &&
1405 !command_line->HasSwitch(switches::kDisableBreakpad))
1406 command_line->AppendSwitch(switches::kDisableBreakpad);
1409 // The command line switch kEnableBenchmarking needs to be specified along
1410 // with the kEnableStatsTable switch to ensure that the stats table global
1411 // is initialized correctly.
1412 if (command_line->HasSwitch(switches::kEnableBenchmarking))
1413 DCHECK(command_line->HasSwitch(switches::kEnableStatsTable));
1416 std::string ChromeContentBrowserClient::GetApplicationLocale() {
1417 if (BrowserThread::CurrentlyOn(BrowserThread::IO))
1418 return g_io_thread_application_locale.Get();
1419 return g_browser_process->GetApplicationLocale();
1422 std::string ChromeContentBrowserClient::GetAcceptLangs(
1423 content::BrowserContext* context) {
1424 Profile* profile = Profile::FromBrowserContext(context);
1425 return profile->GetPrefs()->GetString(prefs::kAcceptLanguages);
1428 const gfx::ImageSkia* ChromeContentBrowserClient::GetDefaultFavicon() {
1429 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
1430 return rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON).ToImageSkia();
1433 bool ChromeContentBrowserClient::AllowAppCache(
1434 const GURL& manifest_url,
1435 const GURL& first_party,
1436 content::ResourceContext* context) {
1437 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1438 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
1439 return io_data->GetCookieSettings()->
1440 IsSettingCookieAllowed(manifest_url, first_party);
1443 bool ChromeContentBrowserClient::AllowGetCookie(
1444 const GURL& url,
1445 const GURL& first_party,
1446 const net::CookieList& cookie_list,
1447 content::ResourceContext* context,
1448 int render_process_id,
1449 int render_frame_id) {
1450 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1451 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
1452 bool allow = io_data->GetCookieSettings()->
1453 IsReadingCookieAllowed(url, first_party);
1455 BrowserThread::PostTask(
1456 BrowserThread::UI, FROM_HERE,
1457 base::Bind(&TabSpecificContentSettings::CookiesRead, render_process_id,
1458 render_frame_id, url, first_party, cookie_list, !allow, true));
1459 return allow;
1462 bool ChromeContentBrowserClient::AllowSetCookie(
1463 const GURL& url,
1464 const GURL& first_party,
1465 const std::string& cookie_line,
1466 content::ResourceContext* context,
1467 int render_process_id,
1468 int render_frame_id,
1469 net::CookieOptions* options) {
1470 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1471 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
1472 CookieSettings* cookie_settings = io_data->GetCookieSettings();
1473 bool allow = cookie_settings->IsSettingCookieAllowed(url, first_party);
1475 if (prerender_tracker_) {
1476 prerender_tracker_->OnCookieChangedForURL(
1477 render_process_id,
1478 context->GetRequestContext()->cookie_store()->GetCookieMonster(),
1479 url);
1482 BrowserThread::PostTask(
1483 BrowserThread::UI, FROM_HERE,
1484 base::Bind(&TabSpecificContentSettings::CookieChanged, render_process_id,
1485 render_frame_id, url, first_party, cookie_line, *options,
1486 !allow));
1487 return allow;
1490 bool ChromeContentBrowserClient::AllowSaveLocalState(
1491 content::ResourceContext* context) {
1492 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1493 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
1494 CookieSettings* cookie_settings = io_data->GetCookieSettings();
1495 ContentSetting setting = cookie_settings->GetDefaultCookieSetting(NULL);
1497 // TODO(bauerb): Should we also disallow local state if the default is BLOCK?
1498 // Could we even support per-origin settings?
1499 return setting != CONTENT_SETTING_SESSION_ONLY;
1502 bool ChromeContentBrowserClient::AllowWorkerDatabase(
1503 const GURL& url,
1504 const base::string16& name,
1505 const base::string16& display_name,
1506 unsigned long estimated_size,
1507 content::ResourceContext* context,
1508 const std::vector<std::pair<int, int> >& render_frames) {
1509 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1510 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
1511 CookieSettings* cookie_settings = io_data->GetCookieSettings();
1512 bool allow = cookie_settings->IsSettingCookieAllowed(url, url);
1514 // Record access to database for potential display in UI.
1515 std::vector<std::pair<int, int> >::const_iterator i;
1516 for (i = render_frames.begin(); i != render_frames.end(); ++i) {
1517 BrowserThread::PostTask(
1518 BrowserThread::UI, FROM_HERE,
1519 base::Bind(&TabSpecificContentSettings::WebDatabaseAccessed,
1520 i->first, i->second, url, name, display_name, !allow));
1523 return allow;
1526 void ChromeContentBrowserClient::AllowWorkerFileSystem(
1527 const GURL& url,
1528 content::ResourceContext* context,
1529 const std::vector<std::pair<int, int> >& render_frames,
1530 base::Callback<void(bool)> callback) {
1531 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1532 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
1533 CookieSettings* cookie_settings = io_data->GetCookieSettings();
1534 bool allow = cookie_settings->IsSettingCookieAllowed(url, url);
1536 #if defined(ENABLE_EXTENSIONS)
1537 GuestPermissionRequestHelper(url, render_frames, callback, allow);
1538 #else
1539 FileSystemAccessed(url, render_frames, callback, allow);
1540 #endif
1543 #if defined(ENABLE_EXTENSIONS)
1544 void ChromeContentBrowserClient::GuestPermissionRequestHelper(
1545 const GURL& url,
1546 const std::vector<std::pair<int, int> >& render_frames,
1547 base::Callback<void(bool)> callback,
1548 bool allow) {
1549 DCHECK(BrowserThread:: CurrentlyOn(BrowserThread::IO));
1550 std::vector<std::pair<int, int> >::const_iterator i;
1551 std::map<int, int> process_map;
1552 std::map<int, int>::const_iterator it;
1553 bool has_web_view_guest = false;
1554 // Record access to file system for potential display in UI.
1555 for (i = render_frames.begin(); i != render_frames.end(); ++i) {
1556 if (process_map.find(i->first) != process_map.end())
1557 continue;
1559 process_map.insert(std::pair<int, int>(i->first, i->second));
1561 if (extensions::WebViewRendererState::GetInstance()->IsGuest(i->first))
1562 has_web_view_guest = true;
1564 if (!has_web_view_guest) {
1565 FileSystemAccessed(url, render_frames, callback, allow);
1566 return;
1568 DCHECK_EQ(1U, process_map.size());
1569 it = process_map.begin();
1570 BrowserThread::PostTask(
1571 BrowserThread::UI,
1572 FROM_HERE,
1573 base::Bind(&ChromeContentBrowserClient::
1574 RequestFileSystemPermissionOnUIThread,
1575 it->first,
1576 it->second,
1577 url,
1578 allow,
1579 base::Bind(&ChromeContentBrowserClient::FileSystemAccessed,
1580 weak_factory_.GetWeakPtr(),
1581 url,
1582 render_frames,
1583 callback)));
1586 void ChromeContentBrowserClient::RequestFileSystemPermissionOnUIThread(
1587 int render_process_id,
1588 int render_frame_id,
1589 const GURL& url,
1590 bool allowed_by_default,
1591 const base::Callback<void(bool)>& callback) {
1592 DCHECK(BrowserThread:: CurrentlyOn(BrowserThread::UI));
1593 extensions::WebViewPermissionHelper* web_view_permission_helper =
1594 extensions::WebViewPermissionHelper::FromFrameID(
1595 render_process_id, render_frame_id);
1596 web_view_permission_helper->RequestFileSystemPermission(url,
1597 allowed_by_default,
1598 callback);
1600 #endif
1602 void ChromeContentBrowserClient::FileSystemAccessed(
1603 const GURL& url,
1604 const std::vector<std::pair<int, int> >& render_frames,
1605 base::Callback<void(bool)> callback,
1606 bool allow) {
1607 // Record access to file system for potential display in UI.
1608 std::vector<std::pair<int, int> >::const_iterator i;
1609 for (i = render_frames.begin(); i != render_frames.end(); ++i) {
1610 BrowserThread::PostTask(
1611 BrowserThread::UI,
1612 FROM_HERE,
1613 base::Bind(&TabSpecificContentSettings::FileSystemAccessed,
1614 i->first, i->second, url, !allow));
1616 callback.Run(allow);
1619 bool ChromeContentBrowserClient::AllowWorkerIndexedDB(
1620 const GURL& url,
1621 const base::string16& name,
1622 content::ResourceContext* context,
1623 const std::vector<std::pair<int, int> >& render_frames) {
1624 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1625 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
1626 CookieSettings* cookie_settings = io_data->GetCookieSettings();
1627 bool allow = cookie_settings->IsSettingCookieAllowed(url, url);
1629 // Record access to IndexedDB for potential display in UI.
1630 std::vector<std::pair<int, int> >::const_iterator i;
1631 for (i = render_frames.begin(); i != render_frames.end(); ++i) {
1632 BrowserThread::PostTask(
1633 BrowserThread::UI, FROM_HERE,
1634 base::Bind(&TabSpecificContentSettings::IndexedDBAccessed,
1635 i->first, i->second, url, name, !allow));
1638 return allow;
1641 net::URLRequestContext*
1642 ChromeContentBrowserClient::OverrideRequestContextForURL(
1643 const GURL& url, content::ResourceContext* context) {
1644 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1645 #if defined(ENABLE_EXTENSIONS)
1646 if (url.SchemeIs(extensions::kExtensionScheme)) {
1647 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
1648 return io_data->extensions_request_context();
1650 #endif
1652 return NULL;
1655 QuotaPermissionContext*
1656 ChromeContentBrowserClient::CreateQuotaPermissionContext() {
1657 return new ChromeQuotaPermissionContext();
1660 void ChromeContentBrowserClient::AllowCertificateError(
1661 int render_process_id,
1662 int render_frame_id,
1663 int cert_error,
1664 const net::SSLInfo& ssl_info,
1665 const GURL& request_url,
1666 ResourceType resource_type,
1667 bool overridable,
1668 bool strict_enforcement,
1669 bool expired_previous_decision,
1670 const base::Callback<void(bool)>& callback,
1671 content::CertificateRequestResultType* result) {
1672 if (resource_type != content::RESOURCE_TYPE_MAIN_FRAME) {
1673 // A sub-resource has a certificate error. The user doesn't really
1674 // have a context for making the right decision, so block the
1675 // request hard, without an info bar to allow showing the insecure
1676 // content.
1677 *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY;
1678 return;
1681 // If the tab is being prerendered, cancel the prerender and the request.
1682 content::RenderFrameHost* render_frame_host =
1683 content::RenderFrameHost::FromID(render_process_id, render_frame_id);
1684 WebContents* tab = WebContents::FromRenderFrameHost(render_frame_host);
1685 if (!tab) {
1686 NOTREACHED();
1687 return;
1690 prerender::PrerenderContents* prerender_contents =
1691 prerender::PrerenderContents::FromWebContents(tab);
1692 if (prerender_contents) {
1693 prerender_contents->Destroy(prerender::FINAL_STATUS_SSL_ERROR);
1694 *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL;
1695 return;
1698 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
1699 CaptivePortalTabHelper* captive_portal_tab_helper =
1700 CaptivePortalTabHelper::FromWebContents(tab);
1701 if (captive_portal_tab_helper)
1702 captive_portal_tab_helper->OnSSLCertError(ssl_info);
1703 #endif
1705 // Otherwise, display an SSL blocking page. The interstitial page takes
1706 // ownership of ssl_blocking_page.
1707 int options_mask = 0;
1708 if (overridable)
1709 options_mask = SSLBlockingPage::OVERRIDABLE;
1710 if (strict_enforcement)
1711 options_mask = SSLBlockingPage::STRICT_ENFORCEMENT;
1712 if (expired_previous_decision)
1713 options_mask = SSLBlockingPage::EXPIRED_BUT_PREVIOUSLY_ALLOWED;
1714 SSLBlockingPage* ssl_blocking_page = new SSLBlockingPage(
1715 tab, cert_error, ssl_info, request_url, options_mask, callback);
1716 ssl_blocking_page->Show();
1719 void ChromeContentBrowserClient::SelectClientCertificate(
1720 int render_process_id,
1721 int render_frame_id,
1722 const net::HttpNetworkSession* network_session,
1723 net::SSLCertRequestInfo* cert_request_info,
1724 const base::Callback<void(net::X509Certificate*)>& callback) {
1725 content::RenderFrameHost* rfh = content::RenderFrameHost::FromID(
1726 render_process_id, render_frame_id);
1727 WebContents* tab = WebContents::FromRenderFrameHost(rfh);
1728 if (!tab) {
1729 NOTREACHED();
1730 return;
1733 prerender::PrerenderContents* prerender_contents =
1734 prerender::PrerenderContents::FromWebContents(tab);
1735 if (prerender_contents) {
1736 prerender_contents->Destroy(
1737 prerender::FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED);
1738 return;
1741 GURL requesting_url("https://" + cert_request_info->host_and_port.ToString());
1742 DCHECK(requesting_url.is_valid())
1743 << "Invalid URL string: https://"
1744 << cert_request_info->host_and_port.ToString();
1746 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
1747 scoped_ptr<base::Value> filter(
1748 profile->GetHostContentSettingsMap()->GetWebsiteSetting(
1749 requesting_url,
1750 requesting_url,
1751 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
1752 std::string(), NULL));
1754 if (filter.get()) {
1755 // Try to automatically select a client certificate.
1756 if (filter->IsType(base::Value::TYPE_DICTIONARY)) {
1757 base::DictionaryValue* filter_dict =
1758 static_cast<base::DictionaryValue*>(filter.get());
1760 const std::vector<scoped_refptr<net::X509Certificate> >&
1761 all_client_certs = cert_request_info->client_certs;
1762 for (size_t i = 0; i < all_client_certs.size(); ++i) {
1763 if (CertMatchesFilter(*all_client_certs[i].get(), *filter_dict)) {
1764 // Use the first certificate that is matched by the filter.
1765 callback.Run(all_client_certs[i].get());
1766 return;
1769 } else {
1770 NOTREACHED();
1774 chrome::ShowSSLClientCertificateSelector(tab, network_session,
1775 cert_request_info, callback);
1778 void ChromeContentBrowserClient::AddCertificate(
1779 net::CertificateMimeType cert_type,
1780 const void* cert_data,
1781 size_t cert_size,
1782 int render_process_id,
1783 int render_frame_id) {
1784 chrome::SSLAddCertificate(cert_type, cert_data, cert_size,
1785 render_process_id, render_frame_id);
1788 content::MediaObserver* ChromeContentBrowserClient::GetMediaObserver() {
1789 return MediaCaptureDevicesDispatcher::GetInstance();
1792 void ChromeContentBrowserClient::RequestDesktopNotificationPermission(
1793 const GURL& source_origin,
1794 content::RenderFrameHost* render_frame_host,
1795 const base::Callback<void(blink::WebNotificationPermission)>& callback) {
1796 #if defined(ENABLE_NOTIFICATIONS)
1797 // Skip showing the infobar if the request comes from an extension, and that
1798 // extension has the 'notify' permission. (If the extension does not have the
1799 // permission, the user will still be prompted.)
1800 Profile* profile = Profile::FromBrowserContext(
1801 render_frame_host->GetSiteInstance()->GetBrowserContext());
1802 DesktopNotificationService* notification_service =
1803 DesktopNotificationServiceFactory::GetForProfile(profile);
1804 #if defined(ENABLE_EXTENSIONS)
1805 InfoMap* extension_info_map =
1806 extensions::ExtensionSystem::Get(profile)->info_map();
1807 const Extension* extension = NULL;
1808 if (extension_info_map) {
1809 extensions::ExtensionSet extensions;
1810 extension_info_map->GetExtensionsWithAPIPermissionForSecurityOrigin(
1811 source_origin,
1812 render_frame_host->GetProcess()->GetID(),
1813 extensions::APIPermission::kNotifications,
1814 &extensions);
1815 for (extensions::ExtensionSet::const_iterator iter = extensions.begin();
1816 iter != extensions.end(); ++iter) {
1817 if (notification_service->IsNotifierEnabled(NotifierId(
1818 NotifierId::APPLICATION, (*iter)->id()))) {
1819 extension = iter->get();
1820 break;
1824 if (IsExtensionWithPermissionOrSuggestInConsole(
1825 APIPermission::kNotifications,
1826 extension,
1827 render_frame_host->GetRenderViewHost())) {
1828 callback.Run(blink::WebNotificationPermissionAllowed);
1829 return;
1831 #endif
1833 WebContents* web_contents = WebContents::FromRenderFrameHost(
1834 render_frame_host);
1835 int render_process_id = render_frame_host->GetProcess()->GetID();
1836 const PermissionRequestID request_id(render_process_id,
1837 web_contents->GetRoutingID(),
1838 -1 /* bridge id */,
1839 GURL());
1841 notification_service->RequestNotificationPermission(
1842 web_contents,
1843 request_id,
1844 source_origin,
1845 // TODO(peter): plumb user_gesture over IPC
1846 true,
1847 callback);
1849 #else
1850 NOTIMPLEMENTED();
1851 #endif
1854 blink::WebNotificationPermission
1855 ChromeContentBrowserClient::CheckDesktopNotificationPermission(
1856 const GURL& source_origin,
1857 content::ResourceContext* context,
1858 int render_process_id) {
1859 #if defined(ENABLE_NOTIFICATIONS)
1860 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1862 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
1863 InfoMap* extension_info_map = io_data->GetExtensionInfoMap();
1865 // We want to see if there is an extension that hasn't been manually disabled
1866 // that has the notifications permission and applies to this security origin.
1867 // First, get the list of extensions with permission for the origin.
1868 extensions::ExtensionSet extensions;
1869 extension_info_map->GetExtensionsWithAPIPermissionForSecurityOrigin(
1870 source_origin,
1871 render_process_id,
1872 extensions::APIPermission::kNotifications,
1873 &extensions);
1874 for (extensions::ExtensionSet::const_iterator iter = extensions.begin();
1875 iter != extensions.end(); ++iter) {
1876 // Then, check to see if it's been disabled by the user.
1877 if (!extension_info_map->AreNotificationsDisabled((*iter)->id()))
1878 return blink::WebNotificationPermissionAllowed;
1881 // No enabled extensions exist, so check the normal host content settings.
1882 HostContentSettingsMap* host_content_settings_map =
1883 io_data->GetHostContentSettingsMap();
1884 ContentSetting setting = host_content_settings_map->GetContentSetting(
1885 source_origin,
1886 source_origin,
1887 CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
1888 NO_RESOURCE_IDENTIFIER);
1890 if (setting == CONTENT_SETTING_ALLOW)
1891 return blink::WebNotificationPermissionAllowed;
1892 if (setting == CONTENT_SETTING_BLOCK)
1893 return blink::WebNotificationPermissionDenied;
1894 return blink::WebNotificationPermissionDefault;
1895 #else
1896 return blink::WebNotificationPermissionAllowed;
1897 #endif
1900 void ChromeContentBrowserClient::ShowDesktopNotification(
1901 const content::ShowDesktopNotificationHostMsgParams& params,
1902 RenderFrameHost* render_frame_host,
1903 scoped_ptr<content::DesktopNotificationDelegate> delegate,
1904 base::Closure* cancel_callback) {
1905 #if defined(ENABLE_NOTIFICATIONS)
1906 content::RenderProcessHost* process = render_frame_host->GetProcess();
1907 Profile* profile = Profile::FromBrowserContext(process->GetBrowserContext());
1908 DesktopNotificationService* service =
1909 DesktopNotificationServiceFactory::GetForProfile(profile);
1910 service->ShowDesktopNotification(
1911 params, render_frame_host, delegate.Pass(), cancel_callback);
1913 profile->GetHostContentSettingsMap()->UpdateLastUsage(
1914 params.origin, params.origin, CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
1915 #else
1916 NOTIMPLEMENTED();
1917 #endif
1920 void ChromeContentBrowserClient::RequestGeolocationPermission(
1921 content::WebContents* web_contents,
1922 int bridge_id,
1923 const GURL& requesting_frame,
1924 bool user_gesture,
1925 base::Callback<void(bool)> result_callback,
1926 base::Closure* cancel_callback) {
1927 GeolocationPermissionContextFactory::GetForProfile(
1928 Profile::FromBrowserContext(web_contents->GetBrowserContext()))->
1929 RequestGeolocationPermission(web_contents, bridge_id,
1930 requesting_frame, user_gesture,
1931 result_callback, cancel_callback);
1934 void ChromeContentBrowserClient::RequestMidiSysExPermission(
1935 content::WebContents* web_contents,
1936 int bridge_id,
1937 const GURL& requesting_frame,
1938 bool user_gesture,
1939 base::Callback<void(bool)> result_callback,
1940 base::Closure* cancel_callback) {
1941 MidiPermissionContext* context =
1942 MidiPermissionContextFactory::GetForProfile(
1943 Profile::FromBrowserContext(web_contents->GetBrowserContext()));
1944 int renderer_id = web_contents->GetRenderProcessHost()->GetID();
1945 int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID();
1946 const PermissionRequestID id(renderer_id, render_view_id, bridge_id, GURL());
1948 context->RequestPermission(web_contents, id, requesting_frame,
1949 user_gesture, result_callback);
1952 void ChromeContentBrowserClient::DidUseGeolocationPermission(
1953 content::WebContents* web_contents,
1954 const GURL& frame_url,
1955 const GURL& main_frame_url) {
1956 Profile::FromBrowserContext(web_contents->GetBrowserContext())
1957 ->GetHostContentSettingsMap()
1958 ->UpdateLastUsage(
1959 frame_url, main_frame_url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
1962 void ChromeContentBrowserClient::RequestProtectedMediaIdentifierPermission(
1963 content::WebContents* web_contents,
1964 const GURL& origin,
1965 base::Callback<void(bool)> result_callback,
1966 base::Closure* cancel_callback) {
1967 #if defined(OS_ANDROID)
1968 ProtectedMediaIdentifierPermissionContext* context =
1969 ProtectedMediaIdentifierPermissionContextFactory::GetForProfile(
1970 Profile::FromBrowserContext(web_contents->GetBrowserContext()));
1971 context->RequestProtectedMediaIdentifierPermission(web_contents,
1972 origin,
1973 result_callback,
1974 cancel_callback);
1975 #else
1976 NOTIMPLEMENTED();
1977 result_callback.Run(false);
1978 #endif // defined(OS_ANDROID)
1981 bool ChromeContentBrowserClient::CanCreateWindow(
1982 const GURL& opener_url,
1983 const GURL& opener_top_level_frame_url,
1984 const GURL& source_origin,
1985 WindowContainerType container_type,
1986 const GURL& target_url,
1987 const content::Referrer& referrer,
1988 WindowOpenDisposition disposition,
1989 const WebWindowFeatures& features,
1990 bool user_gesture,
1991 bool opener_suppressed,
1992 content::ResourceContext* context,
1993 int render_process_id,
1994 int opener_id,
1995 bool* no_javascript_access) {
1996 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1998 *no_javascript_access = false;
2000 // If the opener is trying to create a background window but doesn't have
2001 // the appropriate permission, fail the attempt.
2002 if (container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) {
2003 #if defined(ENABLE_EXTENSIONS)
2004 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
2005 InfoMap* map = io_data->GetExtensionInfoMap();
2006 if (!map->SecurityOriginHasAPIPermission(
2007 source_origin,
2008 render_process_id,
2009 APIPermission::kBackground)) {
2010 return false;
2013 // Note: this use of GetExtensionOrAppByURL is safe but imperfect. It may
2014 // return a recently installed Extension even if this CanCreateWindow call
2015 // was made by an old copy of the page in a normal web process. That's ok,
2016 // because the permission check above would have caused an early return
2017 // already. We must use the full URL to find hosted apps, though, and not
2018 // just the origin.
2019 const Extension* extension =
2020 map->extensions().GetExtensionOrAppByURL(opener_url);
2021 if (extension && !extensions::BackgroundInfo::AllowJSAccess(extension))
2022 *no_javascript_access = true;
2023 #endif
2025 return true;
2028 #if defined(ENABLE_EXTENSIONS)
2029 if (extensions::WebViewRendererState::GetInstance()->IsGuest(
2030 render_process_id))
2031 return true;
2032 #endif
2034 HostContentSettingsMap* content_settings =
2035 ProfileIOData::FromResourceContext(context)->GetHostContentSettingsMap();
2036 BlockedWindowParams blocked_params(target_url,
2037 referrer,
2038 disposition,
2039 features,
2040 user_gesture,
2041 opener_suppressed,
2042 render_process_id,
2043 opener_id);
2045 if (!user_gesture && !CommandLine::ForCurrentProcess()->HasSwitch(
2046 switches::kDisablePopupBlocking)) {
2047 if (content_settings->GetContentSetting(opener_top_level_frame_url,
2048 opener_top_level_frame_url,
2049 CONTENT_SETTINGS_TYPE_POPUPS,
2050 std::string()) !=
2051 CONTENT_SETTING_ALLOW) {
2052 BrowserThread::PostTask(BrowserThread::UI,
2053 FROM_HERE,
2054 base::Bind(&HandleBlockedPopupOnUIThread,
2055 blocked_params));
2056 return false;
2060 #if defined(OS_ANDROID)
2061 if (SingleTabModeTabHelper::IsRegistered(render_process_id, opener_id)) {
2062 BrowserThread::PostTask(BrowserThread::UI,
2063 FROM_HERE,
2064 base::Bind(&HandleSingleTabModeBlockOnUIThread,
2065 blocked_params));
2066 return false;
2068 #endif
2070 return true;
2073 void ChromeContentBrowserClient::ResourceDispatcherHostCreated() {
2074 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2075 prerender_tracker_ = g_browser_process->prerender_tracker();
2076 return g_browser_process->ResourceDispatcherHostCreated();
2079 // TODO(tommi): Rename from Get to Create.
2080 content::SpeechRecognitionManagerDelegate*
2081 ChromeContentBrowserClient::GetSpeechRecognitionManagerDelegate() {
2082 return new speech::ChromeSpeechRecognitionManagerDelegate();
2085 net::NetLog* ChromeContentBrowserClient::GetNetLog() {
2086 return g_browser_process->net_log();
2089 AccessTokenStore* ChromeContentBrowserClient::CreateAccessTokenStore() {
2090 return new ChromeAccessTokenStore();
2093 bool ChromeContentBrowserClient::IsFastShutdownPossible() {
2094 return true;
2097 void ChromeContentBrowserClient::OverrideWebkitPrefs(
2098 RenderViewHost* rvh, const GURL& url, WebPreferences* web_prefs) {
2099 Profile* profile = Profile::FromBrowserContext(
2100 rvh->GetProcess()->GetBrowserContext());
2101 PrefService* prefs = profile->GetPrefs();
2103 // Fill per-script font preferences. These are not registered on Android
2104 // - http://crbug.com/308033.
2105 #if !defined(OS_ANDROID)
2106 FontFamilyCache::FillFontFamilyMap(profile,
2107 prefs::kWebKitStandardFontFamilyMap,
2108 &web_prefs->standard_font_family_map);
2109 FontFamilyCache::FillFontFamilyMap(profile,
2110 prefs::kWebKitFixedFontFamilyMap,
2111 &web_prefs->fixed_font_family_map);
2112 FontFamilyCache::FillFontFamilyMap(profile,
2113 prefs::kWebKitSerifFontFamilyMap,
2114 &web_prefs->serif_font_family_map);
2115 FontFamilyCache::FillFontFamilyMap(profile,
2116 prefs::kWebKitSansSerifFontFamilyMap,
2117 &web_prefs->sans_serif_font_family_map);
2118 FontFamilyCache::FillFontFamilyMap(profile,
2119 prefs::kWebKitCursiveFontFamilyMap,
2120 &web_prefs->cursive_font_family_map);
2121 FontFamilyCache::FillFontFamilyMap(profile,
2122 prefs::kWebKitFantasyFontFamilyMap,
2123 &web_prefs->fantasy_font_family_map);
2124 FontFamilyCache::FillFontFamilyMap(profile,
2125 prefs::kWebKitPictographFontFamilyMap,
2126 &web_prefs->pictograph_font_family_map);
2127 #endif
2129 web_prefs->default_font_size =
2130 prefs->GetInteger(prefs::kWebKitDefaultFontSize);
2131 web_prefs->default_fixed_font_size =
2132 prefs->GetInteger(prefs::kWebKitDefaultFixedFontSize);
2133 web_prefs->minimum_font_size =
2134 prefs->GetInteger(prefs::kWebKitMinimumFontSize);
2135 web_prefs->minimum_logical_font_size =
2136 prefs->GetInteger(prefs::kWebKitMinimumLogicalFontSize);
2138 web_prefs->default_encoding = prefs->GetString(prefs::kDefaultCharset);
2140 web_prefs->javascript_can_open_windows_automatically =
2141 prefs->GetBoolean(prefs::kWebKitJavascriptCanOpenWindowsAutomatically);
2142 web_prefs->dom_paste_enabled =
2143 prefs->GetBoolean(prefs::kWebKitDomPasteEnabled);
2144 web_prefs->shrinks_standalone_images_to_fit =
2145 prefs->GetBoolean(prefs::kWebKitShrinksStandaloneImagesToFit);
2146 web_prefs->tabs_to_links = prefs->GetBoolean(prefs::kWebkitTabsToLinks);
2148 if (!prefs->GetBoolean(prefs::kWebKitJavascriptEnabled))
2149 web_prefs->javascript_enabled = false;
2150 if (!prefs->GetBoolean(prefs::kWebKitWebSecurityEnabled))
2151 web_prefs->web_security_enabled = false;
2152 if (!prefs->GetBoolean(prefs::kWebKitPluginsEnabled))
2153 web_prefs->plugins_enabled = false;
2154 if (!prefs->GetBoolean(prefs::kWebKitJavaEnabled))
2155 web_prefs->java_enabled = false;
2156 web_prefs->loads_images_automatically =
2157 prefs->GetBoolean(prefs::kWebKitLoadsImagesAutomatically);
2159 if (prefs->GetBoolean(prefs::kDisable3DAPIs))
2160 web_prefs->experimental_webgl_enabled = false;
2162 web_prefs->allow_displaying_insecure_content =
2163 prefs->GetBoolean(prefs::kWebKitAllowDisplayingInsecureContent);
2164 web_prefs->allow_running_insecure_content =
2165 prefs->GetBoolean(prefs::kWebKitAllowRunningInsecureContent);
2166 #if defined(OS_ANDROID)
2167 web_prefs->font_scale_factor =
2168 static_cast<float>(prefs->GetDouble(prefs::kWebKitFontScaleFactor));
2169 web_prefs->device_scale_adjustment = GetDeviceScaleAdjustment();
2170 web_prefs->force_enable_zoom =
2171 prefs->GetBoolean(prefs::kWebKitForceEnableZoom);
2172 #endif
2174 #if defined(OS_ANDROID)
2175 web_prefs->password_echo_enabled =
2176 prefs->GetBoolean(prefs::kWebKitPasswordEchoEnabled);
2177 #else
2178 web_prefs->password_echo_enabled = browser_defaults::kPasswordEchoEnabled;
2179 #endif
2181 web_prefs->asynchronous_spell_checking_enabled = true;
2182 web_prefs->unified_textchecker_enabled = true;
2184 web_prefs->uses_universal_detector =
2185 prefs->GetBoolean(prefs::kWebKitUsesUniversalDetector);
2186 web_prefs->text_areas_are_resizable =
2187 prefs->GetBoolean(prefs::kWebKitTextAreasAreResizable);
2188 web_prefs->hyperlink_auditing_enabled =
2189 prefs->GetBoolean(prefs::kEnableHyperlinkAuditing);
2191 // Make sure we will set the default_encoding with canonical encoding name.
2192 web_prefs->default_encoding =
2193 CharacterEncoding::GetCanonicalEncodingNameByAliasName(
2194 web_prefs->default_encoding);
2195 if (web_prefs->default_encoding.empty()) {
2196 prefs->ClearPref(prefs::kDefaultCharset);
2197 web_prefs->default_encoding = prefs->GetString(prefs::kDefaultCharset);
2199 DCHECK(!web_prefs->default_encoding.empty());
2201 for (size_t i = 0; i < extra_parts_.size(); ++i)
2202 extra_parts_[i]->OverrideWebkitPrefs(rvh, url, web_prefs);
2205 void ChromeContentBrowserClient::BrowserURLHandlerCreated(
2206 BrowserURLHandler* handler) {
2207 for (size_t i = 0; i < extra_parts_.size(); ++i)
2208 extra_parts_[i]->BrowserURLHandlerCreated(handler);
2210 // about: handler. Must come before chrome: handler, since it will
2211 // rewrite about: urls to chrome: URLs and then expect chrome: to
2212 // actually handle them.
2213 handler->AddHandlerPair(&WillHandleBrowserAboutURL,
2214 BrowserURLHandler::null_handler());
2216 #if defined(OS_ANDROID)
2217 // Handler to rewrite chrome://newtab on Android.
2218 handler->AddHandlerPair(&chrome::android::HandleAndroidNewTabURL,
2219 BrowserURLHandler::null_handler());
2220 #else
2221 // Handler to rewrite chrome://newtab for InstantExtended.
2222 handler->AddHandlerPair(&chrome::HandleNewTabURLRewrite,
2223 &chrome::HandleNewTabURLReverseRewrite);
2224 #endif
2226 // chrome: & friends.
2227 handler->AddHandlerPair(&HandleWebUI, &HandleWebUIReverse);
2230 void ChromeContentBrowserClient::ClearCache(RenderViewHost* rvh) {
2231 Profile* profile = Profile::FromBrowserContext(
2232 rvh->GetSiteInstance()->GetProcess()->GetBrowserContext());
2233 BrowsingDataRemover* remover =
2234 BrowsingDataRemover::CreateForUnboundedRange(profile);
2235 remover->Remove(BrowsingDataRemover::REMOVE_CACHE,
2236 BrowsingDataHelper::UNPROTECTED_WEB);
2237 // BrowsingDataRemover takes care of deleting itself when done.
2240 void ChromeContentBrowserClient::ClearCookies(RenderViewHost* rvh) {
2241 Profile* profile = Profile::FromBrowserContext(
2242 rvh->GetSiteInstance()->GetProcess()->GetBrowserContext());
2243 BrowsingDataRemover* remover =
2244 BrowsingDataRemover::CreateForUnboundedRange(profile);
2245 int remove_mask = BrowsingDataRemover::REMOVE_SITE_DATA;
2246 remover->Remove(remove_mask, BrowsingDataHelper::UNPROTECTED_WEB);
2247 // BrowsingDataRemover takes care of deleting itself when done.
2250 base::FilePath ChromeContentBrowserClient::GetDefaultDownloadDirectory() {
2251 return DownloadPrefs::GetDefaultDownloadDirectory();
2254 std::string ChromeContentBrowserClient::GetDefaultDownloadName() {
2255 return l10n_util::GetStringUTF8(IDS_DEFAULT_DOWNLOAD_FILENAME);
2258 void ChromeContentBrowserClient::DidCreatePpapiPlugin(
2259 content::BrowserPpapiHost* browser_host) {
2260 #if defined(ENABLE_PLUGINS)
2261 browser_host->GetPpapiHost()->AddHostFactoryFilter(
2262 scoped_ptr<ppapi::host::HostFactory>(
2263 new ChromeBrowserPepperHostFactory(browser_host)));
2264 #endif
2267 content::BrowserPpapiHost*
2268 ChromeContentBrowserClient::GetExternalBrowserPpapiHost(
2269 int plugin_process_id) {
2270 #if !defined(DISABLE_NACL)
2271 content::BrowserChildProcessHostIterator iter(PROCESS_TYPE_NACL_LOADER);
2272 while (!iter.Done()) {
2273 nacl::NaClProcessHost* host = static_cast<nacl::NaClProcessHost*>(
2274 iter.GetDelegate());
2275 if (host->process() &&
2276 host->process()->GetData().id == plugin_process_id) {
2277 // Found the plugin.
2278 return host->browser_ppapi_host();
2280 ++iter;
2282 #endif
2283 return NULL;
2286 bool ChromeContentBrowserClient::AllowPepperSocketAPI(
2287 content::BrowserContext* browser_context,
2288 const GURL& url,
2289 bool private_api,
2290 const content::SocketPermissionRequest* params) {
2291 #if defined(ENABLE_EXTENSIONS)
2292 Profile* profile = Profile::FromBrowserContext(browser_context);
2293 const extensions::ExtensionSet* extension_set = NULL;
2294 if (profile) {
2295 const ExtensionService* ext_service =
2296 extensions::ExtensionSystem::Get(profile)->extension_service();
2297 if (ext_service) {
2298 extension_set = ext_service->extensions();
2302 if (private_api) {
2303 // Access to private socket APIs is controlled by the whitelist.
2304 if (IsExtensionOrSharedModuleWhitelisted(url, extension_set,
2305 allowed_socket_origins_)) {
2306 return true;
2308 } else {
2309 // Access to public socket APIs is controlled by extension permissions.
2310 if (url.is_valid() && url.SchemeIs(extensions::kExtensionScheme) &&
2311 extension_set) {
2312 const Extension* extension = extension_set->GetByID(url.host());
2313 if (extension) {
2314 const extensions::PermissionsData* permissions_data =
2315 extension->permissions_data();
2316 if (params) {
2317 extensions::SocketPermission::CheckParam check_params(
2318 params->type, params->host, params->port);
2319 if (permissions_data->CheckAPIPermissionWithParam(
2320 extensions::APIPermission::kSocket, &check_params)) {
2321 return true;
2323 } else if (permissions_data->HasAPIPermission(
2324 extensions::APIPermission::kSocket)) {
2325 return true;
2331 // Allow both public and private APIs if the command line says so.
2332 return IsHostAllowedByCommandLine(url, extension_set,
2333 switches::kAllowNaClSocketAPI);
2334 #else
2335 return false;
2336 #endif
2339 ui::SelectFilePolicy* ChromeContentBrowserClient::CreateSelectFilePolicy(
2340 WebContents* web_contents) {
2341 return new ChromeSelectFilePolicy(web_contents);
2344 void ChromeContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem(
2345 std::vector<std::string>* additional_allowed_schemes) {
2346 ContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem(
2347 additional_allowed_schemes);
2348 additional_allowed_schemes->push_back(content::kChromeDevToolsScheme);
2349 additional_allowed_schemes->push_back(content::kChromeUIScheme);
2350 for (size_t i = 0; i < extra_parts_.size(); ++i) {
2351 extra_parts_[i]->GetAdditionalAllowedSchemesForFileSystem(
2352 additional_allowed_schemes);
2356 void ChromeContentBrowserClient::GetURLRequestAutoMountHandlers(
2357 std::vector<storage::URLRequestAutoMountHandler>* handlers) {
2358 for (size_t i = 0; i < extra_parts_.size(); ++i)
2359 extra_parts_[i]->GetURLRequestAutoMountHandlers(handlers);
2362 void ChromeContentBrowserClient::GetAdditionalFileSystemBackends(
2363 content::BrowserContext* browser_context,
2364 const base::FilePath& storage_partition_path,
2365 ScopedVector<storage::FileSystemBackend>* additional_backends) {
2366 #if defined(OS_CHROMEOS)
2367 storage::ExternalMountPoints* external_mount_points =
2368 content::BrowserContext::GetMountPoints(browser_context);
2369 DCHECK(external_mount_points);
2370 chromeos::FileSystemBackend* backend = new chromeos::FileSystemBackend(
2371 new drive::FileSystemBackendDelegate,
2372 new chromeos::file_system_provider::BackendDelegate,
2373 new chromeos::MTPFileSystemBackendDelegate(storage_partition_path),
2374 browser_context->GetSpecialStoragePolicy(),
2375 external_mount_points,
2376 storage::ExternalMountPoints::GetSystemInstance());
2377 backend->AddSystemMountPoints();
2378 DCHECK(backend->CanHandleType(storage::kFileSystemTypeExternal));
2379 additional_backends->push_back(backend);
2380 #endif
2382 #if defined(ENABLE_SERVICE_DISCOVERY)
2383 if (CommandLine::ForCurrentProcess()->HasSwitch(
2384 switches::kEnablePrivetStorage)) {
2385 additional_backends->push_back(new local_discovery::PrivetFileSystemBackend(
2386 storage::ExternalMountPoints::GetSystemInstance(), browser_context));
2388 #endif
2390 for (size_t i = 0; i < extra_parts_.size(); ++i) {
2391 extra_parts_[i]->GetAdditionalFileSystemBackends(
2392 browser_context, storage_partition_path, additional_backends);
2396 #if defined(OS_POSIX) && !defined(OS_MACOSX)
2397 void ChromeContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
2398 const CommandLine& command_line,
2399 int child_process_id,
2400 std::vector<FileDescriptorInfo>* mappings) {
2401 #if defined(OS_ANDROID)
2402 base::FilePath data_path;
2403 PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &data_path);
2404 DCHECK(!data_path.empty());
2406 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
2407 base::FilePath chrome_resources_pak =
2408 data_path.AppendASCII("chrome_100_percent.pak");
2409 base::File file(chrome_resources_pak, flags);
2410 DCHECK(file.IsValid());
2411 mappings->push_back(FileDescriptorInfo(kAndroidChrome100PercentPakDescriptor,
2412 FileDescriptor(file.Pass())));
2414 const std::string locale = GetApplicationLocale();
2415 base::FilePath locale_pak = ResourceBundle::GetSharedInstance().
2416 GetLocaleFilePath(locale, false);
2417 file.Initialize(locale_pak, flags);
2418 DCHECK(file.IsValid());
2419 mappings->push_back(FileDescriptorInfo(kAndroidLocalePakDescriptor,
2420 FileDescriptor(file.Pass())));
2422 base::FilePath resources_pack_path;
2423 PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path);
2424 file.Initialize(resources_pack_path, flags);
2425 DCHECK(file.IsValid());
2426 mappings->push_back(FileDescriptorInfo(kAndroidUIResourcesPakDescriptor,
2427 FileDescriptor(file.Pass())));
2429 if (breakpad::IsCrashReporterEnabled()) {
2430 file = breakpad::CrashDumpManager::GetInstance()->CreateMinidumpFile(
2431 child_process_id);
2432 if (file.IsValid()) {
2433 mappings->push_back(FileDescriptorInfo(kAndroidMinidumpDescriptor,
2434 FileDescriptor(file.Pass())));
2435 } else {
2436 LOG(ERROR) << "Failed to create file for minidump, crash reporting will "
2437 "be disabled for this process.";
2441 base::FilePath app_data_path;
2442 PathService::Get(base::DIR_ANDROID_APP_DATA, &app_data_path);
2443 DCHECK(!app_data_path.empty());
2445 flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
2446 base::FilePath icudata_path =
2447 app_data_path.AppendASCII("icudtl.dat");
2448 base::File icudata_file(icudata_path, flags);
2449 DCHECK(icudata_file.IsValid());
2450 mappings->push_back(FileDescriptorInfo(kAndroidICUDataDescriptor,
2451 FileDescriptor(icudata_file.Pass())));
2453 #else
2454 int crash_signal_fd = GetCrashSignalFD(command_line);
2455 if (crash_signal_fd >= 0) {
2456 mappings->push_back(FileDescriptorInfo(kCrashDumpSignal,
2457 FileDescriptor(crash_signal_fd,
2458 false)));
2460 #endif // defined(OS_ANDROID)
2462 #endif // defined(OS_POSIX) && !defined(OS_MACOSX)
2464 #if defined(OS_WIN)
2465 const wchar_t* ChromeContentBrowserClient::GetResourceDllName() {
2466 return chrome::kBrowserResourcesDll;
2469 void ChromeContentBrowserClient::PreSpawnRenderer(
2470 sandbox::TargetPolicy* policy,
2471 bool* success) {
2472 // This code is duplicated in nacl_exe_win_64.cc.
2473 // Allow the server side of a pipe restricted to the "chrome.nacl."
2474 // namespace so that it cannot impersonate other system or other chrome
2475 // service pipes.
2476 sandbox::ResultCode result = policy->AddRule(
2477 sandbox::TargetPolicy::SUBSYS_NAMED_PIPES,
2478 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY,
2479 L"\\\\.\\pipe\\chrome.nacl.*");
2480 if (result != sandbox::SBOX_ALL_OK) {
2481 *success = false;
2482 return;
2485 // Renderers need to send named pipe handles and shared memory
2486 // segment handles to NaCl loader processes.
2487 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
2488 sandbox::TargetPolicy::HANDLES_DUP_ANY,
2489 L"File");
2490 if (result != sandbox::SBOX_ALL_OK) {
2491 *success = false;
2492 return;
2495 #endif
2497 content::DevToolsManagerDelegate*
2498 ChromeContentBrowserClient::GetDevToolsManagerDelegate() {
2499 return new ChromeDevToolsManagerDelegate();
2502 bool ChromeContentBrowserClient::IsPluginAllowedToCallRequestOSFileHandle(
2503 content::BrowserContext* browser_context,
2504 const GURL& url) {
2505 #if defined(ENABLE_EXTENSIONS)
2506 Profile* profile = Profile::FromBrowserContext(browser_context);
2507 const extensions::ExtensionSet* extension_set = NULL;
2508 if (profile) {
2509 const ExtensionService* ext_service =
2510 extensions::ExtensionSystem::Get(profile)->extension_service();
2511 if (ext_service) {
2512 extension_set = ext_service->extensions();
2515 return IsExtensionOrSharedModuleWhitelisted(url, extension_set,
2516 allowed_file_handle_origins_) ||
2517 IsHostAllowedByCommandLine(url, extension_set,
2518 switches::kAllowNaClFileHandleAPI);
2519 #else
2520 return false;
2521 #endif
2524 bool ChromeContentBrowserClient::IsPluginAllowedToUseDevChannelAPIs(
2525 content::BrowserContext* browser_context,
2526 const GURL& url) {
2527 #if defined(ENABLE_EXTENSIONS)
2528 // Allow access for tests.
2529 if (CommandLine::ForCurrentProcess()->HasSwitch(
2530 switches::kEnablePepperTesting)) {
2531 return true;
2534 Profile* profile = Profile::FromBrowserContext(browser_context);
2535 const extensions::ExtensionSet* extension_set = NULL;
2536 if (profile) {
2537 const ExtensionService* ext_service =
2538 extensions::ExtensionSystem::Get(profile)->extension_service();
2539 if (ext_service) {
2540 extension_set = ext_service->extensions();
2544 // Allow access for whitelisted applications.
2545 if (IsExtensionOrSharedModuleWhitelisted(url,
2546 extension_set,
2547 allowed_dev_channel_origins_)) {
2548 return true;
2551 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
2552 // Allow dev channel APIs to be used on "Canary", "Dev", and "Unknown"
2553 // releases of Chrome. Permitting "Unknown" allows these APIs to be used on
2554 // Chromium builds as well.
2555 return channel <= chrome::VersionInfo::CHANNEL_DEV;
2556 #else
2557 return false;
2558 #endif
2561 net::CookieStore*
2562 ChromeContentBrowserClient::OverrideCookieStoreForRenderProcess(
2563 int render_process_id) {
2564 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2565 if (!prerender_tracker_)
2566 return NULL;
2567 return prerender_tracker_->
2568 GetPrerenderCookieStoreForRenderProcess(render_process_id);
2571 #if defined(ENABLE_WEBRTC)
2572 void ChromeContentBrowserClient::MaybeCopyDisableWebRtcEncryptionSwitch(
2573 CommandLine* to_command_line,
2574 const CommandLine& from_command_line,
2575 VersionInfo::Channel channel) {
2576 #if defined(OS_ANDROID)
2577 const VersionInfo::Channel kMaxDisableEncryptionChannel =
2578 VersionInfo::CHANNEL_BETA;
2579 #else
2580 const VersionInfo::Channel kMaxDisableEncryptionChannel =
2581 VersionInfo::CHANNEL_DEV;
2582 #endif
2583 if (channel <= kMaxDisableEncryptionChannel) {
2584 static const char* const kWebRtcDevSwitchNames[] = {
2585 switches::kDisableWebRtcEncryption,
2587 to_command_line->CopySwitchesFrom(from_command_line,
2588 kWebRtcDevSwitchNames,
2589 arraysize(kWebRtcDevSwitchNames));
2592 #endif // defined(ENABLE_WEBRTC)
2594 } // namespace chrome