chrome_content_browser_client.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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. 4 5#include "chrome/browser/chrome_content_browser_client.h" 6 7#include <set> 8#include <utility> 9#include <vector> 10 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/app_mode/app_mode_utils.h" 21#include "chrome/browser/browser_about_handler.h" 22#include "chrome/browser/browser_process.h" 23#include "chrome/browser/browser_shutdown.h" 24#include "chrome/browser/browsing_data/browsing_data_helper.h" 25#include "chrome/browser/browsing_data/browsing_data_remover.h" 26#include "chrome/browser/character_encoding.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/tab_specific_content_settings.h" 33#include "chrome/browser/defaults.h" 34#include "chrome/browser/download/download_prefs.h" 35#include "chrome/browser/extensions/api/web_request/web_request_api.h" 36#include "chrome/browser/extensions/browser_permissions_policy_delegate.h" 37#include "chrome/browser/extensions/extension_host.h" 38#include "chrome/browser/extensions/extension_service.h" 39#include "chrome/browser/extensions/extension_web_ui.h" 40#include "chrome/browser/extensions/extension_webkit_preferences.h" 41#include "chrome/browser/extensions/suggest_permission_util.h" 42#include "chrome/browser/geolocation/chrome_access_token_store.h" 43#include "chrome/browser/google/google_util.h" 44#include "chrome/browser/guestview/adview/adview_guest.h" 45#include "chrome/browser/guestview/guestview.h" 46#include "chrome/browser/guestview/guestview_constants.h" 47#include "chrome/browser/guestview/webview/webview_guest.h" 48#include "chrome/browser/local_discovery/storage/privet_filesystem_backend.h" 49#include "chrome/browser/media/cast_transport_host_filter.h" 50#include "chrome/browser/media/media_capture_devices_dispatcher.h" 51#include "chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.h" 52#include "chrome/browser/nacl_host/nacl_browser_delegate_impl.h" 53#include "chrome/browser/net/chrome_net_log.h" 54#include "chrome/browser/notifications/desktop_notification_service.h" 55#include "chrome/browser/notifications/desktop_notification_service_factory.h" 56#include "chrome/browser/platform_util.h" 57#include "chrome/browser/plugins/plugin_info_message_filter.h" 58#include "chrome/browser/prerender/prerender_final_status.h" 59#include "chrome/browser/prerender/prerender_manager.h" 60#include "chrome/browser/prerender/prerender_manager_factory.h" 61#include "chrome/browser/prerender/prerender_message_filter.h" 62#include "chrome/browser/prerender/prerender_tracker.h" 63#include "chrome/browser/printing/printing_message_filter.h" 64#include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h" 65#include "chrome/browser/profiles/profile.h" 66#include "chrome/browser/profiles/profile_io_data.h" 67#include "chrome/browser/profiles/profile_manager.h" 68#include "chrome/browser/renderer_host/chrome_render_message_filter.h" 69#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h" 70#include "chrome/browser/search/instant_service.h" 71#include "chrome/browser/search/instant_service_factory.h" 72#include "chrome/browser/search/search.h" 73#include "chrome/browser/search_engines/search_provider_install_state_message_filter.h" 74#include "chrome/browser/signin/principals_message_filter.h" 75#include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h" 76#include "chrome/browser/speech/tts_message_filter.h" 77#include "chrome/browser/ssl/ssl_add_certificate.h" 78#include "chrome/browser/ssl/ssl_blocking_page.h" 79#include "chrome/browser/ssl/ssl_tab_helper.h" 80#include "chrome/browser/sync_file_system/local/sync_file_system_backend.h" 81#include "chrome/browser/tab_contents/tab_util.h" 82#include "chrome/browser/ui/blocked_content/blocked_window_params.h" 83#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" 84#include "chrome/browser/ui/chrome_select_file_policy.h" 85#include "chrome/browser/ui/sync/sync_promo_ui.h" 86#include "chrome/browser/ui/tab_contents/chrome_web_contents_view_delegate.h" 87#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" 88#include "chrome/common/chrome_constants.h" 89#include "chrome/common/chrome_paths.h" 90#include "chrome/common/chrome_switches.h" 91#include "chrome/common/chrome_version_info.h" 92#include "chrome/common/env_vars.h" 93#include "chrome/common/extensions/extension_process_policy.h" 94#include "chrome/common/extensions/manifest_handlers/app_isolation_info.h" 95#include "chrome/common/extensions/permissions/socket_permission.h" 96#include "chrome/common/logging_chrome.h" 97#include "chrome/common/pepper_permission_util.h" 98#include "chrome/common/pref_names.h" 99#include "chrome/common/profile_management_switches.h" 100#include "chrome/common/render_messages.h" 101#include "chrome/common/url_constants.h" 102#include "chrome/installer/util/google_update_settings.h" 103#include "chromeos/chromeos_constants.h" 104#include "components/nacl/browser/nacl_browser.h" 105#include "components/nacl/browser/nacl_host_message_filter.h" 106#include "components/nacl/browser/nacl_process_host.h" 107#include "components/nacl/common/nacl_process_type.h" 108#include "components/translate/core/common/translate_switches.h" 109#include "components/user_prefs/pref_registry_syncable.h" 110#include "content/public/browser/browser_child_process_host.h" 111#include "content/public/browser/browser_main_parts.h" 112#include "content/public/browser/browser_ppapi_host.h" 113#include "content/public/browser/browser_thread.h" 114#include "content/public/browser/browser_url_handler.h" 115#include "content/public/browser/child_process_data.h" 116#include "content/public/browser/child_process_security_policy.h" 117#include "content/public/browser/render_frame_host.h" 118#include "content/public/browser/render_process_host.h" 119#include "content/public/browser/render_view_host.h" 120#include "content/public/browser/resource_context.h" 121#include "content/public/browser/site_instance.h" 122#include "content/public/browser/web_contents.h" 123#include "content/public/browser/web_contents_view.h" 124#include "content/public/common/child_process_host.h" 125#include "content/public/common/content_descriptors.h" 126#include "content/public/common/url_utils.h" 127#include "extensions/browser/extension_message_filter.h" 128#include "extensions/browser/extension_registry.h" 129#include "extensions/browser/extension_system.h" 130#include "extensions/browser/info_map.h" 131#include "extensions/browser/process_manager.h" 132#include "extensions/browser/process_map.h" 133#include "extensions/browser/view_type_utils.h" 134#include "extensions/common/constants.h" 135#include "extensions/common/extension.h" 136#include "extensions/common/extension_set.h" 137#include "extensions/common/manifest_handlers/background_info.h" 138#include "extensions/common/manifest_handlers/shared_module_info.h" 139#include "extensions/common/manifest_handlers/web_accessible_resources_info.h" 140#include "extensions/common/permissions/permissions_data.h" 141#include "extensions/common/switches.h" 142#include "grit/generated_resources.h" 143#include "grit/ui_resources.h" 144#include "net/base/mime_util.h" 145#include "net/cookies/canonical_cookie.h" 146#include "net/cookies/cookie_options.h" 147#include "net/ssl/ssl_cert_request_info.h" 148#include "ppapi/host/ppapi_host.h" 149#include "ppapi/shared_impl/ppapi_switches.h" 150#include "ui/base/l10n/l10n_util.h" 151#include "ui/base/resource/resource_bundle.h" 152#include "ui/message_center/message_center_util.h" 153#include "webkit/browser/fileapi/external_mount_points.h" 154#include "webkit/common/webpreferences.h" 155 156#if defined(OS_WIN) 157#include "base/win/windows_version.h" 158#include "chrome/browser/chrome_browser_main_win.h" 159#include "sandbox/win/src/sandbox_policy.h" 160#elif defined(OS_MACOSX) 161#include "chrome/browser/chrome_browser_main_mac.h" 162#include "chrome/browser/spellchecker/spellcheck_message_filter_mac.h" 163#include "components/breakpad/app/breakpad_mac.h" 164#elif defined(OS_CHROMEOS) 165#include "chrome/browser/chromeos/chrome_browser_main_chromeos.h" 166#include "chrome/browser/chromeos/drive/fileapi/file_system_backend_delegate.h" 167#include "chrome/browser/chromeos/fileapi/file_system_backend.h" 168#include "chrome/browser/chromeos/login/startup_utils.h" 169#include "chrome/browser/chromeos/login/user_manager.h" 170#include "chrome/browser/chromeos/system/input_device_settings.h" 171#include "chromeos/chromeos_switches.h" 172#elif defined(OS_LINUX) 173#include "chrome/browser/chrome_browser_main_linux.h" 174#elif defined(OS_ANDROID) 175#include "chrome/browser/android/webapps/single_tab_mode_tab_helper.h" 176#include "chrome/browser/chrome_browser_main_android.h" 177#include "chrome/browser/media/encrypted_media_message_filter_android.h" 178#include "chrome/common/descriptors_android.h" 179#include "components/breakpad/browser/crash_dump_manager_android.h" 180#elif defined(OS_POSIX) 181#include "chrome/browser/chrome_browser_main_posix.h" 182#endif 183 184#if defined(OS_POSIX) && !defined(OS_MACOSX) 185#include "base/debug/leak_annotations.h" 186#include "base/linux_util.h" 187#include "components/breakpad/app/breakpad_linux.h" 188#include "components/breakpad/browser/crash_handler_host_linux.h" 189#endif 190 191#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) 192#include "chrome/browser/captive_portal/captive_portal_tab_helper.h" 193#endif 194 195#if defined(OS_ANDROID) 196#include "ui/base/ui_base_paths.h" 197#include "ui/gfx/android/device_display_info.h" 198#endif 199 200#if !defined(OS_CHROMEOS) 201#include "chrome/browser/signin/signin_manager.h" 202#include "chrome/browser/signin/signin_manager_factory.h" 203#endif 204 205#if !defined(OS_ANDROID) 206#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h" 207#endif 208 209#if defined(ENABLE_WEBRTC) 210#include "chrome/browser/media/webrtc_logging_handler_host.h" 211#endif 212 213#if defined(ENABLE_INPUT_SPEECH) 214#include "chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.h" 215#endif 216 217#if defined(OS_CHROMEOS) 218#include "chrome/browser/chromeos/file_manager/app_id.h" 219#endif 220 221#if defined(TOOLKIT_GTK) 222#include "chrome/browser/ui/gtk/chrome_browser_main_extra_parts_gtk.h" 223#endif 224 225#if defined(TOOLKIT_VIEWS) 226#include "chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h" 227#endif 228 229#if defined(USE_ASH) 230#include "chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.h" 231#endif 232 233#if defined(USE_AURA) 234#include "chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.h" 235#endif 236 237#if defined(USE_X11) 238#include "chrome/browser/chrome_browser_main_extra_parts_x11.h" 239#endif 240 241#if defined(ENABLE_SPELLCHECK) 242#include "chrome/browser/spellchecker/spellcheck_message_filter.h" 243#endif 244 245using blink::WebWindowFeatures; 246using base::FileDescriptor; 247using content::AccessTokenStore; 248using content::BrowserChildProcessHostIterator; 249using content::BrowserThread; 250using content::BrowserURLHandler; 251using content::ChildProcessSecurityPolicy; 252using content::FileDescriptorInfo; 253using content::QuotaPermissionContext; 254using content::RenderViewHost; 255using content::SiteInstance; 256using content::WebContents; 257using extensions::APIPermission; 258using extensions::Extension; 259using extensions::InfoMap; 260using extensions::Manifest; 261using message_center::NotifierId; 262 263namespace { 264 265// Cached version of the locale so we can return the locale on the I/O 266// thread. 267base::LazyInstance<std::string> g_io_thread_application_locale; 268 269#if defined(ENABLE_PLUGINS) 270const char* kPredefinedAllowedFileHandleOrigins[] = { 271 "6EAED1924DB611B6EEF2A664BD077BE7EAD33B8F", // see crbug.com/234789 272 "4EB74897CB187C7633357C2FE832E0AD6A44883A" // see crbug.com/234789 273}; 274 275const char* kPredefinedAllowedSocketOrigins[] = { 276 "okddffdblfhhnmhodogpojmfkjmhinfp", // Test SSH Client 277 "pnhechapfaindjhompbnflcldabbghjo", // HTerm App (SSH Client) 278 "bglhmjfplikpjnfoegeomebmfnkjomhe", // see crbug.com/122126 279 "gbchcmhmhahfdphkhkmpfmihenigjmpp", // Chrome Remote Desktop 280 "kgngmbheleoaphbjbaiobfdepmghbfah", // Pre-release Chrome Remote Desktop 281 "odkaodonbgfohohmklejpjiejmcipmib", // Dogfood Chrome Remote Desktop 282 "ojoimpklfciegopdfgeenehpalipignm", // Chromoting canary 283 "cbkkbcmdlboombapidmoeolnmdacpkch", // see crbug.com/129089 284 "hhnbmknkdabfoieppbbljkhkfjcmcbjh", // see crbug.com/134099 285 "mablfbjkhmhkmefkjjacnbaikjkipphg", // see crbug.com/134099 286 "pdeelgamlgannhelgoegilelnnojegoh", // see crbug.com/134099 287 "cabapfdbkniadpollkckdnedaanlciaj", // see crbug.com/134099 288 "mapljbgnjledlpdmlchihnmeclmefbba", // see crbug.com/134099 289 "ghbfeebgmiidnnmeobbbaiamklmpbpii", // see crbug.com/134099 290 "jdfhpkjeckflbbleddjlpimecpbjdeep", // see crbug.com/142514 291 "iabmpiboiopbgfabjmgeedhcmjenhbla", // see crbug.com/165080 292 "B7CF8A292249681AF81771650BA4CEEAF19A4560", // see crbug.com/165080 293 "6EAED1924DB611B6EEF2A664BD077BE7EAD33B8F", // see crbug.com/234789 294 "4EB74897CB187C7633357C2FE832E0AD6A44883A", // see crbug.com/234789 295 "7525AF4F66763A70A883C4700529F647B470E4D2", // see crbug.com/238084 296 "0B549507088E1564D672F7942EB87CA4DAD73972", // see crbug.com/238084 297 "864288364E239573E777D3E0E36864E590E95C74" // see crbug.com/238084 298}; 299#endif 300 301// Returns a copy of the given url with its host set to given host and path set 302// to given path. Other parts of the url will be the same. 303GURL ReplaceURLHostAndPath(const GURL& url, 304 const std::string& host, 305 const std::string& path) { 306 url_canon::Replacements<char> replacements; 307 replacements.SetHost(host.c_str(), 308 url_parse::Component(0, host.length())); 309 replacements.SetPath(path.c_str(), 310 url_parse::Component(0, path.length())); 311 return url.ReplaceComponents(replacements); 312} 313 314// Maps "foo://bar/baz/" to "foo://chrome/bar/baz/". 315GURL AddUberHost(const GURL& url) { 316 const std::string uber_host = chrome::kChromeUIUberHost; 317 const std::string new_path = url.host() + url.path(); 318 319 return ReplaceURLHostAndPath(url, uber_host, new_path); 320} 321 322// If url->host() is "chrome" and url->path() has characters other than the 323// first slash, changes the url from "foo://chrome/bar/" to "foo://bar/" and 324// returns true. Otherwise returns false. 325bool RemoveUberHost(GURL* url) { 326 if (url->host() != chrome::kChromeUIUberHost) 327 return false; 328 329 if (url->path().empty() || url->path() == "/") 330 return false; 331 332 const std::string old_path = url->path(); 333 334 const std::string::size_type separator = old_path.find('/', 1); 335 std::string new_host; 336 std::string new_path; 337 if (separator == std::string::npos) { 338 new_host = old_path.substr(1); 339 } else { 340 new_host = old_path.substr(1, separator - 1); 341 new_path = old_path.substr(separator); 342 } 343 344 // Do not allow URLs with paths empty before the first slash since we can't 345 // have an empty host. (e.g "foo://chrome//") 346 if (new_host.empty()) 347 return false; 348 349 *url = ReplaceURLHostAndPath(*url, new_host, new_path); 350 351 DCHECK(url->is_valid()); 352 353 return true; 354} 355 356// Handles rewriting Web UI URLs. 357bool HandleWebUI(GURL* url, content::BrowserContext* browser_context) { 358 // Do not handle special URLs such as "about:foo" 359 if (!url->host().empty()) { 360 const GURL chrome_url = AddUberHost(*url); 361 362 // Handle valid "chrome://chrome/foo" URLs so the reverse handler will 363 // be called. 364 if (ChromeWebUIControllerFactory::GetInstance()->UseWebUIForURL( 365 browser_context, chrome_url)) 366 return true; 367 } 368 369 if (!ChromeWebUIControllerFactory::GetInstance()->UseWebUIForURL( 370 browser_context, *url)) 371 return false; 372 373#if defined(OS_CHROMEOS) 374 // Special case : in ChromeOS in Guest mode bookmarks and history are 375 // disabled for security reasons. New tab page explains the reasons, so 376 // we redirect user to new tab page. 377 if (chromeos::UserManager::Get()->IsLoggedInAsGuest()) { 378 if (url->SchemeIs(content::kChromeUIScheme) && 379 (url->DomainIs(chrome::kChromeUIBookmarksHost) || 380#if defined(ENABLE_ENHANCED_BOOKMARKS) 381 url->DomainIs(chrome::kChromeUIEnhancedBookmarksHost) || 382#endif 383 url->DomainIs(chrome::kChromeUIHistoryHost))) { 384 // Rewrite with new tab URL 385 *url = GURL(chrome::kChromeUINewTabURL); 386 } 387 } 388#endif 389 390 return true; 391} 392 393// Reverse URL handler for Web UI. Maps "chrome://chrome/foo/" to 394// "chrome://foo/". 395bool HandleWebUIReverse(GURL* url, content::BrowserContext* browser_context) { 396 if (!url->is_valid() || !url->SchemeIs(content::kChromeUIScheme)) 397 return false; 398 399 return RemoveUberHost(url); 400} 401 402// Used by the GetPrivilegeRequiredByUrl() and GetProcessPrivilege() functions 403// below. Extension, and isolated apps require different privileges to be 404// granted to their RenderProcessHosts. This classification allows us to make 405// sure URLs are served by hosts with the right set of privileges. 406enum RenderProcessHostPrivilege { 407 PRIV_NORMAL, 408 PRIV_HOSTED, 409 PRIV_ISOLATED, 410 PRIV_EXTENSION, 411}; 412 413RenderProcessHostPrivilege GetPrivilegeRequiredByUrl( 414 const GURL& url, 415 ExtensionService* service) { 416 // Default to a normal renderer cause it is lower privileged. This should only 417 // occur if the URL on a site instance is either malformed, or uninitialized. 418 // If it is malformed, then there is no need for better privileges anyways. 419 // If it is uninitialized, but eventually settles on being an a scheme other 420 // than normal webrenderer, the navigation logic will correct us out of band 421 // anyways. 422 if (!url.is_valid()) 423 return PRIV_NORMAL; 424 425 if (url.SchemeIs(extensions::kExtensionScheme)) { 426 const Extension* extension = 427 service->extensions()->GetByID(url.host()); 428 if (extension && 429 extensions::AppIsolationInfo::HasIsolatedStorage(extension)) 430 return PRIV_ISOLATED; 431 if (extension && extension->is_hosted_app()) 432 return PRIV_HOSTED; 433 434 return PRIV_EXTENSION; 435 } 436 437 return PRIV_NORMAL; 438} 439 440RenderProcessHostPrivilege GetProcessPrivilege( 441 content::RenderProcessHost* process_host, 442 extensions::ProcessMap* process_map, 443 ExtensionService* service) { 444 std::set<std::string> extension_ids = 445 process_map->GetExtensionsInProcess(process_host->GetID()); 446 if (extension_ids.empty()) 447 return PRIV_NORMAL; 448 449 for (std::set<std::string>::iterator iter = extension_ids.begin(); 450 iter != extension_ids.end(); ++iter) { 451 const Extension* extension = service->GetExtensionById(*iter, false); 452 if (extension && 453 extensions::AppIsolationInfo::HasIsolatedStorage(extension)) 454 return PRIV_ISOLATED; 455 if (extension && extension->is_hosted_app()) 456 return PRIV_HOSTED; 457 } 458 459 return PRIV_EXTENSION; 460} 461 462bool CertMatchesFilter(const net::X509Certificate& cert, 463 const base::DictionaryValue& filter) { 464 // TODO(markusheintz): This is the minimal required filter implementation. 465 // Implement a better matcher. 466 467 // An empty filter matches any client certificate since no requirements are 468 // specified at all. 469 if (filter.empty()) 470 return true; 471 472 std::string common_name; 473 if (filter.GetString("ISSUER.CN", &common_name) && 474 (cert.issuer().common_name == common_name)) { 475 return true; 476 } 477 return false; 478} 479 480#if !defined(OS_ANDROID) 481// Fills |map| with the per-script font prefs under path |map_name|. 482void FillFontFamilyMap(const PrefService* prefs, 483 const char* map_name, 484 webkit_glue::ScriptFontFamilyMap* map) { 485 // TODO: Get rid of the brute-force scan over possible (font family / script) 486 // combinations - see http://crbug.com/308095. 487 for (size_t i = 0; i < prefs::kWebKitScriptsForFontFamilyMapsLength; ++i) { 488 const char* script = prefs::kWebKitScriptsForFontFamilyMaps[i]; 489 std::string pref_name = base::StringPrintf("%s.%s", map_name, script); 490 std::string font_family = prefs->GetString(pref_name.c_str()); 491 if (!font_family.empty()) 492 (*map)[script] = base::UTF8ToUTF16(font_family); 493 } 494} 495 496#if defined(OS_POSIX) && !defined(OS_MACOSX) 497breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost( 498 const std::string& process_type) { 499 base::FilePath dumps_path; 500 PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path); 501 { 502 ANNOTATE_SCOPED_MEMORY_LEAK; 503 breakpad::CrashHandlerHostLinux* crash_handler = 504 new breakpad::CrashHandlerHostLinux( 505 process_type, dumps_path, getenv(env_vars::kHeadless) == NULL); 506 crash_handler->StartUploaderThread(); 507 return crash_handler; 508 } 509} 510 511int GetCrashSignalFD(const CommandLine& command_line) { 512 if (command_line.HasSwitch(extensions::switches::kExtensionProcess)) { 513 static breakpad::CrashHandlerHostLinux* crash_handler = NULL; 514 if (!crash_handler) 515 crash_handler = CreateCrashHandlerHost("extension"); 516 return crash_handler->GetDeathSignalSocket(); 517 } 518 519 std::string process_type = 520 command_line.GetSwitchValueASCII(switches::kProcessType); 521 522 if (process_type == switches::kRendererProcess) { 523 static breakpad::CrashHandlerHostLinux* crash_handler = NULL; 524 if (!crash_handler) 525 crash_handler = CreateCrashHandlerHost(process_type); 526 return crash_handler->GetDeathSignalSocket(); 527 } 528 529 if (process_type == switches::kPluginProcess) { 530 static breakpad::CrashHandlerHostLinux* crash_handler = NULL; 531 if (!crash_handler) 532 crash_handler = CreateCrashHandlerHost(process_type); 533 return crash_handler->GetDeathSignalSocket(); 534 } 535 536 if (process_type == switches::kPpapiPluginProcess) { 537 static breakpad::CrashHandlerHostLinux* crash_handler = NULL; 538 if (!crash_handler) 539 crash_handler = CreateCrashHandlerHost(process_type); 540 return crash_handler->GetDeathSignalSocket(); 541 } 542 543 if (process_type == switches::kGpuProcess) { 544 static breakpad::CrashHandlerHostLinux* crash_handler = NULL; 545 if (!crash_handler) 546 crash_handler = CreateCrashHandlerHost(process_type); 547 return crash_handler->GetDeathSignalSocket(); 548 } 549 550 return -1; 551} 552#endif // defined(OS_POSIX) && !defined(OS_MACOSX) 553#endif // !defined(OS_ANDROID) 554 555#if !defined(OS_CHROMEOS) 556GURL GetEffectiveURLForSignin(const GURL& url) { 557 CHECK(SigninManager::IsWebBasedSigninFlowURL(url)); 558 559 GURL effective_url(SigninManager::kChromeSigninEffectiveSite); 560 // Copy the path because the argument to SetPathStr must outlive 561 // the Replacements object. 562 const std::string path_copy(url.path()); 563 GURL::Replacements replacements; 564 replacements.SetPathStr(path_copy); 565 effective_url = effective_url.ReplaceComponents(replacements); 566 return effective_url; 567} 568#endif 569 570void SetApplicationLocaleOnIOThread(const std::string& locale) { 571 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 572 g_io_thread_application_locale.Get() = locale; 573} 574 575void HandleBlockedPopupOnUIThread(const BlockedWindowParams& params) { 576 WebContents* tab = tab_util::GetWebContentsByID(params.render_process_id(), 577 params.opener_id()); 578 if (!tab) 579 return; 580 581 prerender::PrerenderContents* prerender_contents = 582 prerender::PrerenderContents::FromWebContents(tab); 583 if (prerender_contents) { 584 prerender_contents->Destroy(prerender::FINAL_STATUS_CREATE_NEW_WINDOW); 585 return; 586 } 587 588 PopupBlockerTabHelper* popup_helper = 589 PopupBlockerTabHelper::FromWebContents(tab); 590 if (!popup_helper) 591 return; 592 popup_helper->AddBlockedPopup(params); 593} 594 595#if defined(OS_ANDROID) 596 597void HandleSingleTabModeBlockOnUIThread(const BlockedWindowParams& params) { 598 WebContents* web_contents = 599 tab_util::GetWebContentsByID(params.render_process_id(), 600 params.opener_id()); 601 if (!web_contents) 602 return; 603 604 SingleTabModeTabHelper::FromWebContents(web_contents)->HandleOpenUrl(params); 605} 606 607float GetDeviceScaleAdjustment() { 608 static const float kMinFSM = 1.05f; 609 static const int kWidthForMinFSM = 320; 610 static const float kMaxFSM = 1.3f; 611 static const int kWidthForMaxFSM = 800; 612 613 gfx::DeviceDisplayInfo info; 614 int minWidth = info.GetSmallestDIPWidth(); 615 616 if (minWidth <= kWidthForMinFSM) 617 return kMinFSM; 618 if (minWidth >= kWidthForMaxFSM) 619 return kMaxFSM; 620 621 // The font scale multiplier varies linearly between kMinFSM and kMaxFSM. 622 float ratio = static_cast<float>(minWidth - kWidthForMinFSM) / 623 (kWidthForMaxFSM - kWidthForMinFSM); 624 return ratio * (kMaxFSM - kMinFSM) + kMinFSM; 625} 626 627#endif // defined(OS_ANDROID) 628 629} // namespace 630 631namespace chrome { 632 633ChromeContentBrowserClient::ChromeContentBrowserClient() { 634#if defined(ENABLE_PLUGINS) 635 for (size_t i = 0; i < arraysize(kPredefinedAllowedFileHandleOrigins); ++i) 636 allowed_file_handle_origins_.insert(kPredefinedAllowedFileHandleOrigins[i]); 637 for (size_t i = 0; i < arraysize(kPredefinedAllowedSocketOrigins); ++i) 638 allowed_socket_origins_.insert(kPredefinedAllowedSocketOrigins[i]); 639#endif 640 641 permissions_policy_delegate_.reset( 642 new extensions::BrowserPermissionsPolicyDelegate()); 643} 644 645ChromeContentBrowserClient::~ChromeContentBrowserClient() { 646} 647 648// static 649void ChromeContentBrowserClient::RegisterProfilePrefs( 650 user_prefs::PrefRegistrySyncable* registry) { 651 registry->RegisterBooleanPref( 652 prefs::kDisable3DAPIs, 653 false, 654 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 655 registry->RegisterBooleanPref( 656 prefs::kEnableHyperlinkAuditing, 657 true, 658 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 659 registry->RegisterBooleanPref( 660 prefs::kEnableMemoryInfo, 661 false, 662 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 663} 664 665// static 666void ChromeContentBrowserClient::SetApplicationLocale( 667 const std::string& locale) { 668 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 669 670 // This object is guaranteed to outlive all threads so we don't have to 671 // worry about the lack of refcounting and can just post as Unretained. 672 // 673 // The common case is that this function is called early in Chrome startup 674 // before any threads are created (it will also be called later if the user 675 // changes the pref). In this case, there will be no threads created and 676 // posting will fail. When there are no threads, we can just set the string 677 // without worrying about threadsafety. 678 if (!BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 679 base::Bind(&SetApplicationLocaleOnIOThread, locale))) { 680 g_io_thread_application_locale.Get() = locale; 681 } 682} 683 684content::BrowserMainParts* ChromeContentBrowserClient::CreateBrowserMainParts( 685 const content::MainFunctionParams& parameters) { 686 ChromeBrowserMainParts* main_parts; 687 // Construct the Main browser parts based on the OS type. 688#if defined(OS_WIN) 689 main_parts = new ChromeBrowserMainPartsWin(parameters); 690#elif defined(OS_MACOSX) 691 main_parts = new ChromeBrowserMainPartsMac(parameters); 692#elif defined(OS_CHROMEOS) 693 main_parts = new chromeos::ChromeBrowserMainPartsChromeos(parameters); 694#elif defined(OS_LINUX) 695 main_parts = new ChromeBrowserMainPartsLinux(parameters); 696#elif defined(OS_ANDROID) 697 main_parts = new ChromeBrowserMainPartsAndroid(parameters); 698#elif defined(OS_POSIX) 699 main_parts = new ChromeBrowserMainPartsPosix(parameters); 700#else 701 NOTREACHED(); 702 main_parts = new ChromeBrowserMainParts(parameters); 703#endif 704 705 chrome::AddProfilesExtraParts(main_parts); 706 707 // Construct additional browser parts. Stages are called in the order in 708 // which they are added. 709#if defined(TOOLKIT_GTK) 710 main_parts->AddParts(new ChromeBrowserMainExtraPartsGtk()); 711#endif 712 713#if defined(TOOLKIT_VIEWS) 714 main_parts->AddParts(new ChromeBrowserMainExtraPartsViews()); 715#endif 716 717#if defined(USE_ASH) 718 main_parts->AddParts(new ChromeBrowserMainExtraPartsAsh()); 719#endif 720 721#if defined(USE_AURA) 722 main_parts->AddParts(new ChromeBrowserMainExtraPartsAura()); 723#endif 724 725#if defined(USE_X11) 726 main_parts->AddParts(new ChromeBrowserMainExtraPartsX11()); 727#endif 728 729 chrome::AddMetricsExtraParts(main_parts); 730 731 return main_parts; 732} 733 734std::string ChromeContentBrowserClient::GetStoragePartitionIdForSite( 735 content::BrowserContext* browser_context, 736 const GURL& site) { 737 std::string partition_id; 738 739 // The partition ID for webview guest processes is the string value of its 740 // SiteInstance URL - "chrome-guest://app_id/persist?partition". 741 if (site.SchemeIs(content::kGuestScheme)) 742 partition_id = site.spec(); 743 744 DCHECK(IsValidStoragePartitionId(browser_context, partition_id)); 745 return partition_id; 746} 747 748bool ChromeContentBrowserClient::IsValidStoragePartitionId( 749 content::BrowserContext* browser_context, 750 const std::string& partition_id) { 751 // The default ID is empty and is always valid. 752 if (partition_id.empty()) 753 return true; 754 755 return GURL(partition_id).is_valid(); 756} 757 758void ChromeContentBrowserClient::GetStoragePartitionConfigForSite( 759 content::BrowserContext* browser_context, 760 const GURL& site, 761 bool can_be_default, 762 std::string* partition_domain, 763 std::string* partition_name, 764 bool* in_memory) { 765 // Default to the browser-wide storage partition and override based on |site| 766 // below. 767 partition_domain->clear(); 768 partition_name->clear(); 769 *in_memory = false; 770 771 bool success = GuestView::GetGuestPartitionConfigForSite( 772 site, partition_domain, partition_name, in_memory); 773 774 if (!success && site.SchemeIs(extensions::kExtensionScheme)) { 775 // If |can_be_default| is false, the caller is stating that the |site| 776 // should be parsed as if it had isolated storage. In particular it is 777 // important to NOT check ExtensionService for the is_storage_isolated() 778 // attribute because this code path is run during Extension uninstall 779 // to do cleanup after the Extension has already been unloaded from the 780 // ExtensionService. 781 bool is_isolated = !can_be_default; 782 if (can_be_default) { 783 const Extension* extension = NULL; 784 Profile* profile = Profile::FromBrowserContext(browser_context); 785 ExtensionService* extension_service = 786 extensions::ExtensionSystem::Get(profile)->extension_service(); 787 if (extension_service) { 788 extension = 789 extension_service->extensions()->GetExtensionOrAppByURL(site); 790 if (extension && 791 extensions::AppIsolationInfo::HasIsolatedStorage(extension)) { 792 is_isolated = true; 793 } 794 } 795 } 796 797 if (is_isolated) { 798 CHECK(site.has_host()); 799 // For extensions with isolated storage, the the host of the |site| is 800 // the |partition_domain|. The |in_memory| and |partition_name| are only 801 // used in guest schemes so they are cleared here. 802 *partition_domain = site.host(); 803 *in_memory = false; 804 partition_name->clear(); 805 } 806 } else if (site.GetOrigin().spec() == kChromeUIChromeSigninURL) { 807 // Chrome signin page has an embedded iframe of extension and web content, 808 // thus it must be isolated from other webUI pages. 809 *partition_domain = chrome::kChromeUIChromeSigninHost; 810 } 811 812 // Assert that if |can_be_default| is false, the code above must have found a 813 // non-default partition. If this fails, the caller has a serious logic 814 // error about which StoragePartition they expect to be in and it is not 815 // safe to continue. 816 CHECK(can_be_default || !partition_domain->empty()); 817} 818 819content::WebContentsViewDelegate* 820 ChromeContentBrowserClient::GetWebContentsViewDelegate( 821 content::WebContents* web_contents) { 822 return chrome::CreateWebContentsViewDelegate(web_contents); 823} 824 825void ChromeContentBrowserClient::GuestWebContentsCreated( 826 SiteInstance* guest_site_instance, 827 WebContents* guest_web_contents, 828 WebContents* opener_web_contents, 829 content::BrowserPluginGuestDelegate** guest_delegate, 830 scoped_ptr<base::DictionaryValue> extra_params) { 831 if (!guest_site_instance) { 832 NOTREACHED(); 833 return; 834 } 835 GURL guest_site_url = guest_site_instance->GetSiteURL(); 836 const std::string& extension_id = guest_site_url.host(); 837 838 Profile* profile = Profile::FromBrowserContext( 839 guest_web_contents->GetBrowserContext()); 840 ExtensionService* service = 841 extensions::ExtensionSystem::Get(profile)->extension_service(); 842 if (!service) { 843 NOTREACHED(); 844 return; 845 } 846 847 /// TODO(fsamuel): In the future, certain types of GuestViews won't require 848 // extension bindings. At that point, we should clear |extension_id| instead 849 // of exiting early. 850 if (!service->GetExtensionById(extension_id, false) && 851 !CommandLine::ForCurrentProcess()->HasSwitch( 852 switches::kEnableBrowserPluginForAllViewTypes)) { 853 NOTREACHED(); 854 return; 855 } 856 857 if (opener_web_contents) { 858 GuestView* guest = GuestView::FromWebContents(opener_web_contents); 859 if (!guest) { 860 NOTREACHED(); 861 return; 862 } 863 864 // Create a new GuestView of the same type as the opener. 865 *guest_delegate = 866 GuestView::Create(guest_web_contents, 867 extension_id, 868 guest->GetViewType()); 869 return; 870 } 871 872 if (!extra_params) { 873 NOTREACHED(); 874 return; 875 } 876 std::string api_type; 877 extra_params->GetString(guestview::kParameterApi, &api_type); 878 879 if (api_type.empty()) 880 return; 881 882 *guest_delegate = 883 GuestView::Create(guest_web_contents, 884 extension_id, 885 GuestView::GetViewTypeFromString(api_type)); 886} 887 888void ChromeContentBrowserClient::GuestWebContentsAttached( 889 WebContents* guest_web_contents, 890 WebContents* embedder_web_contents, 891 const base::DictionaryValue& extra_params) { 892 893 GuestView* guest = GuestView::FromWebContents(guest_web_contents); 894 if (!guest) { 895 // It's ok to return here, since we could be running a browser plugin 896 // outside an extension, and don't need to attach a 897 // BrowserPluginGuestDelegate in that case; 898 // e.g. running with flag --enable-browser-plugin-for-all-view-types. 899 return; 900 } 901 guest->Attach(embedder_web_contents, extra_params); 902} 903 904void ChromeContentBrowserClient::RenderProcessWillLaunch( 905 content::RenderProcessHost* host) { 906 int id = host->GetID(); 907 Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext()); 908 net::URLRequestContextGetter* context = 909 profile->GetRequestContextForRenderProcess(id); 910 911 host->AddFilter(new ChromeRenderMessageFilter(id, profile, context)); 912 host->AddFilter(new extensions::ExtensionMessageFilter(id, profile)); 913#if defined(ENABLE_PLUGINS) 914 host->AddFilter(new PluginInfoMessageFilter(id, profile)); 915#endif 916 host->AddFilter(new cast::CastTransportHostFilter); 917#if defined(ENABLE_PRINTING) 918 host->AddFilter(new PrintingMessageFilter(id, profile)); 919#endif 920 host->AddFilter(new SearchProviderInstallStateMessageFilter(id, profile)); 921#if defined(ENABLE_SPELLCHECK) 922 host->AddFilter(new SpellCheckMessageFilter(id)); 923#endif 924#if defined(OS_MACOSX) 925 host->AddFilter(new SpellCheckMessageFilterMac(id)); 926#endif 927 host->AddFilter(new ChromeNetBenchmarkingMessageFilter(profile, context)); 928 host->AddFilter(new prerender::PrerenderMessageFilter(id, profile)); 929 host->AddFilter(new TtsMessageFilter(id, profile)); 930#if defined(ENABLE_WEBRTC) 931 WebRtcLoggingHandlerHost* webrtc_logging_handler_host = 932 new WebRtcLoggingHandlerHost(profile); 933 host->SetWebRtcLogMessageCallback(base::Bind( 934 &WebRtcLoggingHandlerHost::LogMessage, webrtc_logging_handler_host)); 935 host->AddFilter(webrtc_logging_handler_host); 936 host->SetUserData(host, new base::UserDataAdapter<WebRtcLoggingHandlerHost>( 937 webrtc_logging_handler_host)); 938#endif 939#if !defined(DISABLE_NACL) 940 host->AddFilter(new nacl::NaClHostMessageFilter( 941 id, profile->IsOffTheRecord(), 942 profile->GetPath(), 943 context)); 944#endif 945#if defined(OS_ANDROID) 946 host->AddFilter(new EncryptedMediaMessageFilterAndroid()); 947#endif 948 if (switches::IsNewProfileManagement()) 949 host->AddFilter(new PrincipalsMessageFilter(id)); 950 951 host->Send(new ChromeViewMsg_SetIsIncognitoProcess( 952 profile->IsOffTheRecord())); 953 954 SendExtensionWebRequestStatusToHost(host); 955 956 RendererContentSettingRules rules; 957 if (host->IsGuest()) { 958 GuestView::GetDefaultContentSettingRules(&rules, profile->IsOffTheRecord()); 959 } else { 960 GetRendererContentSettingRules( 961 profile->GetHostContentSettingsMap(), &rules); 962 } 963 host->Send(new ChromeViewMsg_SetContentSettingRules(rules)); 964} 965 966GURL ChromeContentBrowserClient::GetEffectiveURL( 967 content::BrowserContext* browser_context, const GURL& url) { 968 Profile* profile = Profile::FromBrowserContext(browser_context); 969 if (!profile) 970 return url; 971 972 // If the input |url| should be assigned to the Instant renderer, make its 973 // effective URL distinct from other URLs on the search provider's domain. 974 if (chrome::ShouldAssignURLToInstantRenderer(url, profile)) 975 return chrome::GetEffectiveURLForInstant(url, profile); 976 977#if !defined(OS_CHROMEOS) 978 // If the input |url| should be assigned to the Signin renderer, make its 979 // effective URL distinct from other URLs on the signin service's domain. 980 // Note that the signin renderer will be allowed to sign the user in to 981 // Chrome. 982 if (SigninManager::IsWebBasedSigninFlowURL(url)) 983 return GetEffectiveURLForSignin(url); 984#endif 985 986 // If the input |url| is part of an installed app, the effective URL is an 987 // extension URL with the ID of that extension as the host. This has the 988 // effect of grouping apps together in a common SiteInstance. 989 ExtensionService* extension_service = 990 extensions::ExtensionSystem::Get(profile)->extension_service(); 991 if (!extension_service) 992 return url; 993 994 const Extension* extension = extension_service->extensions()-> 995 GetHostedAppByURL(url); 996 if (!extension) 997 return url; 998 999 // Bookmark apps do not use the hosted app process model, and should be 1000 // treated as normal URLs. 1001 if (extension->from_bookmark()) 1002 return url; 1003 1004 // If the URL is part of an extension's web extent, convert it to an 1005 // extension URL. 1006 return extension->GetResourceURL(url.path()); 1007} 1008 1009bool ChromeContentBrowserClient::ShouldUseProcessPerSite( 1010 content::BrowserContext* browser_context, const GURL& effective_url) { 1011 // Non-extension, non-Instant URLs should generally use 1012 // process-per-site-instance. Because we expect to use the effective URL, 1013 // URLs for hosted apps (apart from bookmark apps) should have an extension 1014 // scheme by now. 1015 1016 Profile* profile = Profile::FromBrowserContext(browser_context); 1017 if (!profile) 1018 return false; 1019 1020 if (chrome::ShouldUseProcessPerSiteForInstantURL(effective_url, profile)) 1021 return true; 1022 1023#if !defined(OS_CHROMEOS) 1024 if (SigninManager::IsWebBasedSigninFlowURL(effective_url)) 1025 return true; 1026#endif 1027 1028 if (!effective_url.SchemeIs(extensions::kExtensionScheme)) 1029 return false; 1030 1031 ExtensionService* extension_service = 1032 extensions::ExtensionSystem::Get(profile)->extension_service(); 1033 if (!extension_service) 1034 return false; 1035 1036 const Extension* extension = 1037 extension_service->extensions()->GetExtensionOrAppByURL(effective_url); 1038 if (!extension) 1039 return false; 1040 1041 // If the URL is part of a hosted app that does not have the background 1042 // permission, or that does not allow JavaScript access to the background 1043 // page, we want to give each instance its own process to improve 1044 // responsiveness. 1045 if (extension->GetType() == Manifest::TYPE_HOSTED_APP) { 1046 if (!extension->HasAPIPermission(APIPermission::kBackground) || 1047 !extensions::BackgroundInfo::AllowJSAccess(extension)) { 1048 return false; 1049 } 1050 } 1051 1052 // Hosted apps that have script access to their background page must use 1053 // process per site, since all instances can make synchronous calls to the 1054 // background window. Other extensions should use process per site as well. 1055 return true; 1056} 1057 1058// These are treated as WebUI schemes but do not get WebUI bindings. Also, 1059// view-source is allowed for these schemes. 1060void ChromeContentBrowserClient::GetAdditionalWebUISchemes( 1061 std::vector<std::string>* additional_schemes) { 1062 additional_schemes->push_back(chrome::kChromeSearchScheme); 1063 additional_schemes->push_back(chrome::kDomDistillerScheme); 1064} 1065 1066net::URLRequestContextGetter* 1067ChromeContentBrowserClient::CreateRequestContext( 1068 content::BrowserContext* browser_context, 1069 content::ProtocolHandlerMap* protocol_handlers) { 1070 Profile* profile = Profile::FromBrowserContext(browser_context); 1071 return profile->CreateRequestContext(protocol_handlers); 1072} 1073 1074net::URLRequestContextGetter* 1075ChromeContentBrowserClient::CreateRequestContextForStoragePartition( 1076 content::BrowserContext* browser_context, 1077 const base::FilePath& partition_path, 1078 bool in_memory, 1079 content::ProtocolHandlerMap* protocol_handlers) { 1080 Profile* profile = Profile::FromBrowserContext(browser_context); 1081 return profile->CreateRequestContextForStoragePartition( 1082 partition_path, in_memory, protocol_handlers); 1083} 1084 1085bool ChromeContentBrowserClient::IsHandledURL(const GURL& url) { 1086 return ProfileIOData::IsHandledURL(url); 1087} 1088 1089bool ChromeContentBrowserClient::CanCommitURL( 1090 content::RenderProcessHost* process_host, 1091 const GURL& url) { 1092 // We need to let most extension URLs commit in any process, since this can 1093 // be allowed due to web_accessible_resources. Most hosted app URLs may also 1094 // load in any process (e.g., in an iframe). However, the Chrome Web Store 1095 // cannot be loaded in iframes and should never be requested outside its 1096 // process. 1097 Profile* profile = 1098 Profile::FromBrowserContext(process_host->GetBrowserContext()); 1099 ExtensionService* service = 1100 extensions::ExtensionSystem::Get(profile)->extension_service(); 1101 if (!service) 1102 return true; 1103 const Extension* new_extension = 1104 service->extensions()->GetExtensionOrAppByURL(url); 1105 if (new_extension && 1106 new_extension->is_hosted_app() && 1107 new_extension->id() == extension_misc::kWebStoreAppId && 1108 !extensions::ProcessMap::Get(profile)-> 1109 Contains(new_extension->id(), process_host->GetID())) { 1110 return false; 1111 } 1112 1113 return true; 1114} 1115 1116bool ChromeContentBrowserClient::ShouldAllowOpenURL( 1117 content::SiteInstance* site_instance, const GURL& url) { 1118 GURL from_url = site_instance->GetSiteURL(); 1119 // Do not allow pages from the web or other extensions navigate to 1120 // non-web-accessible extension resources. 1121 if (url.SchemeIs(extensions::kExtensionScheme) && 1122 (from_url.SchemeIsHTTPOrHTTPS() || 1123 from_url.SchemeIs(extensions::kExtensionScheme))) { 1124 Profile* profile = Profile::FromBrowserContext( 1125 site_instance->GetProcess()->GetBrowserContext()); 1126 ExtensionService* service = 1127 extensions::ExtensionSystem::Get(profile)->extension_service(); 1128 if (!service) 1129 return true; 1130 const Extension* extension = 1131 service->extensions()->GetExtensionOrAppByURL(url); 1132 if (!extension) 1133 return true; 1134 const Extension* from_extension = 1135 service->extensions()->GetExtensionOrAppByURL( 1136 site_instance->GetSiteURL()); 1137 if (from_extension && from_extension->id() == extension->id()) 1138 return true; 1139 1140 if (!extensions::WebAccessibleResourcesInfo::IsResourceWebAccessible( 1141 extension, url.path())) 1142 return false; 1143 } 1144 return true; 1145} 1146 1147bool ChromeContentBrowserClient::IsSuitableHost( 1148 content::RenderProcessHost* process_host, 1149 const GURL& site_url) { 1150 Profile* profile = 1151 Profile::FromBrowserContext(process_host->GetBrowserContext()); 1152 // This may be NULL during tests. In that case, just assume any site can 1153 // share any host. 1154 if (!profile) 1155 return true; 1156 1157 // Instant URLs should only be in the instant process and instant process 1158 // should only have Instant URLs. 1159 InstantService* instant_service = 1160 InstantServiceFactory::GetForProfile(profile); 1161 if (instant_service) { 1162 bool is_instant_process = instant_service->IsInstantProcess( 1163 process_host->GetID()); 1164 bool should_be_in_instant_process = 1165 chrome::ShouldAssignURLToInstantRenderer(site_url, profile); 1166 if (is_instant_process || should_be_in_instant_process) 1167 return is_instant_process && should_be_in_instant_process; 1168 } 1169 1170#if !defined(OS_CHROMEOS) 1171 SigninManager* signin_manager = SigninManagerFactory::GetForProfile(profile); 1172 if (signin_manager && signin_manager->IsSigninProcess(process_host->GetID())) 1173 return SigninManager::IsWebBasedSigninFlowURL(site_url); 1174#endif 1175 1176 ExtensionService* service = 1177 extensions::ExtensionSystem::Get(profile)->extension_service(); 1178 extensions::ProcessMap* process_map = extensions::ProcessMap::Get(profile); 1179 1180 // Don't allow the Task Manager to share a process with anything else. 1181 // Otherwise it can affect the renderers it is observing. 1182 // Note: we could create another RenderProcessHostPrivilege bucket for 1183 // this to allow multiple chrome://tasks instances to share, but that's 1184 // a very unlikely case without serious consequences. 1185 if (site_url.GetOrigin() == GURL(chrome::kChromeUITaskManagerURL).GetOrigin()) 1186 return false; 1187 1188 // These may be NULL during tests. In that case, just assume any site can 1189 // share any host. 1190 if (!service || !process_map) 1191 return true; 1192 1193 // Otherwise, just make sure the process privilege matches the privilege 1194 // required by the site. 1195 RenderProcessHostPrivilege privilege_required = 1196 GetPrivilegeRequiredByUrl(site_url, service); 1197 return GetProcessPrivilege(process_host, process_map, service) == 1198 privilege_required; 1199} 1200 1201// This function is trying to limit the amount of processes used by extensions 1202// with background pages. It uses a globally set percentage of processes to 1203// run such extensions and if the limit is exceeded, it returns true, to 1204// indicate to the content module to group extensions together. 1205bool ChromeContentBrowserClient::ShouldTryToUseExistingProcessHost( 1206 content::BrowserContext* browser_context, const GURL& url) { 1207 // It has to be a valid URL for us to check for an extension. 1208 if (!url.is_valid()) 1209 return false; 1210 1211 Profile* profile = Profile::FromBrowserContext(browser_context); 1212 ExtensionService* service = !profile ? NULL : 1213 extensions::ExtensionSystem::Get(profile)->extension_service(); 1214 if (!service) 1215 return false; 1216 1217 // We have to have a valid extension with background page to proceed. 1218 const Extension* extension = 1219 service->extensions()->GetExtensionOrAppByURL(url); 1220 if (!extension) 1221 return false; 1222 if (!extensions::BackgroundInfo::HasBackgroundPage(extension)) 1223 return false; 1224 1225 std::set<int> process_ids; 1226 size_t max_process_count = 1227 content::RenderProcessHost::GetMaxRendererProcessCount(); 1228 1229 // Go through all profiles to ensure we have total count of extension 1230 // processes containing background pages, otherwise one profile can 1231 // starve the other. 1232 std::vector<Profile*> profiles = g_browser_process->profile_manager()-> 1233 GetLoadedProfiles(); 1234 for (size_t i = 0; i < profiles.size(); ++i) { 1235 extensions::ProcessManager* epm = 1236 extensions::ExtensionSystem::Get(profiles[i])->process_manager(); 1237 for (extensions::ProcessManager::const_iterator iter = 1238 epm->background_hosts().begin(); 1239 iter != epm->background_hosts().end(); ++iter) { 1240 const extensions::ExtensionHost* host = *iter; 1241 process_ids.insert(host->render_process_host()->GetID()); 1242 } 1243 } 1244 1245 if (process_ids.size() > 1246 (max_process_count * chrome::kMaxShareOfExtensionProcesses)) { 1247 return true; 1248 } 1249 1250 return false; 1251} 1252 1253void ChromeContentBrowserClient::SiteInstanceGotProcess( 1254 SiteInstance* site_instance) { 1255 CHECK(site_instance->HasProcess()); 1256 1257 Profile* profile = Profile::FromBrowserContext( 1258 site_instance->GetBrowserContext()); 1259 if (!profile) 1260 return; 1261 1262 // Remember the ID of the Instant process to signal the renderer process 1263 // on startup in |AppendExtraCommandLineSwitches| below. 1264 if (chrome::ShouldAssignURLToInstantRenderer( 1265 site_instance->GetSiteURL(), profile)) { 1266 InstantService* instant_service = 1267 InstantServiceFactory::GetForProfile(profile); 1268 if (instant_service) 1269 instant_service->AddInstantProcess(site_instance->GetProcess()->GetID()); 1270 } 1271 1272#if !defined(OS_CHROMEOS) 1273 // We only expect there to be one signin process as we use process-per-site 1274 // for signin URLs. The signin process will be cleared from SigninManager 1275 // when the renderer is destroyed. 1276 if (SigninManager::IsWebBasedSigninFlowURL(site_instance->GetSiteURL())) { 1277 SigninManager* signin_manager = 1278 SigninManagerFactory::GetForProfile(profile); 1279 if (signin_manager) 1280 signin_manager->SetSigninProcess(site_instance->GetProcess()->GetID()); 1281 BrowserThread::PostTask( 1282 BrowserThread::IO, 1283 FROM_HERE, 1284 base::Bind(&InfoMap::SetSigninProcess, 1285 extensions::ExtensionSystem::Get(profile)->info_map(), 1286 site_instance->GetProcess()->GetID())); 1287 } 1288#endif 1289 1290 ExtensionService* service = 1291 extensions::ExtensionSystem::Get(profile)->extension_service(); 1292 if (!service) 1293 return; 1294 1295 const Extension* extension = service->extensions()->GetExtensionOrAppByURL( 1296 site_instance->GetSiteURL()); 1297 if (!extension) 1298 return; 1299 1300 extensions::ProcessMap::Get(profile) 1301 ->Insert(extension->id(), 1302 site_instance->GetProcess()->GetID(), 1303 site_instance->GetId()); 1304 1305 BrowserThread::PostTask( 1306 BrowserThread::IO, 1307 FROM_HERE, 1308 base::Bind(&InfoMap::RegisterExtensionProcess, 1309 extensions::ExtensionSystem::Get(profile)->info_map(), 1310 extension->id(), 1311 site_instance->GetProcess()->GetID(), 1312 site_instance->GetId())); 1313} 1314 1315void ChromeContentBrowserClient::SiteInstanceDeleting( 1316 SiteInstance* site_instance) { 1317 if (!site_instance->HasProcess()) 1318 return; 1319 1320 Profile* profile = Profile::FromBrowserContext( 1321 site_instance->GetBrowserContext()); 1322 ExtensionService* service = 1323 extensions::ExtensionSystem::Get(profile)->extension_service(); 1324 if (!service) 1325 return; 1326 1327 const Extension* extension = service->extensions()->GetExtensionOrAppByURL( 1328 site_instance->GetSiteURL()); 1329 if (!extension) 1330 return; 1331 1332 extensions::ProcessMap::Get(profile) 1333 ->Remove(extension->id(), 1334 site_instance->GetProcess()->GetID(), 1335 site_instance->GetId()); 1336 1337 BrowserThread::PostTask( 1338 BrowserThread::IO, 1339 FROM_HERE, 1340 base::Bind(&InfoMap::UnregisterExtensionProcess, 1341 extensions::ExtensionSystem::Get(profile)->info_map(), 1342 extension->id(), 1343 site_instance->GetProcess()->GetID(), 1344 site_instance->GetId())); 1345} 1346 1347void ChromeContentBrowserClient::WorkerProcessCreated( 1348 SiteInstance* site_instance, 1349 int worker_process_id) { 1350 extensions::ExtensionRegistry* extension_registry = 1351 extensions::ExtensionRegistry::Get(site_instance->GetBrowserContext()); 1352 if (!extension_registry) 1353 return; 1354 const Extension* extension = 1355 extension_registry->enabled_extensions().GetExtensionOrAppByURL( 1356 site_instance->GetSiteURL()); 1357 if (!extension) 1358 return; 1359 extensions::ExtensionSystem* extension_system = 1360 extensions::ExtensionSystem::Get(site_instance->GetBrowserContext()); 1361 extension_system->info_map()->RegisterExtensionWorkerProcess( 1362 extension->id(), 1363 worker_process_id, 1364 site_instance->GetId()); 1365} 1366 1367void ChromeContentBrowserClient::WorkerProcessTerminated( 1368 SiteInstance* site_instance, 1369 int worker_process_id) { 1370 extensions::ExtensionSystem* extension_system = 1371 extensions::ExtensionSystem::Get(site_instance->GetBrowserContext()); 1372 extension_system->info_map()->UnregisterExtensionWorkerProcess( 1373 worker_process_id); 1374} 1375 1376bool ChromeContentBrowserClient::ShouldSwapBrowsingInstancesForNavigation( 1377 SiteInstance* site_instance, 1378 const GURL& current_url, 1379 const GURL& new_url) { 1380 // If we don't have an ExtensionService, then rely on the SiteInstance logic 1381 // in RenderFrameHostManager to decide when to swap. 1382 Profile* profile = 1383 Profile::FromBrowserContext(site_instance->GetBrowserContext()); 1384 ExtensionService* service = 1385 extensions::ExtensionSystem::Get(profile)->extension_service(); 1386 if (!service) 1387 return false; 1388 1389 // We must use a new BrowsingInstance (forcing a process swap and disabling 1390 // scripting by existing tabs) if one of the URLs is an extension and the 1391 // other is not the exact same extension. 1392 // 1393 // We ignore hosted apps here so that other tabs in their BrowsingInstance can 1394 // use postMessage with them. (The exception is the Chrome Web Store, which 1395 // is a hosted app that requires its own BrowsingInstance.) Navigations 1396 // to/from a hosted app will still trigger a SiteInstance swap in 1397 // RenderFrameHostManager. 1398 const Extension* current_extension = 1399 service->extensions()->GetExtensionOrAppByURL(current_url); 1400 if (current_extension && 1401 current_extension->is_hosted_app() && 1402 current_extension->id() != extension_misc::kWebStoreAppId) 1403 current_extension = NULL; 1404 1405 const Extension* new_extension = 1406 service->extensions()->GetExtensionOrAppByURL(new_url); 1407 if (new_extension && 1408 new_extension->is_hosted_app() && 1409 new_extension->id() != extension_misc::kWebStoreAppId) 1410 new_extension = NULL; 1411 1412 // First do a process check. We should force a BrowsingInstance swap if the 1413 // current process doesn't know about new_extension, even if current_extension 1414 // is somehow the same as new_extension. 1415 extensions::ProcessMap* process_map = extensions::ProcessMap::Get(profile); 1416 if (new_extension && 1417 site_instance->HasProcess() && 1418 !process_map->Contains( 1419 new_extension->id(), site_instance->GetProcess()->GetID())) 1420 return true; 1421 1422 // Otherwise, swap BrowsingInstances if current_extension and new_extension 1423 // differ. 1424 return current_extension != new_extension; 1425} 1426 1427bool ChromeContentBrowserClient::ShouldSwapProcessesForRedirect( 1428 content::ResourceContext* resource_context, const GURL& current_url, 1429 const GURL& new_url) { 1430 ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context); 1431 return extensions::CrossesExtensionProcessBoundary( 1432 io_data->GetExtensionInfoMap()->extensions(), 1433 current_url, new_url, false); 1434} 1435 1436bool ChromeContentBrowserClient::ShouldAssignSiteForURL(const GURL& url) { 1437 return !url.SchemeIs(chrome::kChromeNativeScheme); 1438} 1439 1440std::string ChromeContentBrowserClient::GetCanonicalEncodingNameByAliasName( 1441 const std::string& alias_name) { 1442 return CharacterEncoding::GetCanonicalEncodingNameByAliasName(alias_name); 1443} 1444 1445void ChromeContentBrowserClient::AppendExtraCommandLineSwitches( 1446 CommandLine* command_line, int child_process_id) { 1447#if defined(OS_POSIX) 1448 if (breakpad::IsCrashReporterEnabled()) { 1449 std::string enable_crash_reporter; 1450 GoogleUpdateSettings::GetMetricsId(&enable_crash_reporter); 1451#if !defined(OS_MACOSX) 1452 enable_crash_reporter += "," + base::GetLinuxDistro(); 1453#endif 1454 command_line->AppendSwitchASCII(switches::kEnableCrashReporter, 1455 enable_crash_reporter); 1456 } 1457#endif // OS_POSIX 1458 1459 if (logging::DialogsAreSuppressed()) 1460 command_line->AppendSwitch(switches::kNoErrorDialogs); 1461 1462 std::string process_type = 1463 command_line->GetSwitchValueASCII(switches::kProcessType); 1464 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); 1465 1466 static const char* const kCommonSwitchNames[] = { 1467 switches::kUserDataDir, // Make logs go to the right file. 1468 }; 1469 command_line->CopySwitchesFrom(browser_command_line, kCommonSwitchNames, 1470 arraysize(kCommonSwitchNames)); 1471 1472#if defined(ENABLE_IPC_FUZZER) 1473 static const char* const kIpcFuzzerSwitches[] = { 1474 switches::kIpcFuzzerTestcase, 1475 }; 1476 command_line->CopySwitchesFrom(browser_command_line, kIpcFuzzerSwitches, 1477 arraysize(kIpcFuzzerSwitches)); 1478#endif 1479 1480 if (process_type == switches::kRendererProcess) { 1481#if defined(OS_CHROMEOS) 1482 const std::string& login_profile = 1483 browser_command_line.GetSwitchValueASCII( 1484 chromeos::switches::kLoginProfile); 1485 if (!login_profile.empty()) 1486 command_line->AppendSwitchASCII( 1487 chromeos::switches::kLoginProfile, login_profile); 1488#endif 1489 1490#if defined(ENABLE_WEBRTC) 1491#if defined(OS_ANDROID) 1492 const VersionInfo::Channel kMaxDisableEncryptionChannel = 1493 VersionInfo::CHANNEL_BETA; 1494#else 1495 const VersionInfo::Channel kMaxDisableEncryptionChannel = 1496 VersionInfo::CHANNEL_DEV; 1497#endif 1498 if (VersionInfo::GetChannel() <= kMaxDisableEncryptionChannel) { 1499 static const char* const kWebRtcDevSwitchNames[] = { 1500 switches::kDisableWebRtcEncryption, 1501 }; 1502 command_line->CopySwitchesFrom(browser_command_line, 1503 kWebRtcDevSwitchNames, 1504 arraysize(kWebRtcDevSwitchNames)); 1505 } 1506#endif 1507 1508 content::RenderProcessHost* process = 1509 content::RenderProcessHost::FromID(child_process_id); 1510 if (process) { 1511 Profile* profile = Profile::FromBrowserContext( 1512 process->GetBrowserContext()); 1513 1514 if (extensions::ProcessMap::Get(profile)->Contains(process->GetID())) 1515 command_line->AppendSwitch(extensions::switches::kExtensionProcess); 1516 1517 PrefService* prefs = profile->GetPrefs(); 1518 // Currently this pref is only registered if applied via a policy. 1519 if (prefs->HasPrefPath(prefs::kDisable3DAPIs) && 1520 prefs->GetBoolean(prefs::kDisable3DAPIs)) { 1521 // Turn this policy into a command line switch. 1522 command_line->AppendSwitch(switches::kDisable3DAPIs); 1523 } 1524 1525 // Disable client-side phishing detection in the renderer if it is 1526 // disabled in the Profile preferences or the browser process. 1527 if (!prefs->GetBoolean(prefs::kSafeBrowsingEnabled) || 1528 !g_browser_process->safe_browsing_detection_service()) { 1529 command_line->AppendSwitch( 1530 switches::kDisableClientSidePhishingDetection); 1531 } 1532 1533 if (!prefs->GetBoolean(prefs::kPrintPreviewDisabled)) 1534 command_line->AppendSwitch(switches::kRendererPrintPreview); 1535 1536 InstantService* instant_service = 1537 InstantServiceFactory::GetForProfile(profile); 1538 if (instant_service && 1539 instant_service->IsInstantProcess(process->GetID())) 1540 command_line->AppendSwitch(switches::kInstantProcess); 1541 1542#if !defined(OS_CHROMEOS) 1543 SigninManager* signin_manager = 1544 SigninManagerFactory::GetForProfile(profile); 1545 if (signin_manager && signin_manager->IsSigninProcess(process->GetID())) 1546 command_line->AppendSwitch(switches::kSigninProcess); 1547#endif 1548 } 1549 1550 // Please keep this in alphabetical order. 1551 static const char* const kSwitchNames[] = { 1552 autofill::switches::kDisableIgnoreAutocompleteOff, 1553 autofill::switches::kDisableInteractiveAutocomplete, 1554 autofill::switches::kDisablePasswordGeneration, 1555 autofill::switches::kEnableInteractiveAutocomplete, 1556 autofill::switches::kEnablePasswordGeneration, 1557 autofill::switches::kLocalHeuristicsOnlyForPasswordGeneration, 1558 extensions::switches::kAllowHTTPBackgroundPage, 1559 extensions::switches::kAllowLegacyExtensionManifests, 1560 extensions::switches::kAllowScriptingGallery, 1561 extensions::switches::kEnableExperimentalExtensionApis, 1562 extensions::switches::kExtensionsOnChromeURLs, 1563 // TODO(victorhsieh): remove the following flag once we move PPAPI FileIO 1564 // to browser. 1565 switches::kAllowNaClFileHandleAPI, 1566 switches::kAppsCheckoutURL, 1567 switches::kAppsGalleryURL, 1568 switches::kCloudPrintServiceURL, 1569 switches::kDisableBundledPpapiFlash, 1570 switches::kDisableExtensionsResourceWhitelist, 1571 switches::kDisablePnacl, 1572 switches::kDisableScriptedPrintThrottling, 1573 switches::kEnableAdview, 1574 switches::kEnableAppWindowControls, 1575 switches::kEnableBenchmarking, 1576 switches::kEnableNaCl, 1577 switches::kEnableNetBenchmarking, 1578 switches::kEnableStreamlinedHostedApps, 1579 switches::kEnableWatchdog, 1580 switches::kMemoryProfiling, 1581 switches::kMessageLoopHistogrammer, 1582 switches::kNoJsRandomness, 1583 switches::kOutOfProcessPdf, 1584 switches::kPlaybackMode, 1585 switches::kPpapiFlashArgs, 1586 switches::kPpapiFlashPath, 1587 switches::kPpapiFlashVersion, 1588 switches::kProfilingAtStart, 1589 switches::kProfilingFile, 1590 switches::kProfilingFlush, 1591 switches::kRecordMode, 1592 switches::kSilentDumpOnDCHECK, 1593 switches::kWhitelistedExtensionID, 1594 translate::switches::kTranslateSecurityOrigin, 1595 }; 1596 1597 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames, 1598 arraysize(kSwitchNames)); 1599 } else if (process_type == switches::kUtilityProcess) { 1600 static const char* const kSwitchNames[] = { 1601 extensions::switches::kAllowHTTPBackgroundPage, 1602 extensions::switches::kEnableExperimentalExtensionApis, 1603 extensions::switches::kExtensionsOnChromeURLs, 1604 switches::kWhitelistedExtensionID, 1605 }; 1606 1607 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames, 1608 arraysize(kSwitchNames)); 1609 } else if (process_type == switches::kPluginProcess) { 1610 static const char* const kSwitchNames[] = { 1611#if defined(OS_CHROMEOS) 1612 chromeos::switches::kLoginProfile, 1613#endif 1614 switches::kMemoryProfiling, 1615 switches::kSilentDumpOnDCHECK, 1616 }; 1617 1618 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames, 1619 arraysize(kSwitchNames)); 1620 } else if (process_type == switches::kZygoteProcess) { 1621 static const char* const kSwitchNames[] = { 1622 // Load (in-process) Pepper plugins in-process in the zygote pre-sandbox. 1623 switches::kDisableBundledPpapiFlash, 1624 switches::kPpapiFlashPath, 1625 switches::kPpapiFlashVersion, 1626 }; 1627 1628 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames, 1629 arraysize(kSwitchNames)); 1630 } else if (process_type == switches::kGpuProcess) { 1631 // If --ignore-gpu-blacklist is passed in, don't send in crash reports 1632 // because GPU is expected to be unreliable. 1633 if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) && 1634 !command_line->HasSwitch(switches::kDisableBreakpad)) 1635 command_line->AppendSwitch(switches::kDisableBreakpad); 1636 } 1637 1638 // The command line switch kEnableBenchmarking needs to be specified along 1639 // with the kEnableStatsTable switch to ensure that the stats table global 1640 // is initialized correctly. 1641 if (command_line->HasSwitch(switches::kEnableBenchmarking)) 1642 DCHECK(command_line->HasSwitch(switches::kEnableStatsTable)); 1643} 1644 1645std::string ChromeContentBrowserClient::GetApplicationLocale() { 1646 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) 1647 return g_io_thread_application_locale.Get(); 1648 return g_browser_process->GetApplicationLocale(); 1649} 1650 1651std::string ChromeContentBrowserClient::GetAcceptLangs( 1652 content::BrowserContext* context) { 1653 Profile* profile = Profile::FromBrowserContext(context); 1654 return profile->GetPrefs()->GetString(prefs::kAcceptLanguages); 1655} 1656 1657gfx::ImageSkia* ChromeContentBrowserClient::GetDefaultFavicon() { 1658 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 1659 return rb.GetImageSkiaNamed(IDR_DEFAULT_FAVICON); 1660} 1661 1662bool ChromeContentBrowserClient::AllowAppCache( 1663 const GURL& manifest_url, 1664 const GURL& first_party, 1665 content::ResourceContext* context) { 1666 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1667 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context); 1668 return io_data->GetCookieSettings()-> 1669 IsSettingCookieAllowed(manifest_url, first_party); 1670} 1671 1672bool ChromeContentBrowserClient::AllowGetCookie( 1673 const GURL& url, 1674 const GURL& first_party, 1675 const net::CookieList& cookie_list, 1676 content::ResourceContext* context, 1677 int render_process_id, 1678 int render_frame_id) { 1679 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1680 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context); 1681 bool allow = io_data->GetCookieSettings()-> 1682 IsReadingCookieAllowed(url, first_party); 1683 1684 BrowserThread::PostTask( 1685 BrowserThread::UI, FROM_HERE, 1686 base::Bind(&TabSpecificContentSettings::CookiesRead, render_process_id, 1687 render_frame_id, url, first_party, cookie_list, !allow)); 1688 return allow; 1689} 1690 1691bool ChromeContentBrowserClient::AllowSetCookie( 1692 const GURL& url, 1693 const GURL& first_party, 1694 const std::string& cookie_line, 1695 content::ResourceContext* context, 1696 int render_process_id, 1697 int render_frame_id, 1698 net::CookieOptions* options) { 1699 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1700 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context); 1701 CookieSettings* cookie_settings = io_data->GetCookieSettings(); 1702 bool allow = cookie_settings->IsSettingCookieAllowed(url, first_party); 1703 1704 BrowserThread::PostTask( 1705 BrowserThread::UI, FROM_HERE, 1706 base::Bind(&TabSpecificContentSettings::CookieChanged, render_process_id, 1707 render_frame_id, url, first_party, cookie_line, *options, 1708 !allow)); 1709 return allow; 1710} 1711 1712bool ChromeContentBrowserClient::AllowSaveLocalState( 1713 content::ResourceContext* context) { 1714 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1715 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context); 1716 CookieSettings* cookie_settings = io_data->GetCookieSettings(); 1717 ContentSetting setting = cookie_settings->GetDefaultCookieSetting(NULL); 1718 1719 // TODO(bauerb): Should we also disallow local state if the default is BLOCK? 1720 // Could we even support per-origin settings? 1721 return setting != CONTENT_SETTING_SESSION_ONLY; 1722} 1723 1724bool ChromeContentBrowserClient::AllowWorkerDatabase( 1725 const GURL& url, 1726 const base::string16& name, 1727 const base::string16& display_name, 1728 unsigned long estimated_size, 1729 content::ResourceContext* context, 1730 const std::vector<std::pair<int, int> >& render_frames) { 1731 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1732 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context); 1733 CookieSettings* cookie_settings = io_data->GetCookieSettings(); 1734 bool allow = cookie_settings->IsSettingCookieAllowed(url, url); 1735 1736 // Record access to database for potential display in UI. 1737 std::vector<std::pair<int, int> >::const_iterator i; 1738 for (i = render_frames.begin(); i != render_frames.end(); ++i) { 1739 BrowserThread::PostTask( 1740 BrowserThread::UI, FROM_HERE, 1741 base::Bind(&TabSpecificContentSettings::WebDatabaseAccessed, 1742 i->first, i->second, url, name, display_name, !allow)); 1743 } 1744 1745 return allow; 1746} 1747 1748bool ChromeContentBrowserClient::AllowWorkerFileSystem( 1749 const GURL& url, 1750 content::ResourceContext* context, 1751 const std::vector<std::pair<int, int> >& render_frames) { 1752 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1753 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context); 1754 CookieSettings* cookie_settings = io_data->GetCookieSettings(); 1755 bool allow = cookie_settings->IsSettingCookieAllowed(url, url); 1756 1757 // Record access to file system for potential display in UI. 1758 std::vector<std::pair<int, int> >::const_iterator i; 1759 for (i = render_frames.begin(); i != render_frames.end(); ++i) { 1760 BrowserThread::PostTask( 1761 BrowserThread::UI, FROM_HERE, 1762 base::Bind(&TabSpecificContentSettings::FileSystemAccessed, 1763 i->first, i->second, url, !allow)); 1764 } 1765 1766 return allow; 1767} 1768 1769bool ChromeContentBrowserClient::AllowWorkerIndexedDB( 1770 const GURL& url, 1771 const base::string16& name, 1772 content::ResourceContext* context, 1773 const std::vector<std::pair<int, int> >& render_frames) { 1774 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1775 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context); 1776 CookieSettings* cookie_settings = io_data->GetCookieSettings(); 1777 bool allow = cookie_settings->IsSettingCookieAllowed(url, url); 1778 1779 // Record access to IndexedDB for potential display in UI. 1780 std::vector<std::pair<int, int> >::const_iterator i; 1781 for (i = render_frames.begin(); i != render_frames.end(); ++i) { 1782 BrowserThread::PostTask( 1783 BrowserThread::UI, FROM_HERE, 1784 base::Bind(&TabSpecificContentSettings::IndexedDBAccessed, 1785 i->first, i->second, url, name, !allow)); 1786 } 1787 1788 return allow; 1789} 1790 1791net::URLRequestContext* 1792ChromeContentBrowserClient::OverrideRequestContextForURL( 1793 const GURL& url, content::ResourceContext* context) { 1794 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1795 if (url.SchemeIs(extensions::kExtensionScheme)) { 1796 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context); 1797 return io_data->extensions_request_context(); 1798 } 1799 1800 return NULL; 1801} 1802 1803QuotaPermissionContext* 1804ChromeContentBrowserClient::CreateQuotaPermissionContext() { 1805 return new ChromeQuotaPermissionContext(); 1806} 1807 1808void ChromeContentBrowserClient::AllowCertificateError( 1809 int render_process_id, 1810 int render_frame_id, 1811 int cert_error, 1812 const net::SSLInfo& ssl_info, 1813 const GURL& request_url, 1814 ResourceType::Type resource_type, 1815 bool overridable, 1816 bool strict_enforcement, 1817 const base::Callback<void(bool)>& callback, 1818 content::CertificateRequestResultType* result) { 1819 if (resource_type != ResourceType::MAIN_FRAME) { 1820 // A sub-resource has a certificate error. The user doesn't really 1821 // have a context for making the right decision, so block the 1822 // request hard, without an info bar to allow showing the insecure 1823 // content. 1824 *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY; 1825 return; 1826 } 1827 1828 // If the tab is being prerendered, cancel the prerender and the request. 1829 content::RenderFrameHost* render_frame_host = 1830 content::RenderFrameHost::FromID(render_process_id, render_frame_id); 1831 WebContents* tab = WebContents::FromRenderFrameHost(render_frame_host); 1832 if (!tab) { 1833 NOTREACHED(); 1834 return; 1835 } 1836 1837 prerender::PrerenderContents* prerender_contents = 1838 prerender::PrerenderContents::FromWebContents(tab); 1839 if (prerender_contents) { 1840 prerender_contents->Destroy(prerender::FINAL_STATUS_SSL_ERROR); 1841 *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL; 1842 return; 1843 } 1844 1845#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) 1846 captive_portal::CaptivePortalTabHelper* captive_portal_tab_helper = 1847 captive_portal::CaptivePortalTabHelper::FromWebContents(tab); 1848 if (captive_portal_tab_helper) 1849 captive_portal_tab_helper->OnSSLCertError(ssl_info); 1850#endif 1851 1852 // Otherwise, display an SSL blocking page. 1853 new SSLBlockingPage(tab, cert_error, ssl_info, request_url, overridable, 1854 strict_enforcement, callback); 1855} 1856 1857void ChromeContentBrowserClient::SelectClientCertificate( 1858 int render_process_id, 1859 int render_frame_id, 1860 const net::HttpNetworkSession* network_session, 1861 net::SSLCertRequestInfo* cert_request_info, 1862 const base::Callback<void(net::X509Certificate*)>& callback) { 1863 content::RenderFrameHost* rfh = content::RenderFrameHost::FromID( 1864 render_process_id, render_frame_id); 1865 WebContents* tab = WebContents::FromRenderFrameHost(rfh); 1866 if (!tab) { 1867 NOTREACHED(); 1868 return; 1869 } 1870 1871 prerender::PrerenderContents* prerender_contents = 1872 prerender::PrerenderContents::FromWebContents(tab); 1873 if (prerender_contents) { 1874 prerender_contents->Destroy( 1875 prerender::FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED); 1876 return; 1877 } 1878 1879 GURL requesting_url("https://" + cert_request_info->host_and_port.ToString()); 1880 DCHECK(requesting_url.is_valid()) 1881 << "Invalid URL string: https://" 1882 << cert_request_info->host_and_port.ToString(); 1883 1884 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext()); 1885 scoped_ptr<base::Value> filter( 1886 profile->GetHostContentSettingsMap()->GetWebsiteSetting( 1887 requesting_url, 1888 requesting_url, 1889 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE, 1890 std::string(), NULL)); 1891 1892 if (filter.get()) { 1893 // Try to automatically select a client certificate. 1894 if (filter->IsType(base::Value::TYPE_DICTIONARY)) { 1895 base::DictionaryValue* filter_dict = 1896 static_cast<base::DictionaryValue*>(filter.get()); 1897 1898 const std::vector<scoped_refptr<net::X509Certificate> >& 1899 all_client_certs = cert_request_info->client_certs; 1900 for (size_t i = 0; i < all_client_certs.size(); ++i) { 1901 if (CertMatchesFilter(*all_client_certs[i].get(), *filter_dict)) { 1902 // Use the first certificate that is matched by the filter. 1903 callback.Run(all_client_certs[i].get()); 1904 return; 1905 } 1906 } 1907 } else { 1908 NOTREACHED(); 1909 } 1910 } 1911 1912 SSLTabHelper* ssl_tab_helper = SSLTabHelper::FromWebContents(tab); 1913 if (!ssl_tab_helper) { 1914 // If there is no SSLTabHelper for the given WebContents then we can't 1915 // show the user a dialog to select a client certificate. So we simply 1916 // proceed with no client certificate. 1917 callback.Run(NULL); 1918 return; 1919 } 1920 ssl_tab_helper->ShowClientCertificateRequestDialog( 1921 network_session, cert_request_info, callback); 1922} 1923 1924void ChromeContentBrowserClient::AddCertificate( 1925 net::URLRequest* request, 1926 net::CertificateMimeType cert_type, 1927 const void* cert_data, 1928 size_t cert_size, 1929 int render_process_id, 1930 int render_view_id) { 1931 chrome::SSLAddCertificate(request, cert_type, cert_data, cert_size, 1932 render_process_id, render_view_id); 1933} 1934 1935content::MediaObserver* ChromeContentBrowserClient::GetMediaObserver() { 1936 return MediaCaptureDevicesDispatcher::GetInstance(); 1937} 1938 1939void ChromeContentBrowserClient::RequestDesktopNotificationPermission( 1940 const GURL& source_origin, 1941 int callback_context, 1942 int render_process_id, 1943 int render_view_id) { 1944#if defined(ENABLE_NOTIFICATIONS) 1945 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1946 WebContents* contents = 1947 tab_util::GetWebContentsByID(render_process_id, render_view_id); 1948 if (!contents) { 1949 NOTREACHED(); 1950 return; 1951 } 1952 1953 // Skip showing the infobar if the request comes from an extension, and that 1954 // extension has the 'notify' permission. (If the extension does not have the 1955 // permission, the user will still be prompted.) 1956 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); 1957 InfoMap* extension_info_map = 1958 extensions::ExtensionSystem::Get(profile)->info_map(); 1959 DesktopNotificationService* notification_service = 1960 DesktopNotificationServiceFactory::GetForProfile(profile); 1961 const Extension* extension = NULL; 1962 if (extension_info_map) { 1963 extensions::ExtensionSet extensions; 1964 extension_info_map->GetExtensionsWithAPIPermissionForSecurityOrigin( 1965 source_origin, render_process_id, 1966 extensions::APIPermission::kNotification, &extensions); 1967 for (extensions::ExtensionSet::const_iterator iter = extensions.begin(); 1968 iter != extensions.end(); ++iter) { 1969 if (notification_service->IsNotifierEnabled(NotifierId( 1970 NotifierId::APPLICATION, (*iter)->id()))) { 1971 extension = iter->get(); 1972 break; 1973 } 1974 } 1975 } 1976 RenderViewHost* rvh = 1977 RenderViewHost::FromID(render_process_id, render_view_id); 1978 if (IsExtensionWithPermissionOrSuggestInConsole( 1979 APIPermission::kNotification, extension, rvh)) { 1980 if (rvh) 1981 rvh->DesktopNotificationPermissionRequestDone(callback_context); 1982 return; 1983 } 1984 1985 notification_service->RequestPermission(source_origin, render_process_id, 1986 render_view_id, callback_context, contents); 1987#else 1988 NOTIMPLEMENTED(); 1989#endif 1990} 1991 1992blink::WebNotificationPresenter::Permission 1993 ChromeContentBrowserClient::CheckDesktopNotificationPermission( 1994 const GURL& source_origin, 1995 content::ResourceContext* context, 1996 int render_process_id) { 1997#if defined(ENABLE_NOTIFICATIONS) 1998 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1999 2000 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context); 2001 InfoMap* extension_info_map = io_data->GetExtensionInfoMap(); 2002 2003 // We want to see if there is an extension that hasn't been manually disabled 2004 // that has the notifications permission and applies to this security origin. 2005 // First, get the list of extensions with permission for the origin. 2006 extensions::ExtensionSet extensions; 2007 extension_info_map->GetExtensionsWithAPIPermissionForSecurityOrigin( 2008 source_origin, render_process_id, 2009 extensions::APIPermission::kNotification, &extensions); 2010 for (extensions::ExtensionSet::const_iterator iter = extensions.begin(); 2011 iter != extensions.end(); ++iter) { 2012 // Then, check to see if it's been disabled by the user. 2013 if (!extension_info_map->AreNotificationsDisabled((*iter)->id())) 2014 return blink::WebNotificationPresenter::PermissionAllowed; 2015 } 2016 2017 // No enabled extensions exist, so check the normal host content settings. 2018 HostContentSettingsMap* host_content_settings_map = 2019 io_data->GetHostContentSettingsMap(); 2020 ContentSetting setting = host_content_settings_map->GetContentSetting( 2021 source_origin, 2022 source_origin, 2023 CONTENT_SETTINGS_TYPE_NOTIFICATIONS, 2024 NO_RESOURCE_IDENTIFIER); 2025 2026 if (setting == CONTENT_SETTING_ALLOW) 2027 return blink::WebNotificationPresenter::PermissionAllowed; 2028 if (setting == CONTENT_SETTING_BLOCK) 2029 return blink::WebNotificationPresenter::PermissionDenied; 2030 return blink::WebNotificationPresenter::PermissionNotAllowed; 2031#else 2032 return blink::WebNotificationPresenter::PermissionAllowed; 2033#endif 2034} 2035 2036void ChromeContentBrowserClient::ShowDesktopNotification( 2037 const content::ShowDesktopNotificationHostMsgParams& params, 2038 int render_process_id, 2039 int render_view_id, 2040 bool worker) { 2041#if defined(ENABLE_NOTIFICATIONS) 2042 RenderViewHost* rvh = RenderViewHost::FromID( 2043 render_process_id, render_view_id); 2044 if (!rvh) { 2045 NOTREACHED(); 2046 return; 2047 } 2048 2049 content::RenderProcessHost* process = rvh->GetProcess(); 2050 Profile* profile = Profile::FromBrowserContext(process->GetBrowserContext()); 2051 DesktopNotificationService* service = 2052 DesktopNotificationServiceFactory::GetForProfile(profile); 2053 service->ShowDesktopNotification( 2054 params, render_process_id, render_view_id, 2055 worker ? DesktopNotificationService::WorkerNotification : 2056 DesktopNotificationService::PageNotification); 2057#else 2058 NOTIMPLEMENTED(); 2059#endif 2060} 2061 2062void ChromeContentBrowserClient::CancelDesktopNotification( 2063 int render_process_id, 2064 int render_view_id, 2065 int notification_id) { 2066#if defined(ENABLE_NOTIFICATIONS) 2067 RenderViewHost* rvh = RenderViewHost::FromID( 2068 render_process_id, render_view_id); 2069 if (!rvh) { 2070 NOTREACHED(); 2071 return; 2072 } 2073 2074 content::RenderProcessHost* process = rvh->GetProcess(); 2075 Profile* profile = Profile::FromBrowserContext(process->GetBrowserContext()); 2076 DesktopNotificationService* service = 2077 DesktopNotificationServiceFactory::GetForProfile(profile); 2078 service->CancelDesktopNotification( 2079 render_process_id, render_view_id, notification_id); 2080#else 2081 NOTIMPLEMENTED(); 2082#endif 2083} 2084 2085bool ChromeContentBrowserClient::CanCreateWindow( 2086 const GURL& opener_url, 2087 const GURL& opener_top_level_frame_url, 2088 const GURL& source_origin, 2089 WindowContainerType container_type, 2090 const GURL& target_url, 2091 const content::Referrer& referrer, 2092 WindowOpenDisposition disposition, 2093 const WebWindowFeatures& features, 2094 bool user_gesture, 2095 bool opener_suppressed, 2096 content::ResourceContext* context, 2097 int render_process_id, 2098 bool is_guest, 2099 int opener_id, 2100 bool* no_javascript_access) { 2101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 2102 2103 *no_javascript_access = false; 2104 2105 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context); 2106 InfoMap* map = io_data->GetExtensionInfoMap(); 2107 2108 // If the opener is trying to create a background window but doesn't have 2109 // the appropriate permission, fail the attempt. 2110 if (container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) { 2111 if (!map->SecurityOriginHasAPIPermission( 2112 source_origin, 2113 render_process_id, 2114 APIPermission::kBackground)) { 2115 return false; 2116 } 2117 2118 // Note: this use of GetExtensionOrAppByURL is safe but imperfect. It may 2119 // return a recently installed Extension even if this CanCreateWindow call 2120 // was made by an old copy of the page in a normal web process. That's ok, 2121 // because the permission check above would have caused an early return 2122 // already. We must use the full URL to find hosted apps, though, and not 2123 // just the origin. 2124 const Extension* extension = 2125 map->extensions().GetExtensionOrAppByURL(opener_url); 2126 if (extension && !extensions::BackgroundInfo::AllowJSAccess(extension)) 2127 *no_javascript_access = true; 2128 2129 return true; 2130 } 2131 2132 // No new browser window (popup or tab) in app mode. 2133 if (container_type == WINDOW_CONTAINER_TYPE_NORMAL && 2134 chrome::IsRunningInForcedAppMode()) { 2135 return false; 2136 } 2137 2138 if (is_guest) 2139 return true; 2140 2141 HostContentSettingsMap* content_settings = 2142 ProfileIOData::FromResourceContext(context)->GetHostContentSettingsMap(); 2143 BlockedWindowParams blocked_params(target_url, 2144 referrer, 2145 disposition, 2146 features, 2147 user_gesture, 2148 opener_suppressed, 2149 render_process_id, 2150 opener_id); 2151 2152 if (!user_gesture && !CommandLine::ForCurrentProcess()->HasSwitch( 2153 switches::kDisablePopupBlocking)) { 2154 if (content_settings->GetContentSetting(opener_top_level_frame_url, 2155 opener_top_level_frame_url, 2156 CONTENT_SETTINGS_TYPE_POPUPS, 2157 std::string()) != 2158 CONTENT_SETTING_ALLOW) { 2159 BrowserThread::PostTask(BrowserThread::UI, 2160 FROM_HERE, 2161 base::Bind(&HandleBlockedPopupOnUIThread, 2162 blocked_params)); 2163 return false; 2164 } 2165 } 2166 2167#if defined(OS_ANDROID) 2168 if (SingleTabModeTabHelper::IsRegistered(render_process_id, opener_id)) { 2169 BrowserThread::PostTask(BrowserThread::UI, 2170 FROM_HERE, 2171 base::Bind(&HandleSingleTabModeBlockOnUIThread, 2172 blocked_params)); 2173 return false; 2174 } 2175#endif 2176 2177 return true; 2178} 2179 2180std::string ChromeContentBrowserClient::GetWorkerProcessTitle( 2181 const GURL& url, content::ResourceContext* context) { 2182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 2183 // Check if it's an extension-created worker, in which case we want to use 2184 // the name of the extension. 2185 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context); 2186 const Extension* extension = 2187 io_data->GetExtensionInfoMap()->extensions().GetByID(url.host()); 2188 return extension ? extension->name() : std::string(); 2189} 2190 2191void ChromeContentBrowserClient::ResourceDispatcherHostCreated() { 2192 return g_browser_process->ResourceDispatcherHostCreated(); 2193} 2194 2195// TODO(tommi): Rename from Get to Create. 2196content::SpeechRecognitionManagerDelegate* 2197 ChromeContentBrowserClient::GetSpeechRecognitionManagerDelegate() { 2198#if defined(ENABLE_INPUT_SPEECH) 2199 return new speech::ChromeSpeechRecognitionManagerDelegateBubbleUI(); 2200#else 2201 // Platforms who don't implement x-webkit-speech (a.k.a INPUT_SPEECH) just 2202 // need the base delegate without the bubble UI. 2203 return new speech::ChromeSpeechRecognitionManagerDelegate(); 2204#endif 2205} 2206 2207net::NetLog* ChromeContentBrowserClient::GetNetLog() { 2208 return g_browser_process->net_log(); 2209} 2210 2211AccessTokenStore* ChromeContentBrowserClient::CreateAccessTokenStore() { 2212 return new ChromeAccessTokenStore(); 2213} 2214 2215bool ChromeContentBrowserClient::IsFastShutdownPossible() { 2216 return true; 2217} 2218 2219void ChromeContentBrowserClient::OverrideWebkitPrefs( 2220 RenderViewHost* rvh, const GURL& url, WebPreferences* web_prefs) { 2221 Profile* profile = Profile::FromBrowserContext( 2222 rvh->GetProcess()->GetBrowserContext()); 2223 PrefService* prefs = profile->GetPrefs(); 2224 2225 // Fill per-script font preferences. These are not registered on Android 2226 // - http://crbug.com/308033. 2227#if !defined(OS_ANDROID) 2228 FillFontFamilyMap(prefs, prefs::kWebKitStandardFontFamilyMap, 2229 &web_prefs->standard_font_family_map); 2230 FillFontFamilyMap(prefs, prefs::kWebKitFixedFontFamilyMap, 2231 &web_prefs->fixed_font_family_map); 2232 FillFontFamilyMap(prefs, prefs::kWebKitSerifFontFamilyMap, 2233 &web_prefs->serif_font_family_map); 2234 FillFontFamilyMap(prefs, prefs::kWebKitSansSerifFontFamilyMap, 2235 &web_prefs->sans_serif_font_family_map); 2236 FillFontFamilyMap(prefs, prefs::kWebKitCursiveFontFamilyMap, 2237 &web_prefs->cursive_font_family_map); 2238 FillFontFamilyMap(prefs, prefs::kWebKitFantasyFontFamilyMap, 2239 &web_prefs->fantasy_font_family_map); 2240 FillFontFamilyMap(prefs, prefs::kWebKitPictographFontFamilyMap, 2241 &web_prefs->pictograph_font_family_map); 2242#endif 2243 2244 web_prefs->default_font_size = 2245 prefs->GetInteger(prefs::kWebKitDefaultFontSize); 2246 web_prefs->default_fixed_font_size = 2247 prefs->GetInteger(prefs::kWebKitDefaultFixedFontSize); 2248 web_prefs->minimum_font_size = 2249 prefs->GetInteger(prefs::kWebKitMinimumFontSize); 2250 web_prefs->minimum_logical_font_size = 2251 prefs->GetInteger(prefs::kWebKitMinimumLogicalFontSize); 2252 2253 web_prefs->default_encoding = prefs->GetString(prefs::kDefaultCharset); 2254 2255 web_prefs->javascript_can_open_windows_automatically = 2256 prefs->GetBoolean(prefs::kWebKitJavascriptCanOpenWindowsAutomatically); 2257 web_prefs->dom_paste_enabled = 2258 prefs->GetBoolean(prefs::kWebKitDomPasteEnabled); 2259 web_prefs->shrinks_standalone_images_to_fit = 2260 prefs->GetBoolean(prefs::kWebKitShrinksStandaloneImagesToFit); 2261 const base::DictionaryValue* inspector_settings = 2262 prefs->GetDictionary(prefs::kWebKitInspectorSettings); 2263 if (inspector_settings) { 2264 for (base::DictionaryValue::Iterator iter(*inspector_settings); 2265 !iter.IsAtEnd(); 2266 iter.Advance()) { 2267 std::string value; 2268 if (iter.value().GetAsString(&value)) { 2269 web_prefs->inspector_settings.push_back( 2270 std::make_pair(iter.key(), value)); 2271 } 2272 } 2273 } 2274 web_prefs->tabs_to_links = prefs->GetBoolean(prefs::kWebkitTabsToLinks); 2275 2276 if (!prefs->GetBoolean(prefs::kWebKitJavascriptEnabled)) 2277 web_prefs->javascript_enabled = false; 2278 if (!prefs->GetBoolean(prefs::kWebKitWebSecurityEnabled)) 2279 web_prefs->web_security_enabled = false; 2280 if (!prefs->GetBoolean(prefs::kWebKitPluginsEnabled)) 2281 web_prefs->plugins_enabled = false; 2282 if (!prefs->GetBoolean(prefs::kWebKitJavaEnabled)) 2283 web_prefs->java_enabled = false; 2284 web_prefs->loads_images_automatically = 2285 prefs->GetBoolean(prefs::kWebKitLoadsImagesAutomatically); 2286 2287 if (prefs->GetBoolean(prefs::kDisable3DAPIs)) 2288 web_prefs->experimental_webgl_enabled = false; 2289 2290 web_prefs->memory_info_enabled = 2291 prefs->GetBoolean(prefs::kEnableMemoryInfo); 2292 web_prefs->allow_displaying_insecure_content = 2293 prefs->GetBoolean(prefs::kWebKitAllowDisplayingInsecureContent); 2294 web_prefs->allow_running_insecure_content = 2295 prefs->GetBoolean(prefs::kWebKitAllowRunningInsecureContent); 2296#if defined(OS_ANDROID) 2297 web_prefs->font_scale_factor = 2298 static_cast<float>(prefs->GetDouble(prefs::kWebKitFontScaleFactor)); 2299 web_prefs->device_scale_adjustment = GetDeviceScaleAdjustment(); 2300 web_prefs->force_enable_zoom = 2301 prefs->GetBoolean(prefs::kWebKitForceEnableZoom); 2302#endif 2303 2304#if defined(OS_ANDROID) 2305 web_prefs->password_echo_enabled = 2306 prefs->GetBoolean(prefs::kWebKitPasswordEchoEnabled); 2307#else 2308 web_prefs->password_echo_enabled = browser_defaults::kPasswordEchoEnabled; 2309#endif 2310 2311 web_prefs->asynchronous_spell_checking_enabled = true; 2312 web_prefs->unified_textchecker_enabled = true; 2313 2314 web_prefs->uses_universal_detector = 2315 prefs->GetBoolean(prefs::kWebKitUsesUniversalDetector); 2316 web_prefs->text_areas_are_resizable = 2317 prefs->GetBoolean(prefs::kWebKitTextAreasAreResizable); 2318 web_prefs->hyperlink_auditing_enabled = 2319 prefs->GetBoolean(prefs::kEnableHyperlinkAuditing); 2320 2321 // Make sure we will set the default_encoding with canonical encoding name. 2322 web_prefs->default_encoding = 2323 CharacterEncoding::GetCanonicalEncodingNameByAliasName( 2324 web_prefs->default_encoding); 2325 if (web_prefs->default_encoding.empty()) { 2326 prefs->ClearPref(prefs::kDefaultCharset); 2327 web_prefs->default_encoding = prefs->GetString(prefs::kDefaultCharset); 2328 } 2329 DCHECK(!web_prefs->default_encoding.empty()); 2330 2331 WebContents* web_contents = WebContents::FromRenderViewHost(rvh); 2332 extensions::ViewType view_type = extensions::GetViewType(web_contents); 2333 ExtensionService* service = 2334 extensions::ExtensionSystem::Get(profile)->extension_service(); 2335 if (service) { 2336 const GURL& site_url = rvh->GetSiteInstance()->GetSiteURL(); 2337 const Extension* extension = 2338 service->extensions()->GetByID(site_url.host()); 2339 // Ensure that we are only granting extension preferences to URLs with 2340 // the correct scheme. Without this check, chrome-guest:// schemes used by 2341 // webview tags as well as hosts that happen to match the id of an 2342 // installed extension would get the wrong preferences. 2343 if (site_url.SchemeIs(extensions::kExtensionScheme)) { 2344 extension_webkit_preferences::SetPreferences( 2345 extension, view_type, web_prefs); 2346 } 2347 } 2348 2349 if (view_type == extensions::VIEW_TYPE_NOTIFICATION) { 2350 web_prefs->allow_scripts_to_close_windows = true; 2351 } else if (view_type == extensions::VIEW_TYPE_BACKGROUND_CONTENTS) { 2352 // Disable all kinds of acceleration for background pages. 2353 // See http://crbug.com/96005 and http://crbug.com/96006 2354 web_prefs->force_compositing_mode = false; 2355 web_prefs->accelerated_compositing_enabled = false; 2356 } 2357 2358#if defined(OS_CHROMEOS) 2359 // Override the default of suppressing HW compositing for WebUI pages for the 2360 // file manager, which is implemented using WebUI but wants HW acceleration 2361 // for video decode & render. 2362 if (url.SchemeIs(extensions::kExtensionScheme) && 2363 url.host() == file_manager::kFileManagerAppId) { 2364 web_prefs->accelerated_compositing_enabled = true; 2365 web_prefs->accelerated_2d_canvas_enabled = true; 2366 } 2367#endif 2368} 2369 2370void ChromeContentBrowserClient::UpdateInspectorSetting( 2371 RenderViewHost* rvh, const std::string& key, const std::string& value) { 2372 content::BrowserContext* browser_context = 2373 rvh->GetProcess()->GetBrowserContext(); 2374 DictionaryPrefUpdate update( 2375 Profile::FromBrowserContext(browser_context)->GetPrefs(), 2376 prefs::kWebKitInspectorSettings); 2377 base::DictionaryValue* inspector_settings = update.Get(); 2378 inspector_settings->SetWithoutPathExpansion( 2379 key, base::Value::CreateStringValue(value)); 2380} 2381 2382void ChromeContentBrowserClient::BrowserURLHandlerCreated( 2383 BrowserURLHandler* handler) { 2384 // Add the default URL handlers. 2385 handler->AddHandlerPair(&ExtensionWebUI::HandleChromeURLOverride, 2386 BrowserURLHandler::null_handler()); 2387 handler->AddHandlerPair(BrowserURLHandler::null_handler(), 2388 &ExtensionWebUI::HandleChromeURLOverrideReverse); 2389 2390 // about: handler. Must come before chrome: handler, since it will 2391 // rewrite about: urls to chrome: URLs and then expect chrome: to 2392 // actually handle them. 2393 handler->AddHandlerPair(&WillHandleBrowserAboutURL, 2394 BrowserURLHandler::null_handler()); 2395 2396 // Handler to rewrite chrome://newtab for InstantExtended. 2397 handler->AddHandlerPair(&chrome::HandleNewTabURLRewrite, 2398 &chrome::HandleNewTabURLReverseRewrite); 2399 2400 // chrome: & friends. 2401 handler->AddHandlerPair(&HandleWebUI, &HandleWebUIReverse); 2402} 2403 2404void ChromeContentBrowserClient::ClearCache(RenderViewHost* rvh) { 2405 Profile* profile = Profile::FromBrowserContext( 2406 rvh->GetSiteInstance()->GetProcess()->GetBrowserContext()); 2407 BrowsingDataRemover* remover = 2408 BrowsingDataRemover::CreateForUnboundedRange(profile); 2409 remover->Remove(BrowsingDataRemover::REMOVE_CACHE, 2410 BrowsingDataHelper::UNPROTECTED_WEB); 2411 // BrowsingDataRemover takes care of deleting itself when done. 2412} 2413 2414void ChromeContentBrowserClient::ClearCookies(RenderViewHost* rvh) { 2415 Profile* profile = Profile::FromBrowserContext( 2416 rvh->GetSiteInstance()->GetProcess()->GetBrowserContext()); 2417 BrowsingDataRemover* remover = 2418 BrowsingDataRemover::CreateForUnboundedRange(profile); 2419 int remove_mask = BrowsingDataRemover::REMOVE_SITE_DATA; 2420 remover->Remove(remove_mask, BrowsingDataHelper::UNPROTECTED_WEB); 2421 // BrowsingDataRemover takes care of deleting itself when done. 2422} 2423 2424base::FilePath ChromeContentBrowserClient::GetDefaultDownloadDirectory() { 2425 return DownloadPrefs::GetDefaultDownloadDirectory(); 2426} 2427 2428std::string ChromeContentBrowserClient::GetDefaultDownloadName() { 2429 return l10n_util::GetStringUTF8(IDS_DEFAULT_DOWNLOAD_FILENAME); 2430} 2431 2432void ChromeContentBrowserClient::DidCreatePpapiPlugin( 2433 content::BrowserPpapiHost* browser_host) { 2434#if defined(ENABLE_PLUGINS) 2435 browser_host->GetPpapiHost()->AddHostFactoryFilter( 2436 scoped_ptr<ppapi::host::HostFactory>( 2437 new ChromeBrowserPepperHostFactory(browser_host))); 2438#endif 2439} 2440 2441content::BrowserPpapiHost* 2442 ChromeContentBrowserClient::GetExternalBrowserPpapiHost( 2443 int plugin_process_id) { 2444 BrowserChildProcessHostIterator iter(PROCESS_TYPE_NACL_LOADER); 2445 while (!iter.Done()) { 2446 nacl::NaClProcessHost* host = static_cast<nacl::NaClProcessHost*>( 2447 iter.GetDelegate()); 2448 if (host->process() && 2449 host->process()->GetData().id == plugin_process_id) { 2450 // Found the plugin. 2451 return host->browser_ppapi_host(); 2452 } 2453 ++iter; 2454 } 2455 return NULL; 2456} 2457 2458bool ChromeContentBrowserClient::SupportsBrowserPlugin( 2459 content::BrowserContext* browser_context, const GURL& site_url) { 2460 if (CommandLine::ForCurrentProcess()->HasSwitch( 2461 switches::kEnableBrowserPluginForAllViewTypes)) 2462 return true; 2463 2464 if (content::HasWebUIScheme(site_url)) 2465 return true; 2466 2467 Profile* profile = Profile::FromBrowserContext(browser_context); 2468 ExtensionService* service = 2469 extensions::ExtensionSystem::Get(profile)->extension_service(); 2470 if (!service) 2471 return false; 2472 2473 const Extension* extension = 2474 service->extensions()->GetExtensionOrAppByURL(site_url); 2475 if (!extension) 2476 return false; 2477 2478 return extension->HasAPIPermission(APIPermission::kWebView) || 2479 extension->HasAPIPermission(APIPermission::kAdView); 2480} 2481 2482bool ChromeContentBrowserClient::AllowPepperSocketAPI( 2483 content::BrowserContext* browser_context, 2484 const GURL& url, 2485 bool private_api, 2486 const content::SocketPermissionRequest* params) { 2487#if defined(ENABLE_PLUGINS) 2488 Profile* profile = Profile::FromBrowserContext(browser_context); 2489 const extensions::ExtensionSet* extension_set = NULL; 2490 if (profile) { 2491 extension_set = extensions::ExtensionSystem::Get(profile)-> 2492 extension_service()->extensions(); 2493 } 2494 2495 if (private_api) { 2496 // Access to private socket APIs is controlled by the whitelist. 2497 if (IsExtensionOrSharedModuleWhitelisted(url, extension_set, 2498 allowed_socket_origins_)) { 2499 return true; 2500 } 2501 } else { 2502 // Access to public socket APIs is controlled by extension permissions. 2503 if (url.is_valid() && url.SchemeIs(extensions::kExtensionScheme) && 2504 extension_set) { 2505 const Extension* extension = extension_set->GetByID(url.host()); 2506 if (extension) { 2507 if (params) { 2508 extensions::SocketPermission::CheckParam check_params( 2509 params->type, params->host, params->port); 2510 if (extensions::PermissionsData::CheckAPIPermissionWithParam( 2511 extension, extensions::APIPermission::kSocket, 2512 &check_params)) { 2513 return true; 2514 } 2515 } else { 2516 if (extensions::PermissionsData::HasAPIPermission( 2517 extension, extensions::APIPermission::kSocket)) { 2518 return true; 2519 } 2520 } 2521 } 2522 } 2523 } 2524 2525 // Allow both public and private APIs if the command line says so. 2526 return IsHostAllowedByCommandLine(url, extension_set, 2527 switches::kAllowNaClSocketAPI); 2528#else 2529 return false; 2530#endif 2531} 2532 2533ui::SelectFilePolicy* ChromeContentBrowserClient::CreateSelectFilePolicy( 2534 WebContents* web_contents) { 2535 return new ChromeSelectFilePolicy(web_contents); 2536} 2537 2538void ChromeContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem( 2539 std::vector<std::string>* additional_allowed_schemes) { 2540 ContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem( 2541 additional_allowed_schemes); 2542 additional_allowed_schemes->push_back(content::kChromeDevToolsScheme); 2543 additional_allowed_schemes->push_back(content::kChromeUIScheme); 2544 additional_allowed_schemes->push_back(extensions::kExtensionScheme); 2545} 2546 2547void ChromeContentBrowserClient::GetAdditionalFileSystemBackends( 2548 content::BrowserContext* browser_context, 2549 const base::FilePath& storage_partition_path, 2550 ScopedVector<fileapi::FileSystemBackend>* additional_backends) { 2551#if !defined(OS_ANDROID) 2552 base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool(); 2553 additional_backends->push_back(new MediaFileSystemBackend( 2554 storage_partition_path, 2555 pool->GetSequencedTaskRunner(pool->GetNamedSequenceToken( 2556 MediaFileSystemBackend::kMediaTaskRunnerName)).get())); 2557#endif 2558#if defined(OS_CHROMEOS) 2559 fileapi::ExternalMountPoints* external_mount_points = 2560 content::BrowserContext::GetMountPoints(browser_context); 2561 DCHECK(external_mount_points); 2562 chromeos::FileSystemBackend* backend = 2563 new chromeos::FileSystemBackend( 2564 new drive::FileSystemBackendDelegate, 2565 browser_context->GetSpecialStoragePolicy(), 2566 external_mount_points, 2567 fileapi::ExternalMountPoints::GetSystemInstance()); 2568 backend->AddSystemMountPoints(); 2569 DCHECK(backend->CanHandleType(fileapi::kFileSystemTypeExternal)); 2570 additional_backends->push_back(backend); 2571#endif 2572 2573 additional_backends->push_back( 2574 new sync_file_system::SyncFileSystemBackend( 2575 Profile::FromBrowserContext(browser_context))); 2576 2577 if (CommandLine::ForCurrentProcess()->HasSwitch( 2578 switches::kEnablePrivetStorage)) { 2579 additional_backends->push_back( 2580 new local_discovery::PrivetFileSystemBackend( 2581 fileapi::ExternalMountPoints::GetSystemInstance())); 2582 } 2583} 2584 2585#if defined(OS_POSIX) && !defined(OS_MACOSX) 2586void ChromeContentBrowserClient::GetAdditionalMappedFilesForChildProcess( 2587 const CommandLine& command_line, 2588 int child_process_id, 2589 std::vector<FileDescriptorInfo>* mappings) { 2590#if defined(OS_ANDROID) 2591 base::FilePath data_path; 2592 PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &data_path); 2593 DCHECK(!data_path.empty()); 2594 2595 int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ; 2596 base::FilePath chrome_resources_pak = 2597 data_path.AppendASCII("chrome_100_percent.pak"); 2598 base::PlatformFile f = 2599 base::CreatePlatformFile(chrome_resources_pak, flags, NULL, NULL); 2600 DCHECK(f != base::kInvalidPlatformFileValue); 2601 mappings->push_back(FileDescriptorInfo(kAndroidChrome100PercentPakDescriptor, 2602 FileDescriptor(f, true))); 2603 2604 const std::string locale = GetApplicationLocale(); 2605 base::FilePath locale_pak = ResourceBundle::GetSharedInstance(). 2606 GetLocaleFilePath(locale, false); 2607 f = base::CreatePlatformFile(locale_pak, flags, NULL, NULL); 2608 DCHECK(f != base::kInvalidPlatformFileValue); 2609 mappings->push_back(FileDescriptorInfo(kAndroidLocalePakDescriptor, 2610 FileDescriptor(f, true))); 2611 2612 base::FilePath resources_pack_path; 2613 PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path); 2614 f = base::CreatePlatformFile(resources_pack_path, flags, NULL, NULL); 2615 DCHECK(f != base::kInvalidPlatformFileValue); 2616 mappings->push_back(FileDescriptorInfo(kAndroidUIResourcesPakDescriptor, 2617 FileDescriptor(f, true))); 2618 2619 if (breakpad::IsCrashReporterEnabled()) { 2620 f = breakpad::CrashDumpManager::GetInstance()->CreateMinidumpFile( 2621 child_process_id); 2622 if (f == base::kInvalidPlatformFileValue) { 2623 LOG(ERROR) << "Failed to create file for minidump, crash reporting will " 2624 "be disabled for this process."; 2625 } else { 2626 mappings->push_back(FileDescriptorInfo(kAndroidMinidumpDescriptor, 2627 FileDescriptor(f, true))); 2628 } 2629 } 2630 2631#else 2632 int crash_signal_fd = GetCrashSignalFD(command_line); 2633 if (crash_signal_fd >= 0) { 2634 mappings->push_back(FileDescriptorInfo(kCrashDumpSignal, 2635 FileDescriptor(crash_signal_fd, 2636 false))); 2637 } 2638#endif // defined(OS_ANDROID) 2639} 2640#endif // defined(OS_POSIX) && !defined(OS_MACOSX) 2641 2642#if defined(OS_WIN) 2643const wchar_t* ChromeContentBrowserClient::GetResourceDllName() { 2644 return chrome::kBrowserResourcesDll; 2645} 2646 2647void ChromeContentBrowserClient::PreSpawnRenderer( 2648 sandbox::TargetPolicy* policy, 2649 bool* success) { 2650 // This code is duplicated in nacl_exe_win_64.cc. 2651 // Allow the server side of a pipe restricted to the "chrome.nacl." 2652 // namespace so that it cannot impersonate other system or other chrome 2653 // service pipes. 2654 sandbox::ResultCode result = policy->AddRule( 2655 sandbox::TargetPolicy::SUBSYS_NAMED_PIPES, 2656 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, 2657 L"\\\\.\\pipe\\chrome.nacl.*"); 2658 if (result != sandbox::SBOX_ALL_OK) { 2659 *success = false; 2660 return; 2661 } 2662 2663 // Renderers need to send named pipe handles and shared memory 2664 // segment handles to NaCl loader processes. 2665 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES, 2666 sandbox::TargetPolicy::HANDLES_DUP_ANY, 2667 L"File"); 2668 if (result != sandbox::SBOX_ALL_OK) { 2669 *success = false; 2670 return; 2671 } 2672} 2673#endif 2674 2675bool ChromeContentBrowserClient::IsPluginAllowedToCallRequestOSFileHandle( 2676 content::BrowserContext* browser_context, 2677 const GURL& url) { 2678#if defined(ENABLE_PLUGINS) 2679 Profile* profile = Profile::FromBrowserContext(browser_context); 2680 const extensions::ExtensionSet* extension_set = NULL; 2681 if (profile) { 2682 extension_set = extensions::ExtensionSystem::Get(profile)-> 2683 extension_service()->extensions(); 2684 } 2685 // TODO(teravest): Populate allowed_file_handle_origins_ when FileIO is moved 2686 // from the renderer to the browser. 2687 return IsExtensionOrSharedModuleWhitelisted(url, extension_set, 2688 allowed_file_handle_origins_) || 2689 IsHostAllowedByCommandLine(url, extension_set, 2690 switches::kAllowNaClFileHandleAPI); 2691#else 2692 return false; 2693#endif 2694} 2695 2696bool ChromeContentBrowserClient::IsPluginAllowedToUseDevChannelAPIs() { 2697#if defined(ENABLE_PLUGINS) 2698 // Allow access for tests. 2699 if (CommandLine::ForCurrentProcess()->HasSwitch( 2700 switches::kEnablePepperTesting)) { 2701 return true; 2702 } 2703 2704 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); 2705 // Allow dev channel APIs to be used on "Canary", "Dev", and "Unknown" 2706 // releases of Chrome. Permitting "Unknown" allows these APIs to be used on 2707 // Chromium builds as well. 2708 return channel <= chrome::VersionInfo::CHANNEL_DEV; 2709#else 2710 return false; 2711#endif 2712} 2713 2714 2715} // namespace chrome 2716