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