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