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