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