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