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