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