blob: 4e32646f9867ea162c086e49a2ebdad3567037bb [file] [log] [blame]
[email protected]f3986f82012-01-03 20:00:061// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]d977f9c2011-03-14 16:10:262// 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
[email protected]7c3228a2011-11-11 21:35:227#include <set>
[email protected]1033acd2012-02-08 08:46:278#include <utility>
[email protected]7c3228a2011-11-11 21:35:229#include <vector>
10
[email protected]317c58f02011-11-09 02:15:0311#include "base/bind.h"
[email protected]b80f68432011-05-02 17:22:3012#include "base/command_line.h"
[email protected]29699c22012-10-03 23:57:3913#include "base/path_service.h"
[email protected]e461da2f2012-02-16 19:06:4014#include "base/string_tokenizer.h"
[email protected]f3986f82012-01-03 20:00:0615#include "base/utf_string_conversions.h"
[email protected]b80f68432011-05-02 17:22:3016#include "chrome/app/breakpad_mac.h"
[email protected]b8148ac2011-07-13 22:03:2517#include "chrome/browser/browser_about_handler.h"
[email protected]b80f68432011-05-02 17:22:3018#include "chrome/browser/browser_process.h"
[email protected]b0cb5e82012-07-19 19:22:4719#include "chrome/browser/browsing_data/browsing_data_helper.h"
20#include "chrome/browser/browsing_data/browsing_data_remover.h"
[email protected]763ec4ca2011-04-29 15:48:1221#include "chrome/browser/character_encoding.h"
[email protected]6f08af82011-09-15 01:19:0322#include "chrome/browser/chrome_benchmarking_message_filter.h"
[email protected]317f96c92011-05-31 06:53:4123#include "chrome/browser/chrome_quota_permission_context.h"
[email protected]edece212011-11-16 11:56:5624#include "chrome/browser/content_settings/content_settings_utils.h"
[email protected]30fde822011-10-28 09:49:0525#include "chrome/browser/content_settings/cookie_settings.h"
[email protected]6786bf402011-12-03 15:19:4526#include "chrome/browser/content_settings/host_content_settings_map.h"
[email protected]8093a542011-05-13 07:29:3227#include "chrome/browser/content_settings/tab_specific_content_settings.h"
[email protected]9d06d88d2012-02-23 22:37:0828#include "chrome/browser/defaults.h"
[email protected]e1d16eb92011-08-18 23:19:3229#include "chrome/browser/download/download_util.h"
[email protected]2b33dcd02012-03-18 01:34:1630#include "chrome/browser/extensions/api/web_request/web_request_api.h"
[email protected]76411f412012-02-22 18:56:0631#include "chrome/browser/extensions/extension_host.h"
[email protected]941623e2011-06-07 23:06:0432#include "chrome/browser/extensions/extension_info_map.h"
[email protected]9c1662b2012-03-06 15:44:3333#include "chrome/browser/extensions/extension_process_manager.h"
[email protected]d977f9c2011-03-14 16:10:2634#include "chrome/browser/extensions/extension_service.h"
[email protected]31d8f5f22012-04-02 15:22:0835#include "chrome/browser/extensions/extension_system.h"
[email protected]b8148ac2011-07-13 22:03:2536#include "chrome/browser/extensions/extension_web_ui.h"
[email protected]f3986f82012-01-03 20:00:0637#include "chrome/browser/extensions/extension_webkit_preferences.h"
[email protected]40404bc2012-07-25 17:40:4938#include "chrome/browser/extensions/message_handler.h"
[email protected]eb4832a2012-12-08 01:57:5239#include "chrome/browser/extensions/suggest_permission_util.h"
[email protected]32538d92011-08-25 00:09:2340#include "chrome/browser/geolocation/chrome_access_token_store.h"
[email protected]763ec4ca2011-04-29 15:48:1241#include "chrome/browser/google/google_util.h"
[email protected]117b6b42012-02-29 09:11:0842#include "chrome/browser/infobars/infobar_tab_helper.h"
[email protected]dc73a7b2012-03-25 15:27:1843#include "chrome/browser/media/media_internals.h"
[email protected]0c7193742012-11-07 19:05:0344#include "chrome/browser/nacl_host/nacl_process_host.h"
[email protected]ae6e9912011-07-27 01:18:2845#include "chrome/browser/net/chrome_net_log.h"
[email protected]941623e2011-06-07 23:06:0446#include "chrome/browser/notifications/desktop_notification_service.h"
47#include "chrome/browser/notifications/desktop_notification_service_factory.h"
[email protected]0609b17f2011-05-31 20:13:4248#include "chrome/browser/platform_util.h"
[email protected]763ec4ca2011-04-29 15:48:1249#include "chrome/browser/prefs/pref_service.h"
[email protected]f3986f82012-01-03 20:00:0650#include "chrome/browser/prefs/scoped_user_pref_update.h"
[email protected]f9034cf2011-07-21 12:43:4151#include "chrome/browser/prerender/prerender_manager.h"
[email protected]3085c502011-10-05 17:50:5052#include "chrome/browser/prerender/prerender_manager_factory.h"
[email protected]2736c032012-05-11 18:06:0753#include "chrome/browser/prerender/prerender_message_filter.h"
[email protected]f9034cf2011-07-21 12:43:4154#include "chrome/browser/prerender/prerender_tracker.h"
[email protected]05fcf982011-04-19 00:44:1455#include "chrome/browser/printing/printing_message_filter.h"
56#include "chrome/browser/profiles/profile.h"
[email protected]8093a542011-05-13 07:29:3257#include "chrome/browser/profiles/profile_io_data.h"
[email protected]76411f412012-02-22 18:56:0658#include "chrome/browser/profiles/profile_manager.h"
[email protected]05fcf982011-04-19 00:44:1459#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
[email protected]53a0afa2011-04-28 02:09:3360#include "chrome/browser/renderer_host/chrome_render_view_host_observer.h"
[email protected]b7631cc2012-09-15 05:08:3861#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
[email protected]8aa7a412011-11-07 12:33:4262#include "chrome/browser/renderer_host/plugin_info_message_filter.h"
[email protected]05fcf982011-04-19 00:44:1463#include "chrome/browser/search_engines/search_provider_install_state_message_filter.h"
[email protected]c52b2892012-03-07 11:01:0264#include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h"
[email protected]8ec71262011-07-28 08:12:4665#include "chrome/browser/spellchecker/spellcheck_message_filter.h"
[email protected]3b455502012-12-11 18:22:5866#include "chrome/browser/ssl/ssl_add_certificate.h"
[email protected]848dd042011-06-04 18:24:0367#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]11feec322012-09-18 03:58:5268#include "chrome/browser/ssl/ssl_tab_helper.h"
[email protected]8ec26472011-06-06 16:52:4569#include "chrome/browser/tab_contents/tab_util.h"
[email protected]c27541f2012-05-24 19:25:5470#include "chrome/browser/toolkit_extra_parts.h"
[email protected]b5d73422012-06-02 23:46:4471#include "chrome/browser/ui/tab_contents/chrome_web_contents_view_delegate.h"
[email protected]871dc682012-06-11 19:35:3372#include "chrome/browser/ui/tab_contents/tab_contents.h"
[email protected]863f70a2012-01-27 02:05:5073#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
[email protected]f3986f82012-01-03 20:00:0674#include "chrome/browser/user_style_sheet_watcher.h"
[email protected]13169ab2012-04-06 07:48:1575#include "chrome/browser/user_style_sheet_watcher_factory.h"
[email protected]9ec0f452012-05-31 15:58:5376#include "chrome/browser/view_type_utils.h"
[email protected]b80f68432011-05-02 17:22:3077#include "chrome/common/child_process_logging.h"
[email protected]4a65826d2011-08-25 16:04:0178#include "chrome/common/chrome_constants.h"
[email protected]a7944aa2012-10-15 10:12:1479#include "chrome/common/chrome_paths.h"
[email protected]b80f68432011-05-02 17:22:3080#include "chrome/common/chrome_switches.h"
[email protected]941623e2011-06-07 23:06:0481#include "chrome/common/extensions/extension.h"
[email protected]395045c2012-05-22 15:04:3882#include "chrome/common/extensions/extension_process_policy.h"
[email protected]615d88f2011-12-13 01:47:4483#include "chrome/common/extensions/extension_set.h"
[email protected]157cc902012-11-02 06:31:5884#include "chrome/common/extensions/permissions/socket_permission.h"
[email protected]f1933792011-06-14 00:49:3485#include "chrome/common/logging_chrome.h"
[email protected]763ec4ca2011-04-29 15:48:1286#include "chrome/common/pref_names.h"
[email protected]3e69bc82011-05-26 23:22:3887#include "chrome/common/render_messages.h"
[email protected]c5dbef02011-05-13 05:06:0988#include "chrome/common/url_constants.h"
[email protected]e0ada9c2012-03-20 03:54:4389#include "content/public/browser/browser_child_process_host.h"
[email protected]b48c9182011-10-26 18:03:3090#include "content/public/browser/browser_main_parts.h"
[email protected]b7631cc2012-09-15 05:08:3891#include "content/public/browser/browser_ppapi_host.h"
[email protected]825b1662012-03-12 19:07:3192#include "content/public/browser/browser_url_handler.h"
[email protected]0c7193742012-11-07 19:05:0393#include "content/public/browser/child_process_data.h"
[email protected]b9535422012-02-09 01:47:5994#include "content/public/browser/child_process_security_policy.h"
[email protected]cb6430932012-10-31 00:53:3695#include "content/public/browser/compositor_util.h"
[email protected]f3b1a082011-11-18 00:34:3096#include "content/public/browser/render_process_host.h"
[email protected]9c1662b2012-03-06 15:44:3397#include "content/public/browser/render_view_host.h"
[email protected]ce967862012-02-09 22:47:0598#include "content/public/browser/resource_context.h"
[email protected]b6583592012-01-25 19:52:3399#include "content/public/browser/site_instance.h"
[email protected]91ee3682012-01-19 15:02:19100#include "content/public/browser/web_contents.h"
[email protected]8643e6d2012-01-18 20:26:10101#include "content/public/browser/web_contents_view.h"
[email protected]e0ada9c2012-03-20 03:54:43102#include "content/public/common/child_process_host.h"
[email protected]a1733df2012-06-22 11:24:18103#include "content/public/common/content_descriptors.h"
[email protected]885c0e92012-11-13 20:27:42104#include "extensions/common/constants.h"
[email protected]c9b6eb62011-10-18 20:49:39105#include "grit/generated_resources.h"
[email protected]2a281332012-07-11 22:20:23106#include "grit/ui_resources.h"
[email protected]1bc28312012-11-08 08:31:53107#include "net/base/escape.h"
[email protected]3b455502012-12-11 18:22:58108#include "net/base/mime_util.h"
[email protected]7a593db2012-02-13 21:19:40109#include "net/base/ssl_cert_request_info.h"
[email protected]5b9bc352012-07-18 13:13:34110#include "net/cookies/canonical_cookie.h"
[email protected]aa84a7e2012-03-15 21:29:06111#include "net/cookies/cookie_options.h"
[email protected]b7631cc2012-09-15 05:08:38112#include "ppapi/host/ppapi_host.h"
[email protected]c9b6eb62011-10-18 20:49:39113#include "ui/base/l10n/l10n_util.h"
[email protected]ac55e292011-06-24 05:16:08114#include "ui/base/resource/resource_bundle.h"
[email protected]edbea622012-11-28 20:39:38115#include "ui/base/ui_base_switches.h"
[email protected]4fdf6742012-01-10 20:14:36116#include "webkit/glue/webpreferences.h"
[email protected]a085aed72012-04-24 05:32:04117#include "webkit/plugins/plugin_switches.h"
[email protected]d977f9c2011-03-14 16:10:26118
[email protected]b48c9182011-10-26 18:03:30119#if defined(OS_WIN)
[email protected]199fc7a2011-09-28 22:45:38120#include "chrome/browser/chrome_browser_main_win.h"
121#elif defined(OS_MACOSX)
122#include "chrome/browser/chrome_browser_main_mac.h"
[email protected]7ceb99012011-12-21 08:05:56123#include "chrome/browser/spellchecker/spellcheck_message_filter_mac.h"
[email protected]b48c9182011-10-26 18:03:30124#elif defined(OS_CHROMEOS)
125#include "chrome/browser/chromeos/chrome_browser_main_chromeos.h"
[email protected]fe69558d2012-03-12 11:34:49126#include "chrome/browser/chromeos/login/user_manager.h"
[email protected]81ce2c42012-03-24 01:43:26127#elif defined(OS_LINUX)
[email protected]b48c9182011-10-26 18:03:30128#include "chrome/browser/chrome_browser_main_linux.h"
[email protected]81054f812012-08-30 00:47:09129#elif defined(OS_ANDROID)
[email protected]40da3e0c2012-10-24 22:03:38130#include "chrome/browser/android/crash_dump_manager.h"
[email protected]81054f812012-08-30 00:47:09131#include "chrome/browser/chrome_browser_main_android.h"
[email protected]29699c22012-10-03 23:57:39132#include "chrome/common/descriptors_android.h"
[email protected]b48c9182011-10-26 18:03:30133#elif defined(OS_POSIX)
134#include "chrome/browser/chrome_browser_main_posix.h"
135#endif
136
[email protected]6653c192012-04-10 22:52:44137#if defined(OS_LINUX) || defined(OS_OPENBSD) || defined(OS_ANDROID)
[email protected]b80f68432011-05-02 17:22:30138#include "base/linux_util.h"
[email protected]1602cde2012-06-26 15:09:12139#include "chrome/browser/crash_handler_host_linux.h"
[email protected]1fd5302c2011-05-28 04:06:43140#endif
[email protected]b80f68432011-05-02 17:22:30141
[email protected]1e87df32012-09-12 04:53:19142#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
143#include "chrome/browser/captive_portal/captive_portal_tab_helper.h"
144#endif
145
[email protected]29699c22012-10-03 23:57:39146#if defined(OS_ANDROID)
147#include "ui/base/ui_base_paths.h"
148#endif
149
[email protected]37a72af2011-06-13 05:42:01150#if defined(USE_NSS)
151#include "chrome/browser/ui/crypto_module_password_dialog.h"
152#endif
153
[email protected]c7abd422012-09-25 00:20:08154using base::FileDescriptor;
[email protected]c8c77182011-12-21 15:04:47155using content::AccessTokenStore;
[email protected]0c7193742012-11-07 19:05:03156using content::BrowserChildProcessHostIterator;
[email protected]631bb742011-11-02 11:29:39157using content::BrowserThread;
[email protected]825b1662012-03-12 19:07:31158using content::BrowserURLHandler;
[email protected]b9535422012-02-09 01:47:59159using content::ChildProcessSecurityPolicy;
[email protected]c7abd422012-09-25 00:20:08160using content::FileDescriptorInfo;
[email protected]9f9749a2012-03-02 19:37:00161using content::QuotaPermissionContext;
[email protected]eaabba22012-03-07 15:02:11162using content::RenderViewHost;
[email protected]b6583592012-01-25 19:52:33163using content::SiteInstance;
[email protected]83ff91c2012-01-05 20:54:13164using content::WebContents;
[email protected]c2e66e12012-06-27 06:27:06165using extensions::APIPermission;
[email protected]1c321ee2012-05-21 03:02:34166using extensions::Extension;
[email protected]6717bf272012-05-11 23:31:25167using webkit_glue::WebPreferences;
[email protected]631bb742011-11-02 11:29:39168
[email protected]c5dbef02011-05-13 05:06:09169namespace {
170
[email protected]e461da2f2012-02-16 19:06:40171const char* kPredefinedAllowedSocketOrigins[] = {
172 "okddffdblfhhnmhodogpojmfkjmhinfp", // Test SSH Client
[email protected]b95bf502012-04-06 07:41:18173 "pnhechapfaindjhompbnflcldabbghjo", // HTerm App (SSH Client)
[email protected]99132682012-04-24 19:00:45174 "bglhmjfplikpjnfoegeomebmfnkjomhe", // see crbug.com/122126
175 "gbchcmhmhahfdphkhkmpfmihenigjmpp", // Chrome Remote Desktop
176 "kgngmbheleoaphbjbaiobfdepmghbfah", // Pre-release Chrome Remote Desktop
177 "odkaodonbgfohohmklejpjiejmcipmib", // Dogfood Chrome Remote Desktop
[email protected]a450b6be2012-05-22 19:30:35178 "ojoimpklfciegopdfgeenehpalipignm", // Chromoting canary
[email protected]9040a0c22012-06-22 19:06:54179 "cbkkbcmdlboombapidmoeolnmdacpkch", // see crbug.com/129089
180 "hhnbmknkdabfoieppbbljkhkfjcmcbjh", // see crbug.com/134099
181 "mablfbjkhmhkmefkjjacnbaikjkipphg", // see crbug.com/134099
182 "pdeelgamlgannhelgoegilelnnojegoh", // see crbug.com/134099
183 "cabapfdbkniadpollkckdnedaanlciaj", // see crbug.com/134099
184 "mapljbgnjledlpdmlchihnmeclmefbba", // see crbug.com/134099
[email protected]4dc30b82012-08-15 00:24:38185 "ghbfeebgmiidnnmeobbbaiamklmpbpii", // see crbug.com/134099
[email protected]45db05f2012-12-10 21:52:58186 "jdfhpkjeckflbbleddjlpimecpbjdeep", // see crbug.com/142514
187 "iabmpiboiopbgfabjmgeedhcmjenhbla" // see crbug.com/165080
[email protected]e461da2f2012-02-16 19:06:40188};
189
[email protected]f8f93eb2012-09-25 03:06:24190// Returns a copy of the given url with its host set to given host and path set
191// to given path. Other parts of the url will be the same.
192GURL ReplaceURLHostAndPath(const GURL& url,
193 const std::string& host,
194 const std::string& path) {
195 url_canon::Replacements<char> replacements;
196 replacements.SetHost(host.c_str(),
197 url_parse::Component(0, host.length()));
198 replacements.SetPath(path.c_str(),
199 url_parse::Component(0, path.length()));
200 return url.ReplaceComponents(replacements);
201}
202
203// Maps "foo://bar/baz/" to "foo://chrome/bar/baz/".
204GURL AddUberHost(const GURL& url) {
205 const std::string uber_host = chrome::kChromeUIUberHost;
206 const std::string new_path = url.host() + url.path();
207
208 return ReplaceURLHostAndPath(url, uber_host, new_path);
209}
210
[email protected]045bf7c2012-09-28 20:27:36211// If url->host() is "chrome" and url->path() has characters other than the
212// first slash, changes the url from "foo://chrome/bar/" to "foo://bar/" and
213// returns true. Otherwise returns false.
[email protected]f8f93eb2012-09-25 03:06:24214bool RemoveUberHost(GURL* url) {
215 if (url->host() != chrome::kChromeUIUberHost)
216 return false;
217
[email protected]045bf7c2012-09-28 20:27:36218 if (url->path().empty() || url->path() == "/")
219 return false;
220
[email protected]f8f93eb2012-09-25 03:06:24221 const std::string old_path = url->path();
222
223 const std::string::size_type separator = old_path.find('/', 1);
224 std::string new_host;
225 std::string new_path;
226 if (separator == std::string::npos) {
[email protected]045bf7c2012-09-28 20:27:36227 new_host = old_path.substr(1);
[email protected]f8f93eb2012-09-25 03:06:24228 } else {
229 new_host = old_path.substr(1, separator - 1);
230 new_path = old_path.substr(separator);
231 }
232
233 *url = ReplaceURLHostAndPath(*url, new_host, new_path);
234
235 return true;
236}
237
[email protected]b8148ac2011-07-13 22:03:25238// Handles rewriting Web UI URLs.
[email protected]8d3132f62011-10-12 07:13:42239bool HandleWebUI(GURL* url, content::BrowserContext* browser_context) {
[email protected]f8f93eb2012-09-25 03:06:24240 // Do not handle special URLs such as "about:foo"
241 if (!url->host().empty()) {
242 const GURL chrome_url = AddUberHost(*url);
243
244 // Handle valid "chrome://chrome/foo" URLs so the reverse handler will
245 // be called.
246 if (ChromeWebUIControllerFactory::GetInstance()->UseWebUIForURL(
247 browser_context, chrome_url))
248 return true;
249 }
250
[email protected]863f70a2012-01-27 02:05:50251 if (!ChromeWebUIControllerFactory::GetInstance()->UseWebUIForURL(
252 browser_context, *url))
[email protected]b8148ac2011-07-13 22:03:25253 return false;
254
[email protected]fe69558d2012-03-12 11:34:49255#if defined(OS_CHROMEOS)
256 // Special case : in ChromeOS in Guest mode bookmarks and history are
257 // disabled for security reasons. New tab page explains the reasons, so
258 // we redirect user to new tab page.
259 if (chromeos::UserManager::Get()->IsLoggedInAsGuest()) {
260 if (url->SchemeIs(chrome::kChromeUIScheme) &&
261 (url->DomainIs(chrome::kChromeUIBookmarksHost) ||
262 url->DomainIs(chrome::kChromeUIHistoryHost))) {
263 // Rewrite with new tab URL
264 *url = GURL(chrome::kChromeUINewTabURL);
265 }
266 }
267#endif
268
[email protected]b8148ac2011-07-13 22:03:25269 // Special case the new tab page. In older versions of Chrome, the new tab
270 // page was hosted at chrome-internal:<blah>. This might be in people's saved
271 // sessions or bookmarks, so we say any URL with that scheme triggers the new
272 // tab page.
273 if (url->SchemeIs(chrome::kChromeInternalScheme)) {
274 // Rewrite it with the proper new tab URL.
275 *url = GURL(chrome::kChromeUINewTabURL);
276 }
277
278 return true;
279}
280
[email protected]f8f93eb2012-09-25 03:06:24281// Reverse URL handler for Web UI. Maps "chrome://chrome/foo/" to
282// "chrome://foo/".
283bool HandleWebUIReverse(GURL* url, content::BrowserContext* browser_context) {
284 if (!url->is_valid() || !url->SchemeIs(chrome::kChromeUIScheme))
285 return false;
286
287 return RemoveUberHost(url);
288}
289
[email protected]8d3132f62011-10-12 07:13:42290// Used by the GetPrivilegeRequiredByUrl() and GetProcessPrivilege() functions
291// below. Extension, and isolated apps require different privileges to be
292// granted to their RenderProcessHosts. This classification allows us to make
293// sure URLs are served by hosts with the right set of privileges.
294enum RenderProcessHostPrivilege {
295 PRIV_NORMAL,
[email protected]eec0b33c2011-12-05 22:09:45296 PRIV_HOSTED,
[email protected]8d3132f62011-10-12 07:13:42297 PRIV_ISOLATED,
[email protected]eec0b33c2011-12-05 22:09:45298 PRIV_EXTENSION,
[email protected]8d3132f62011-10-12 07:13:42299};
300
301RenderProcessHostPrivilege GetPrivilegeRequiredByUrl(
302 const GURL& url,
303 ExtensionService* service) {
304 // Default to a normal renderer cause it is lower privileged. This should only
305 // occur if the URL on a site instance is either malformed, or uninitialized.
306 // If it is malformed, then there is no need for better privileges anyways.
307 // If it is uninitialized, but eventually settles on being an a scheme other
308 // than normal webrenderer, the navigation logic will correct us out of band
309 // anyways.
310 if (!url.is_valid())
311 return PRIV_NORMAL;
312
[email protected]885c0e92012-11-13 20:27:42313 if (url.SchemeIs(extensions::kExtensionScheme)) {
[email protected]615d88f2011-12-13 01:47:44314 const Extension* extension =
315 service->extensions()->GetByID(url.host());
[email protected]eec0b33c2011-12-05 22:09:45316 if (extension && extension->is_storage_isolated())
[email protected]8d3132f62011-10-12 07:13:42317 return PRIV_ISOLATED;
[email protected]eec0b33c2011-12-05 22:09:45318 if (extension && extension->is_hosted_app())
319 return PRIV_HOSTED;
[email protected]8d3132f62011-10-12 07:13:42320
321 return PRIV_EXTENSION;
322 }
323
324 return PRIV_NORMAL;
325}
326
327RenderProcessHostPrivilege GetProcessPrivilege(
[email protected]f3b1a082011-11-18 00:34:30328 content::RenderProcessHost* process_host,
[email protected]6f371442011-11-09 06:45:46329 extensions::ProcessMap* process_map,
330 ExtensionService* service) {
[email protected]6f371442011-11-09 06:45:46331 std::set<std::string> extension_ids =
[email protected]f3b1a082011-11-18 00:34:30332 process_map->GetExtensionsInProcess(process_host->GetID());
[email protected]6f371442011-11-09 06:45:46333 if (extension_ids.empty())
[email protected]676f6ab2011-10-19 20:23:21334 return PRIV_NORMAL;
335
[email protected]6f371442011-11-09 06:45:46336 for (std::set<std::string>::iterator iter = extension_ids.begin();
337 iter != extension_ids.end(); ++iter) {
338 const Extension* extension = service->GetExtensionById(*iter, false);
339 if (extension && extension->is_storage_isolated())
[email protected]8d3132f62011-10-12 07:13:42340 return PRIV_ISOLATED;
[email protected]eec0b33c2011-12-05 22:09:45341 if (extension && extension->is_hosted_app())
342 return PRIV_HOSTED;
[email protected]8d3132f62011-10-12 07:13:42343 }
344
[email protected]676f6ab2011-10-19 20:23:21345 return PRIV_EXTENSION;
[email protected]8d3132f62011-10-12 07:13:42346}
347
[email protected]6786bf402011-12-03 15:19:45348bool CertMatchesFilter(const net::X509Certificate& cert,
349 const base::DictionaryValue& filter) {
350 // TODO(markusheintz): This is the minimal required filter implementation.
351 // Implement a better matcher.
352
353 // An empty filter matches any client certificate since no requirements are
354 // specified at all.
355 if (filter.empty())
356 return true;
357
358 std::string common_name;
359 if (filter.GetString("ISSUER.CN", &common_name) &&
360 (cert.issuer().common_name == common_name)) {
361 return true;
362 }
363 return false;
364}
365
[email protected]f3986f82012-01-03 20:00:06366// Fills |map| with the per-script font prefs under path |map_name|.
367void FillFontFamilyMap(const PrefService* prefs,
368 const char* map_name,
369 WebPreferences::ScriptFontFamilyMap* map) {
370 for (size_t i = 0; i < prefs::kWebKitScriptsForFontFamilyMapsLength; ++i) {
371 const char* script = prefs::kWebKitScriptsForFontFamilyMaps[i];
372 std::string pref_name = base::StringPrintf("%s.%s", map_name, script);
373 std::string font_family = prefs->GetString(pref_name.c_str());
[email protected]d0471062012-10-26 09:00:23374 if (!font_family.empty())
375 (*map)[script] = UTF8ToUTF16(font_family);
[email protected]f3986f82012-01-03 20:00:06376 }
377}
378
[email protected]a1733df2012-06-22 11:24:18379#if defined(OS_POSIX) && !defined(OS_MACOSX)
380int GetCrashSignalFD(const CommandLine& command_line) {
381 if (command_line.HasSwitch(switches::kExtensionProcess)) {
382 ExtensionCrashHandlerHostLinux* crash_handler =
383 ExtensionCrashHandlerHostLinux::GetInstance();
384 return crash_handler->GetDeathSignalSocket();
385 }
386
387 std::string process_type =
388 command_line.GetSwitchValueASCII(switches::kProcessType);
389
390 if (process_type == switches::kRendererProcess)
391 return RendererCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
392
393 if (process_type == switches::kPluginProcess)
394 return PluginCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
395
396 if (process_type == switches::kPpapiPluginProcess)
397 return PpapiCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
398
399 if (process_type == switches::kGpuProcess)
400 return GpuCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
401
402 return -1;
403}
404#endif // defined(OS_POSIX) && !defined(OS_MACOSX)
405
[email protected]9dbfff12011-07-01 19:37:07406} // namespace
[email protected]c5dbef02011-05-13 05:06:09407
[email protected]d977f9c2011-03-14 16:10:26408namespace chrome {
409
[email protected]e461da2f2012-02-16 19:06:40410ChromeContentBrowserClient::ChromeContentBrowserClient() {
411 for (size_t i = 0; i < arraysize(kPredefinedAllowedSocketOrigins); ++i)
412 allowed_socket_origins_.insert(kPredefinedAllowedSocketOrigins[i]);
[email protected]e461da2f2012-02-16 19:06:40413}
414
415ChromeContentBrowserClient::~ChromeContentBrowserClient() {
416}
417
[email protected]bca18382012-06-25 19:15:23418// static
419void ChromeContentBrowserClient::RegisterUserPrefs(PrefService* prefs) {
420 prefs->RegisterBooleanPref(prefs::kDisable3DAPIs,
421 false,
422 PrefService::UNSYNCABLE_PREF);
423 prefs->RegisterBooleanPref(prefs::kEnableHyperlinkAuditing,
424 true,
425 PrefService::UNSYNCABLE_PREF);
426 prefs->RegisterBooleanPref(prefs::kEnableMemoryInfo,
427 false,
428 PrefService::UNSYNCABLE_PREF);
429}
430
[email protected]50462bf02011-11-21 19:13:31431content::BrowserMainParts* ChromeContentBrowserClient::CreateBrowserMainParts(
432 const content::MainFunctionParams& parameters) {
433 ChromeBrowserMainParts* main_parts;
[email protected]b48c9182011-10-26 18:03:30434 // Construct the Main browser parts based on the OS type.
435#if defined(OS_WIN)
[email protected]50462bf02011-11-21 19:13:31436 main_parts = new ChromeBrowserMainPartsWin(parameters);
[email protected]f967b722011-09-07 00:58:04437#elif defined(OS_MACOSX)
[email protected]50462bf02011-11-21 19:13:31438 main_parts = new ChromeBrowserMainPartsMac(parameters);
[email protected]b48c9182011-10-26 18:03:30439#elif defined(OS_CHROMEOS)
[email protected]2c624d02012-11-15 19:37:22440 main_parts = new chromeos::ChromeBrowserMainPartsChromeos(parameters);
[email protected]81ce2c42012-03-24 01:43:26441#elif defined(OS_LINUX)
[email protected]50462bf02011-11-21 19:13:31442 main_parts = new ChromeBrowserMainPartsLinux(parameters);
[email protected]6e677a342012-02-11 01:21:14443#elif defined(OS_ANDROID)
[email protected]81054f812012-08-30 00:47:09444 main_parts = new ChromeBrowserMainPartsAndroid(parameters);
[email protected]b48c9182011-10-26 18:03:30445#elif defined(OS_POSIX)
[email protected]50462bf02011-11-21 19:13:31446 main_parts = new ChromeBrowserMainPartsPosix(parameters);
[email protected]f967b722011-09-07 00:58:04447#else
[email protected]b48c9182011-10-26 18:03:30448 NOTREACHED();
[email protected]50462bf02011-11-21 19:13:31449 main_parts = new ChromeBrowserMainParts(parameters);
[email protected]b48c9182011-10-26 18:03:30450#endif
451
[email protected]c7480942011-11-08 19:18:27452 // Construct additional browser parts. Stages are called in the order in
453 // which they are added.
[email protected]a13283cc2012-04-05 00:21:22454#if defined(TOOLKIT_GTK)
[email protected]684dace42012-07-01 14:30:41455 chrome::AddGtkToolkitExtraParts(main_parts);
[email protected]f967b722011-09-07 00:58:04456#endif
[email protected]c7480942011-11-08 19:18:27457
458#if defined(TOOLKIT_VIEWS)
[email protected]684dace42012-07-01 14:30:41459 chrome::AddViewsToolkitExtraParts(main_parts);
[email protected]c7480942011-11-08 19:18:27460#endif
461
[email protected]dc04be7c2012-03-15 23:57:49462#if defined(USE_ASH)
[email protected]684dace42012-07-01 14:30:41463 chrome::AddAshToolkitExtraParts(main_parts);
[email protected]dc04be7c2012-03-15 23:57:49464#endif
465
[email protected]e050ef142012-03-21 01:04:24466#if defined(USE_AURA)
[email protected]684dace42012-07-01 14:30:41467 chrome::AddAuraToolkitExtraParts(main_parts);
[email protected]e050ef142012-03-21 01:04:24468#endif
469
[email protected]50462bf02011-11-21 19:13:31470 return main_parts;
[email protected]f967b722011-09-07 00:58:04471}
472
[email protected]38b098f2012-03-14 21:11:57473content::WebContentsView*
474 ChromeContentBrowserClient::OverrideCreateWebContentsView(
[email protected]5a3bdf52012-05-24 15:12:57475 WebContents* web_contents,
476 content::RenderViewHostDelegateView** render_view_host_delegate_view) {
[email protected]38b098f2012-03-14 21:11:57477 return NULL;
478}
479
[email protected]e94bbcb2012-09-07 05:33:57480std::string ChromeContentBrowserClient::GetStoragePartitionIdForSite(
[email protected]d1198fd2012-08-13 22:50:19481 content::BrowserContext* browser_context,
[email protected]e94bbcb2012-09-07 05:33:57482 const GURL& site) {
[email protected]1bc28312012-11-08 08:31:53483 std::string partition_id;
484
485 // The partition ID for webview guest processes is the string value of its
486 // SiteInstance URL - "chrome-guest://app_id/persist?partition".
487 if (site.SchemeIs(chrome::kGuestScheme))
488 partition_id = site.spec();
489
490 DCHECK(IsValidStoragePartitionId(browser_context,partition_id));
491 return partition_id;
492}
493
494bool ChromeContentBrowserClient::IsValidStoragePartitionId(
495 content::BrowserContext* browser_context,
496 const std::string& partition_id) {
497 // The default ID is empty and is always valid.
498 if (partition_id.empty())
499 return true;
500
501 return GURL(partition_id).is_valid();
502}
503
504void ChromeContentBrowserClient::GetStoragePartitionConfigForSite(
505 content::BrowserContext* browser_context,
506 const GURL& site,
[email protected]14acc642012-11-17 12:20:10507 bool can_be_default,
[email protected]1bc28312012-11-08 08:31:53508 std::string* partition_domain,
509 std::string* partition_name,
510 bool* in_memory) {
[email protected]14acc642012-11-17 12:20:10511 // Default to the browser-wide storage partition and override based on |site|
512 // below.
513 partition_domain->clear();
514 partition_name->clear();
515 *in_memory = false;
516
[email protected]1bc28312012-11-08 08:31:53517 // For the webview tag, we create special guest processes, which host the
518 // tag content separately from the main application that embeds the tag.
519 // A webview tag can specify both the partition name and whether the storage
520 // for that partition should be persisted. Each tag gets a SiteInstance with
521 // a specially formatted URL, based on the application it is hosted by and
522 // the partition requested by it. The format for that URL is:
523 // chrome-guest://partition_domain/persist?partition_name
524 if (site.SchemeIs(chrome::kGuestScheme)) {
525 // Since guest URLs are only used for packaged apps, there must be an app
526 // id in the URL.
527 CHECK(site.has_host());
528 *partition_domain = site.host();
529 // Since persistence is optional, the path must either be empty or the
530 // literal string.
531 *in_memory = (site.path() != "/persist");
532 // The partition name is user supplied value, which we have encoded when the
533 // URL was created, so it needs to be decoded.
534 *partition_name = net::UnescapeURLComponent(site.query(),
535 net::UnescapeRule::NORMAL);
[email protected]14acc642012-11-17 12:20:10536 } else if (site.SchemeIs(extensions::kExtensionScheme)) {
537 // If |can_be_default| is false, the caller is stating that the |site|
538 // should be parsed as if it had isolated storage. In particular it is
539 // important to NOT check ExtensionService for the is_storage_isolated()
540 // attribute because this code path is run during Extension uninstall
541 // to do cleanup after the Extension has already been unloaded from the
542 // ExtensionService.
543 bool is_isolated = !can_be_default;
544 if (can_be_default) {
545 const Extension* extension = NULL;
546 Profile* profile = Profile::FromBrowserContext(browser_context);
547 ExtensionService* extension_service =
548 extensions::ExtensionSystem::Get(profile)->extension_service();
549 if (extension_service) {
550 extension = extension_service->extensions()->
551 GetExtensionOrAppByURL(ExtensionURLInfo(site));
552 if (extension && extension->is_storage_isolated()) {
553 is_isolated = true;
554 }
555 }
556 }
[email protected]1bc28312012-11-08 08:31:53557
[email protected]14acc642012-11-17 12:20:10558 if (is_isolated) {
559 CHECK(site.has_host());
560 // For extensions with isolated storage, the the host of the |site| is
561 // the |partition_domain|. The |in_memory| and |partition_name| are only
562 // used in guest schemes so they are cleared here.
563 *partition_domain = site.host();
[email protected]1bc28312012-11-08 08:31:53564 *in_memory = false;
[email protected]14acc642012-11-17 12:20:10565 partition_name->clear();
[email protected]1bc28312012-11-08 08:31:53566 }
[email protected]d1198fd2012-08-13 22:50:19567 }
568
[email protected]14acc642012-11-17 12:20:10569 // Assert that if |can_be_default| is false, the code above must have found a
570 // non-default partition. If this fails, the caller has a serious logic
571 // error about which StoragePartition they expect to be in and it is not
572 // safe to continue.
573 CHECK(can_be_default || !partition_domain->empty());
[email protected]d7c7c98a2012-07-12 21:27:44574}
575
[email protected]38b098f2012-03-14 21:11:57576content::WebContentsViewDelegate*
577 ChromeContentBrowserClient::GetWebContentsViewDelegate(
578 content::WebContents* web_contents) {
[email protected]d33220292012-07-04 01:41:27579 return chrome::CreateWebContentsViewDelegate(web_contents);
[email protected]74313b42011-08-24 16:51:32580}
581
[email protected]f364d1392011-04-08 21:03:10582void ChromeContentBrowserClient::RenderViewHostCreated(
583 RenderViewHost* render_view_host) {
[email protected]67372ecf2011-09-10 01:30:46584
[email protected]9f76c1e2012-03-05 15:15:58585 SiteInstance* site_instance = render_view_host->GetSiteInstance();
[email protected]67372ecf2011-09-10 01:30:46586 Profile* profile = Profile::FromBrowserContext(
[email protected]72daaa92012-01-18 13:39:02587 site_instance->GetBrowserContext());
[email protected]67372ecf2011-09-10 01:30:46588
589 new ChromeRenderViewHostObserver(render_view_host,
590 profile->GetNetworkPredictor());
[email protected]40404bc2012-07-25 17:40:49591 new extensions::MessageHandler(render_view_host);
[email protected]d977f9c2011-03-14 16:10:26592}
593
[email protected]f3b1a082011-11-18 00:34:30594void ChromeContentBrowserClient::RenderProcessHostCreated(
595 content::RenderProcessHost* host) {
596 int id = host->GetID();
597 Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext());
598 host->GetChannel()->AddFilter(new ChromeRenderMessageFilter(
[email protected]c47cfd62011-04-29 21:27:02599 id, profile, profile->GetRequestContextForRenderProcess(id)));
[email protected]f3b1a082011-11-18 00:34:30600 host->GetChannel()->AddFilter(new PluginInfoMessageFilter(id, profile));
[email protected]658677f2012-06-09 06:04:02601#if defined(ENABLE_PRINTING)
[email protected]0045b0f42012-07-26 11:52:08602 host->GetChannel()->AddFilter(new PrintingMessageFilter(id, profile));
[email protected]058e5732012-03-01 22:48:03603#endif
[email protected]f3b1a082011-11-18 00:34:30604 host->GetChannel()->AddFilter(
[email protected]c47cfd62011-04-29 21:27:02605 new SearchProviderInstallStateMessageFilter(id, profile));
[email protected]f3b1a082011-11-18 00:34:30606 host->GetChannel()->AddFilter(new SpellCheckMessageFilter(id));
[email protected]7ceb99012011-12-21 08:05:56607#if defined(OS_MACOSX)
608 host->GetChannel()->AddFilter(new SpellCheckMessageFilterMac());
609#endif
[email protected]f3b1a082011-11-18 00:34:30610 host->GetChannel()->AddFilter(new ChromeBenchmarkingMessageFilter(
[email protected]6f08af82011-09-15 01:19:03611 id, profile, profile->GetRequestContextForRenderProcess(id)));
[email protected]2736c032012-05-11 18:06:07612 host->GetChannel()->AddFilter(
613 new prerender::PrerenderMessageFilter(id, profile));
[email protected]3e69bc82011-05-26 23:22:38614
[email protected]2ccf45c2011-08-19 23:35:50615 host->Send(new ChromeViewMsg_SetIsIncognitoProcess(
616 profile->IsOffTheRecord()));
[email protected]39a5b532011-10-22 01:47:07617
618 SendExtensionWebRequestStatusToHost(host);
[email protected]edece212011-11-16 11:56:56619
620 RendererContentSettingRules rules;
621 GetRendererContentSettingRules(profile->GetHostContentSettingsMap(), &rules);
622 host->Send(new ChromeViewMsg_SetContentSettingRules(rules));
[email protected]40da3e0c2012-10-24 22:03:38623
624#if defined(OS_ANDROID) && defined(USE_LINUX_BREAKPAD)
625 InitCrashDumpManager();
626#endif
[email protected]05fcf982011-04-19 00:44:14627}
628
[email protected]863f70a2012-01-27 02:05:50629content::WebUIControllerFactory*
630 ChromeContentBrowserClient::GetWebUIControllerFactory() {
631 return ChromeWebUIControllerFactory::GetInstance();
[email protected]1fd1a502011-03-30 16:55:56632}
633
[email protected]3d7474ff2011-07-27 17:47:37634GURL ChromeContentBrowserClient::GetEffectiveURL(
635 content::BrowserContext* browser_context, const GURL& url) {
636 Profile* profile = Profile::FromBrowserContext(browser_context);
[email protected]36fb2c7c2011-04-04 15:49:08637 // Get the effective URL for the given actual URL. If the URL is part of an
638 // installed app, the effective URL is an extension URL with the ID of that
639 // extension as the host. This has the effect of grouping apps together in
640 // a common SiteInstance.
[email protected]2ee3da9d62012-12-05 20:17:19641 ExtensionService* extension_service = !profile ? NULL :
[email protected]06bdd2b2012-11-30 18:47:13642 extensions::ExtensionSystem::Get(profile)->extension_service();
643 if (!extension_service)
[email protected]36fb2c7c2011-04-04 15:49:08644 return url;
645
[email protected]06bdd2b2012-11-30 18:47:13646 const Extension* extension = extension_service->extensions()->
[email protected]615d88f2011-12-13 01:47:44647 GetHostedAppByURL(ExtensionURLInfo(url));
[email protected]36fb2c7c2011-04-04 15:49:08648 if (!extension)
649 return url;
650
[email protected]15877ca2011-11-18 22:40:52651 // Bookmark apps do not use the hosted app process model, and should be
652 // treated as normal URLs.
653 if (extension->from_bookmark())
654 return url;
655
[email protected]36fb2c7c2011-04-04 15:49:08656 // If the URL is part of an extension's web extent, convert it to an
657 // extension URL.
658 return extension->GetResourceURL(url.path());
659}
660
[email protected]056ad2a2011-07-12 02:13:55661bool ChromeContentBrowserClient::ShouldUseProcessPerSite(
[email protected]3d7474ff2011-07-27 17:47:37662 content::BrowserContext* browser_context, const GURL& effective_url) {
[email protected]056ad2a2011-07-12 02:13:55663 // Non-extension URLs should generally use process-per-site-instance.
[email protected]15877ca2011-11-18 22:40:52664 // Because we expect to use the effective URL, URLs for hosted apps (apart
665 // from bookmark apps) should have an extension scheme by now.
[email protected]885c0e92012-11-13 20:27:42666 if (!effective_url.SchemeIs(extensions::kExtensionScheme))
[email protected]056ad2a2011-07-12 02:13:55667 return false;
668
[email protected]3d7474ff2011-07-27 17:47:37669 Profile* profile = Profile::FromBrowserContext(browser_context);
[email protected]2ee3da9d62012-12-05 20:17:19670 ExtensionService* extension_service = !profile ? NULL :
[email protected]06bdd2b2012-11-30 18:47:13671 extensions::ExtensionSystem::Get(profile)->extension_service();
672 if (!extension_service)
[email protected]056ad2a2011-07-12 02:13:55673 return false;
674
[email protected]06bdd2b2012-11-30 18:47:13675 const Extension* extension = extension_service->extensions()->
[email protected]615d88f2011-12-13 01:47:44676 GetExtensionOrAppByURL(ExtensionURLInfo(effective_url));
[email protected]056ad2a2011-07-12 02:13:55677 if (!extension)
678 return false;
679
680 // If the URL is part of a hosted app that does not have the background
[email protected]7b54ca02012-03-02 18:06:53681 // permission, or that does not allow JavaScript access to the background
682 // page, we want to give each instance its own process to improve
[email protected]056ad2a2011-07-12 02:13:55683 // responsiveness.
[email protected]7b54ca02012-03-02 18:06:53684 if (extension->GetType() == Extension::TYPE_HOSTED_APP) {
[email protected]c2e66e12012-06-27 06:27:06685 if (!extension->HasAPIPermission(APIPermission::kBackground) ||
[email protected]7b54ca02012-03-02 18:06:53686 !extension->allow_background_js_access()) {
687 return false;
688 }
689 }
[email protected]056ad2a2011-07-12 02:13:55690
[email protected]7b54ca02012-03-02 18:06:53691 // Hosted apps that have script access to their background page must use
692 // process per site, since all instances can make synchronous calls to the
693 // background window. Other extensions should use process per site as well.
[email protected]056ad2a2011-07-12 02:13:55694 return true;
695}
696
[email protected]46fb9442011-12-09 17:57:47697bool ChromeContentBrowserClient::IsHandledURL(const GURL& url) {
698 return ProfileIOData::IsHandledURL(url);
699}
700
[email protected]2a5221b2011-09-27 23:07:31701bool ChromeContentBrowserClient::IsSuitableHost(
[email protected]f3b1a082011-11-18 00:34:30702 content::RenderProcessHost* process_host,
[email protected]2a5221b2011-09-27 23:07:31703 const GURL& site_url) {
704 Profile* profile =
[email protected]f3b1a082011-11-18 00:34:30705 Profile::FromBrowserContext(process_host->GetBrowserContext());
[email protected]06bdd2b2012-11-30 18:47:13706 ExtensionService* service =
707 extensions::ExtensionSystem::Get(profile)->extension_service();
[email protected]6f371442011-11-09 06:45:46708 extensions::ProcessMap* process_map = service->process_map();
[email protected]2a5221b2011-09-27 23:07:31709
[email protected]ffa97602011-11-17 17:55:52710 // Don't allow the Task Manager to share a process with anything else.
711 // Otherwise it can affect the renderers it is observing.
712 // Note: we could create another RenderProcessHostPrivilege bucket for
713 // this to allow multiple chrome://tasks instances to share, but that's
714 // a very unlikely case without serious consequences.
715 if (site_url.GetOrigin() == GURL(chrome::kChromeUITaskManagerURL).GetOrigin())
716 return false;
717
[email protected]8d3132f62011-10-12 07:13:42718 // These may be NULL during tests. In that case, just assume any site can
719 // share any host.
[email protected]6f371442011-11-09 06:45:46720 if (!service || !process_map)
[email protected]2a5221b2011-09-27 23:07:31721 return true;
722
[email protected]eec0b33c2011-12-05 22:09:45723 // Otherwise, just make sure the process privilege matches the privilege
724 // required by the site.
[email protected]e94bbcb2012-09-07 05:33:57725 RenderProcessHostPrivilege privilege_required =
726 GetPrivilegeRequiredByUrl(site_url, service);
[email protected]eec0b33c2011-12-05 22:09:45727 return GetProcessPrivilege(process_host, process_map, service) ==
728 privilege_required;
[email protected]2a5221b2011-09-27 23:07:31729}
730
[email protected]76411f412012-02-22 18:56:06731// This function is trying to limit the amount of processes used by extensions
732// with background pages. It uses a globally set percentage of processes to
733// run such extensions and if the limit is exceeded, it returns true, to
734// indicate to the content module to group extensions together.
735bool ChromeContentBrowserClient::ShouldTryToUseExistingProcessHost(
736 content::BrowserContext* browser_context, const GURL& url) {
737 // It has to be a valid URL for us to check for an extension.
738 if (!url.is_valid())
739 return false;
740
741 Profile* profile = Profile::FromBrowserContext(browser_context);
[email protected]2ee3da9d62012-12-05 20:17:19742 ExtensionService* service = !profile ? NULL :
[email protected]06bdd2b2012-11-30 18:47:13743 extensions::ExtensionSystem::Get(profile)->extension_service();
[email protected]76411f412012-02-22 18:56:06744 if (!service)
745 return false;
746
747 // We have to have a valid extension with background page to proceed.
748 const Extension* extension =
749 service->extensions()->GetExtensionOrAppByURL(ExtensionURLInfo(url));
750 if (!extension)
751 return false;
752 if (!extension->has_background_page())
753 return false;
754
755 std::set<int> process_ids;
756 size_t max_process_count =
757 content::RenderProcessHost::GetMaxRendererProcessCount();
758
759 // Go through all profiles to ensure we have total count of extension
760 // processes containing background pages, otherwise one profile can
761 // starve the other.
762 std::vector<Profile*> profiles = g_browser_process->profile_manager()->
763 GetLoadedProfiles();
764 for (size_t i = 0; i < profiles.size(); ++i) {
[email protected]be93bba02012-10-24 16:44:03765 ExtensionProcessManager* epm =
766 extensions::ExtensionSystem::Get(profiles[i])->process_manager();
[email protected]d1fe1352012-04-26 00:47:32767 for (ExtensionProcessManager::const_iterator iter =
768 epm->background_hosts().begin();
769 iter != epm->background_hosts().end(); ++iter) {
[email protected]3a1dc572012-07-31 22:25:13770 const extensions::ExtensionHost* host = *iter;
[email protected]d1fe1352012-04-26 00:47:32771 process_ids.insert(host->render_process_host()->GetID());
[email protected]76411f412012-02-22 18:56:06772 }
773 }
774
775 if (process_ids.size() >
776 (max_process_count * chrome::kMaxShareOfExtensionProcesses)) {
777 return true;
778 }
779
780 return false;
781}
782
[email protected]6f371442011-11-09 06:45:46783void ChromeContentBrowserClient::SiteInstanceGotProcess(
784 SiteInstance* site_instance) {
785 CHECK(site_instance->HasProcess());
786
787 Profile* profile = Profile::FromBrowserContext(
[email protected]72daaa92012-01-18 13:39:02788 site_instance->GetBrowserContext());
[email protected]06bdd2b2012-11-30 18:47:13789 ExtensionService* service =
790 extensions::ExtensionSystem::Get(profile)->extension_service();
[email protected]6f371442011-11-09 06:45:46791 if (!service)
792 return;
793
794 const Extension* extension =
[email protected]615d88f2011-12-13 01:47:44795 service->extensions()->GetExtensionOrAppByURL(ExtensionURLInfo(
[email protected]77ab17312012-09-28 15:34:59796 site_instance->GetSiteURL()));
[email protected]6f371442011-11-09 06:45:46797 if (!extension)
798 return;
799
[email protected]6bc04fd82011-12-04 02:29:35800 service->process_map()->Insert(extension->id(),
801 site_instance->GetProcess()->GetID(),
[email protected]b6583592012-01-25 19:52:33802 site_instance->GetId());
[email protected]6f371442011-11-09 06:45:46803 BrowserThread::PostTask(
804 BrowserThread::IO, FROM_HERE,
805 base::Bind(&ExtensionInfoMap::RegisterExtensionProcess,
[email protected]bd306722012-07-11 20:43:59806 extensions::ExtensionSystem::Get(profile)->info_map(),
[email protected]6f371442011-11-09 06:45:46807 extension->id(),
[email protected]6bc04fd82011-12-04 02:29:35808 site_instance->GetProcess()->GetID(),
[email protected]b6583592012-01-25 19:52:33809 site_instance->GetId()));
[email protected]6f371442011-11-09 06:45:46810}
811
812void ChromeContentBrowserClient::SiteInstanceDeleting(
813 SiteInstance* site_instance) {
814 if (!site_instance->HasProcess())
815 return;
816
817 Profile* profile = Profile::FromBrowserContext(
[email protected]72daaa92012-01-18 13:39:02818 site_instance->GetBrowserContext());
[email protected]06bdd2b2012-11-30 18:47:13819 ExtensionService* service =
820 extensions::ExtensionSystem::Get(profile)->extension_service();
[email protected]6f371442011-11-09 06:45:46821 if (!service)
822 return;
823
824 const Extension* extension =
[email protected]615d88f2011-12-13 01:47:44825 service->extensions()->GetExtensionOrAppByURL(
[email protected]77ab17312012-09-28 15:34:59826 ExtensionURLInfo(site_instance->GetSiteURL()));
[email protected]6f371442011-11-09 06:45:46827 if (!extension)
828 return;
829
[email protected]6bc04fd82011-12-04 02:29:35830 service->process_map()->Remove(extension->id(),
831 site_instance->GetProcess()->GetID(),
[email protected]b6583592012-01-25 19:52:33832 site_instance->GetId());
[email protected]6f371442011-11-09 06:45:46833 BrowserThread::PostTask(
834 BrowserThread::IO, FROM_HERE,
835 base::Bind(&ExtensionInfoMap::UnregisterExtensionProcess,
[email protected]bd306722012-07-11 20:43:59836 extensions::ExtensionSystem::Get(profile)->info_map(),
[email protected]6f371442011-11-09 06:45:46837 extension->id(),
[email protected]6bc04fd82011-12-04 02:29:35838 site_instance->GetProcess()->GetID(),
[email protected]b6583592012-01-25 19:52:33839 site_instance->GetId()));
[email protected]6f371442011-11-09 06:45:46840}
841
[email protected]f05763972012-06-06 18:17:26842bool ChromeContentBrowserClient::ShouldSwapProcessesForNavigation(
[email protected]e3daf3c2011-10-05 21:17:08843 const GURL& current_url,
844 const GURL& new_url) {
[email protected]f05763972012-06-06 18:17:26845 if (current_url.is_empty()) {
846 // Always choose a new process when navigating to extension URLs. The
847 // process grouping logic will combine all of a given extension's pages
848 // into the same process.
[email protected]885c0e92012-11-13 20:27:42849 if (new_url.SchemeIs(extensions::kExtensionScheme))
[email protected]f05763972012-06-06 18:17:26850 return true;
[email protected]e3daf3c2011-10-05 21:17:08851
[email protected]f05763972012-06-06 18:17:26852 return false;
853 }
854
855 // Also, we must switch if one is an extension and the other is not the exact
856 // same extension.
[email protected]885c0e92012-11-13 20:27:42857 if (current_url.SchemeIs(extensions::kExtensionScheme) ||
858 new_url.SchemeIs(extensions::kExtensionScheme)) {
[email protected]f05763972012-06-06 18:17:26859 if (current_url.GetOrigin() != new_url.GetOrigin())
860 return true;
861 }
862
863 return false;
[email protected]e3daf3c2011-10-05 21:17:08864}
865
[email protected]395045c2012-05-22 15:04:38866bool ChromeContentBrowserClient::ShouldSwapProcessesForRedirect(
867 content::ResourceContext* resource_context, const GURL& current_url,
868 const GURL& new_url) {
869 ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context);
870 return extensions::CrossesExtensionProcessBoundary(
871 io_data->GetExtensionInfoMap()->extensions(),
[email protected]ea7b7d82012-05-25 17:29:17872 ExtensionURLInfo(current_url), ExtensionURLInfo(new_url), false);
[email protected]395045c2012-05-22 15:04:38873}
874
[email protected]763ec4ca2011-04-29 15:48:12875std::string ChromeContentBrowserClient::GetCanonicalEncodingNameByAliasName(
876 const std::string& alias_name) {
877 return CharacterEncoding::GetCanonicalEncodingNameByAliasName(alias_name);
878}
879
[email protected]b80f68432011-05-02 17:22:30880void ChromeContentBrowserClient::AppendExtraCommandLineSwitches(
881 CommandLine* command_line, int child_process_id) {
882#if defined(USE_LINUX_BREAKPAD)
883 if (IsCrashReporterEnabled()) {
884 command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
885 child_process_logging::GetClientId() + "," + base::GetLinuxDistro());
886 }
887#elif defined(OS_MACOSX)
888 if (IsCrashReporterEnabled()) {
889 command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
890 child_process_logging::GetClientId());
891 }
892#endif // OS_MACOSX
893
[email protected]f1933792011-06-14 00:49:34894 if (logging::DialogsAreSuppressed())
895 command_line->AppendSwitch(switches::kNoErrorDialogs);
896
[email protected]b80f68432011-05-02 17:22:30897 std::string process_type =
898 command_line->GetSwitchValueASCII(switches::kProcessType);
[email protected]3cb054e62011-06-13 05:21:17899 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
[email protected]718eab62011-10-05 21:16:52900 if (process_type == switches::kRendererProcess) {
[email protected]b80f68432011-05-02 17:22:30901 FilePath user_data_dir =
902 browser_command_line.GetSwitchValuePath(switches::kUserDataDir);
903 if (!user_data_dir.empty())
904 command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir);
905#if defined(OS_CHROMEOS)
906 const std::string& login_profile =
907 browser_command_line.GetSwitchValueASCII(switches::kLoginProfile);
908 if (!login_profile.empty())
909 command_line->AppendSwitchASCII(switches::kLoginProfile, login_profile);
910#endif
911
[email protected]f3b1a082011-11-18 00:34:30912 content::RenderProcessHost* process =
913 content::RenderProcessHost::FromID(child_process_id);
[email protected]a8d851f82011-12-21 00:32:37914 if (process) {
915 Profile* profile = Profile::FromBrowserContext(
916 process->GetBrowserContext());
[email protected]06bdd2b2012-11-30 18:47:13917 ExtensionService* extension_service =
918 extensions::ExtensionSystem::Get(profile)->extension_service();
919 if (extension_service) {
920 extensions::ProcessMap* process_map = extension_service->process_map();
[email protected]c8598d42012-09-25 21:17:00921 if (process_map && process_map->Contains(process->GetID()))
922 command_line->AppendSwitch(switches::kExtensionProcess);
923 }
[email protected]b80f68432011-05-02 17:22:30924
[email protected]a8d851f82011-12-21 00:32:37925 PrefService* prefs = profile->GetPrefs();
926 // Currently this pref is only registered if applied via a policy.
927 if (prefs->HasPrefPath(prefs::kDisable3DAPIs) &&
928 prefs->GetBoolean(prefs::kDisable3DAPIs)) {
929 // Turn this policy into a command line switch.
930 command_line->AppendSwitch(switches::kDisable3DAPIs);
931 }
[email protected]718eab62011-10-05 21:16:52932
[email protected]a8d851f82011-12-21 00:32:37933 // Disable client-side phishing detection in the renderer if it is
934 // disabled in the Profile preferences or the browser process.
935 if (!prefs->GetBoolean(prefs::kSafeBrowsingEnabled) ||
936 !g_browser_process->safe_browsing_detection_service()) {
937 command_line->AppendSwitch(
938 switches::kDisableClientSidePhishingDetection);
939 }
[email protected]0045b0f42012-07-26 11:52:08940
941 if (!prefs->GetBoolean(prefs::kPrintPreviewDisabled))
[email protected]47c7ec82012-01-18 03:29:21942 command_line->AppendSwitch(switches::kRendererPrintPreview);
[email protected]47c7ec82012-01-18 03:29:21943 }
[email protected]4287a3d2011-06-13 23:56:51944
[email protected]87552982012-11-02 17:21:40945 if (content::IsThreadedCompositingEnabled())
946 command_line->AppendSwitch(switches::kEnableThreadedCompositing);
947
[email protected]47c7ec82012-01-18 03:29:21948 // Please keep this in alphabetical order.
[email protected]4287a3d2011-06-13 23:56:51949 static const char* const kSwitchNames[] = {
950 switches::kAllowHTTPBackgroundPage,
[email protected]70f48c02011-12-02 21:27:48951 switches::kAllowLegacyExtensionManifests,
[email protected]4287a3d2011-06-13 23:56:51952 switches::kAllowScriptingGallery,
953 switches::kAppsCheckoutURL,
954 switches::kAppsGalleryURL,
[email protected]be9d9c82011-07-13 04:17:31955 switches::kCloudPrintServiceURL,
[email protected]4287a3d2011-06-13 23:56:51956 switches::kDebugPrint,
[email protected]382fb0d2012-02-25 00:19:50957 switches::kDisableBundledPpapiFlash,
[email protected]e9dfe222012-05-11 22:05:53958 switches::kDisableExtensionsResourceWhitelist,
[email protected]b0553c7e2012-09-19 21:36:11959 switches::kDisableScriptedPrintThrottling,
[email protected]4287a3d2011-06-13 23:56:51960 switches::kDumpHistogramsOnExit,
[email protected]47c7ec82012-01-18 03:29:21961 switches::kEnableBenchmarking,
[email protected]b50368b2012-02-18 00:02:13962 switches::kEnableBundledPpapiFlash,
[email protected]4e7d1a22012-11-06 13:57:03963 switches::kEnableChromeStyleDialogs,
[email protected]4287a3d2011-06-13 23:56:51964 switches::kEnableCrxlessWebApps,
965 switches::kEnableExperimentalExtensionApis,
[email protected]4287a3d2011-06-13 23:56:51966 switches::kEnableIPCFuzzing,
[email protected]aa75e4ed2012-11-08 23:51:51967 switches::kEnableInteractiveAutocomplete,
[email protected]4287a3d2011-06-13 23:56:51968 switches::kEnableNaCl,
[email protected]45a9c0a2012-11-08 21:00:29969 switches::kEnableNaClSRPCProxy,
[email protected]bcbe7652012-02-22 00:08:48970 switches::kEnablePasswordGeneration,
[email protected]284b03c2012-08-13 17:55:05971 switches::kEnablePnacl,
[email protected]edbea622012-11-28 20:39:38972 switches::kEnableTouchDragDrop,
[email protected]4287a3d2011-06-13 23:56:51973 switches::kEnableWatchdog,
[email protected]4287a3d2011-06-13 23:56:51974 switches::kMemoryProfiling,
975 switches::kMessageLoopHistogrammer,
[email protected]f45c5f32012-04-18 19:26:37976 switches::kNoJsRandomness,
[email protected]732b1604e2012-10-26 19:59:58977 switches::kPerformCrashAnalysis,
[email protected]f45c5f32012-04-18 19:26:37978 switches::kPlaybackMode,
[email protected]4287a3d2011-06-13 23:56:51979 switches::kPpapiFlashArgs,
980 switches::kPpapiFlashInProcess,
981 switches::kPpapiFlashPath,
982 switches::kPpapiFlashVersion,
983 switches::kProfilingAtStart,
984 switches::kProfilingFile,
985 switches::kProfilingFlush,
[email protected]f45c5f32012-04-18 19:26:37986 switches::kRecordMode,
[email protected]4287a3d2011-06-13 23:56:51987 switches::kSilentDumpOnDCHECK,
[email protected]c79d9492012-10-04 19:56:30988 switches::kSpdyProxyOrigin,
[email protected]a446534d2012-02-09 00:07:38989 switches::kWhitelistedExtensionID,
[email protected]4287a3d2011-06-13 23:56:51990 };
991
992 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
993 arraysize(kSwitchNames));
[email protected]3cb054e62011-06-13 05:21:17994 } else if (process_type == switches::kUtilityProcess) {
[email protected]a446534d2012-02-09 00:07:38995 static const char* const kSwitchNames[] = {
[email protected]eb653f82012-05-24 02:31:35996 switches::kAllowHTTPBackgroundPage,
[email protected]a446534d2012-02-09 00:07:38997 switches::kEnableExperimentalExtensionApis,
998 switches::kWhitelistedExtensionID,
999 };
1000
1001 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
1002 arraysize(kSwitchNames));
[email protected]4287a3d2011-06-13 23:56:511003 } else if (process_type == switches::kPluginProcess) {
1004 static const char* const kSwitchNames[] = {
1005 #if defined(OS_CHROMEOS)
1006 switches::kLoginProfile,
1007 #endif
1008 switches::kMemoryProfiling,
1009 switches::kSilentDumpOnDCHECK,
1010 switches::kUserDataDir,
1011 };
1012
1013 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
1014 arraysize(kSwitchNames));
1015 } else if (process_type == switches::kZygoteProcess) {
1016 static const char* const kSwitchNames[] = {
[email protected]4287a3d2011-06-13 23:56:511017 switches::kUserDataDir, // Make logs go to the right file.
1018 // Load (in-process) Pepper plugins in-process in the zygote pre-sandbox.
[email protected]382fb0d2012-02-25 00:19:501019 switches::kDisableBundledPpapiFlash,
[email protected]b50368b2012-02-18 00:02:131020 switches::kEnableBundledPpapiFlash,
[email protected]4287a3d2011-06-13 23:56:511021 switches::kPpapiFlashInProcess,
1022 switches::kPpapiFlashPath,
1023 switches::kPpapiFlashVersion,
1024 };
1025
1026 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
1027 arraysize(kSwitchNames));
[email protected]d56ecf922012-02-15 16:03:111028 } else if (process_type == switches::kGpuProcess) {
1029 // If --ignore-gpu-blacklist is passed in, don't send in crash reports
1030 // because GPU is expected to be unreliable.
1031 if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) &&
1032 !command_line->HasSwitch(switches::kDisableBreakpad))
1033 command_line->AppendSwitch(switches::kDisableBreakpad);
[email protected]b80f68432011-05-02 17:22:301034 }
[email protected]6f08af82011-09-15 01:19:031035
1036 // The command line switch kEnableBenchmarking needs to be specified along
1037 // with the kEnableStatsTable switch to ensure that the stats table global
1038 // is initialized correctly.
1039 if (command_line->HasSwitch(switches::kEnableBenchmarking))
1040 DCHECK(command_line->HasSwitch(switches::kEnableStatsTable));
[email protected]b80f68432011-05-02 17:22:301041}
1042
1043std::string ChromeContentBrowserClient::GetApplicationLocale() {
[email protected]e9a32a52012-06-14 23:32:431044 if (BrowserThread::CurrentlyOn(BrowserThread::IO))
1045 return io_thread_application_locale_;
[email protected]b80f68432011-05-02 17:22:301046 return g_browser_process->GetApplicationLocale();
1047}
1048
[email protected]597a867b2011-11-18 18:31:201049std::string ChromeContentBrowserClient::GetAcceptLangs(
1050 content::BrowserContext* context) {
1051 Profile* profile = Profile::FromBrowserContext(context);
[email protected]3d7474ff2011-07-27 17:47:371052 return profile->GetPrefs()->GetString(prefs::kAcceptLanguages);
[email protected]b5cca982011-05-26 04:42:081053}
1054
[email protected]9ec0f452012-05-31 15:58:531055gfx::ImageSkia* ChromeContentBrowserClient::GetDefaultFavicon() {
[email protected]7c3228a2011-11-11 21:35:221056 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
[email protected]9ec0f452012-05-31 15:58:531057 return rb.GetImageSkiaNamed(IDR_DEFAULT_FAVICON);
[email protected]ac55e292011-06-24 05:16:081058}
1059
[email protected]a2176792011-05-08 19:30:491060bool ChromeContentBrowserClient::AllowAppCache(
[email protected]5b52ad42011-05-26 14:26:091061 const GURL& manifest_url,
[email protected]0a608842011-09-08 10:55:191062 const GURL& first_party,
[email protected]df02aca2012-02-09 21:03:201063 content::ResourceContext* context) {
[email protected]8093a542011-05-13 07:29:321064 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]df02aca2012-02-09 21:03:201065 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
[email protected]30fde822011-10-28 09:49:051066 return io_data->GetCookieSettings()->
1067 IsSettingCookieAllowed(manifest_url, first_party);
[email protected]a2176792011-05-08 19:30:491068}
1069
[email protected]ed24fad2011-05-10 22:44:011070bool ChromeContentBrowserClient::AllowGetCookie(
1071 const GURL& url,
1072 const GURL& first_party,
1073 const net::CookieList& cookie_list,
[email protected]df02aca2012-02-09 21:03:201074 content::ResourceContext* context,
[email protected]ed24fad2011-05-10 22:44:011075 int render_process_id,
1076 int render_view_id) {
1077 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]df02aca2012-02-09 21:03:201078 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
[email protected]30fde822011-10-28 09:49:051079 bool allow = io_data->GetCookieSettings()->
1080 IsReadingCookieAllowed(url, first_party);
[email protected]ed24fad2011-05-10 22:44:011081
[email protected]8093a542011-05-13 07:29:321082 BrowserThread::PostTask(
1083 BrowserThread::UI, FROM_HERE,
[email protected]317c58f02011-11-09 02:15:031084 base::Bind(&TabSpecificContentSettings::CookiesRead, render_process_id,
[email protected]fd473d12012-04-05 11:38:431085 render_view_id, url, first_party, cookie_list, !allow));
[email protected]ed24fad2011-05-10 22:44:011086 return allow;
1087}
1088
1089bool ChromeContentBrowserClient::AllowSetCookie(
1090 const GURL& url,
1091 const GURL& first_party,
1092 const std::string& cookie_line,
[email protected]df02aca2012-02-09 21:03:201093 content::ResourceContext* context,
[email protected]ed24fad2011-05-10 22:44:011094 int render_process_id,
1095 int render_view_id,
1096 net::CookieOptions* options) {
1097 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]df02aca2012-02-09 21:03:201098 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
[email protected]30fde822011-10-28 09:49:051099 CookieSettings* cookie_settings = io_data->GetCookieSettings();
1100 bool allow = cookie_settings->IsSettingCookieAllowed(url, first_party);
1101
[email protected]8093a542011-05-13 07:29:321102 BrowserThread::PostTask(
1103 BrowserThread::UI, FROM_HERE,
[email protected]317c58f02011-11-09 02:15:031104 base::Bind(&TabSpecificContentSettings::CookieChanged, render_process_id,
[email protected]fd473d12012-04-05 11:38:431105 render_view_id, url, first_party, cookie_line, *options,
1106 !allow));
[email protected]ed24fad2011-05-10 22:44:011107 return allow;
1108}
1109
[email protected]ea628e32012-08-02 21:50:161110bool ChromeContentBrowserClient::AllowPluginLocalDataAccess(
1111 const GURL& document_url,
1112 const GURL& plugin_url,
1113 content::ResourceContext* context) {
1114 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1115 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
1116 return io_data->GetCookieSettings()->IsReadingCookieAllowed(document_url,
1117 plugin_url);
1118}
1119
1120bool ChromeContentBrowserClient::AllowPluginLocalDataSessionOnly(
1121 const GURL& url,
1122 content::ResourceContext* context) {
1123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1124 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
1125 return io_data->GetCookieSettings()->IsCookieSessionOnly(url);
1126}
1127
[email protected]d5a19162011-06-30 18:51:541128bool ChromeContentBrowserClient::AllowSaveLocalState(
[email protected]df02aca2012-02-09 21:03:201129 content::ResourceContext* context) {
[email protected]d5a19162011-06-30 18:51:541130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]df02aca2012-02-09 21:03:201131 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
[email protected]bf510ed2012-06-05 08:31:431132 CookieSettings* cookie_settings = io_data->GetCookieSettings();
1133 ContentSetting setting = cookie_settings->GetDefaultCookieSetting(NULL);
[email protected]1848cdc2012-02-17 10:48:261134
[email protected]bf510ed2012-06-05 08:31:431135 // TODO(bauerb): Should we also disallow local state if the default is BLOCK?
1136 // Could we even support per-origin settings?
1137 return setting != CONTENT_SETTING_SESSION_ONLY;
[email protected]d5a19162011-06-30 18:51:541138}
1139
[email protected]5c5a88e2011-11-12 00:45:351140bool ChromeContentBrowserClient::AllowWorkerDatabase(
[email protected]5c5a88e2011-11-12 00:45:351141 const GURL& url,
1142 const string16& name,
1143 const string16& display_name,
1144 unsigned long estimated_size,
[email protected]df02aca2012-02-09 21:03:201145 content::ResourceContext* context,
[email protected]62151052012-02-01 18:40:481146 const std::vector<std::pair<int, int> >& render_views) {
[email protected]5c5a88e2011-11-12 00:45:351147 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]df02aca2012-02-09 21:03:201148 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
[email protected]5c5a88e2011-11-12 00:45:351149 CookieSettings* cookie_settings = io_data->GetCookieSettings();
1150 bool allow = cookie_settings->IsSettingCookieAllowed(url, url);
1151
[email protected]62151052012-02-01 18:40:481152 // Record access to database for potential display in UI.
1153 std::vector<std::pair<int, int> >::const_iterator i;
1154 for (i = render_views.begin(); i != render_views.end(); ++i) {
1155 BrowserThread::PostTask(
1156 BrowserThread::UI, FROM_HERE,
1157 base::Bind(&TabSpecificContentSettings::WebDatabaseAccessed,
1158 i->first, i->second, url, name, display_name, !allow));
[email protected]5c5a88e2011-11-12 00:45:351159 }
1160
1161 return allow;
1162}
1163
1164bool ChromeContentBrowserClient::AllowWorkerFileSystem(
[email protected]5c5a88e2011-11-12 00:45:351165 const GURL& url,
[email protected]df02aca2012-02-09 21:03:201166 content::ResourceContext* context,
[email protected]62151052012-02-01 18:40:481167 const std::vector<std::pair<int, int> >& render_views) {
[email protected]5c5a88e2011-11-12 00:45:351168 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]df02aca2012-02-09 21:03:201169 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
[email protected]5c5a88e2011-11-12 00:45:351170 CookieSettings* cookie_settings = io_data->GetCookieSettings();
1171 bool allow = cookie_settings->IsSettingCookieAllowed(url, url);
1172
[email protected]62151052012-02-01 18:40:481173 // Record access to file system for potential display in UI.
1174 std::vector<std::pair<int, int> >::const_iterator i;
1175 for (i = render_views.begin(); i != render_views.end(); ++i) {
1176 BrowserThread::PostTask(
1177 BrowserThread::UI, FROM_HERE,
1178 base::Bind(&TabSpecificContentSettings::FileSystemAccessed,
1179 i->first, i->second, url, !allow));
[email protected]5c5a88e2011-11-12 00:45:351180 }
1181
1182 return allow;
1183}
1184
[email protected]7c5ff9a2012-03-02 07:42:491185bool ChromeContentBrowserClient::AllowWorkerIndexedDB(
1186 const GURL& url,
1187 const string16& name,
1188 content::ResourceContext* context,
1189 const std::vector<std::pair<int, int> >& render_views) {
1190 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1191 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
1192 CookieSettings* cookie_settings = io_data->GetCookieSettings();
1193 bool allow = cookie_settings->IsSettingCookieAllowed(url, url);
1194
1195 // Record access to IndexedDB for potential display in UI.
1196 std::vector<std::pair<int, int> >::const_iterator i;
1197 for (i = render_views.begin(); i != render_views.end(); ++i) {
1198 BrowserThread::PostTask(
1199 BrowserThread::UI, FROM_HERE,
1200 base::Bind(&TabSpecificContentSettings::IndexedDBAccessed,
1201 i->first, i->second, url, name, !allow));
1202 }
1203
1204 return allow;
1205}
1206
[email protected]6133f922011-07-01 21:34:341207net::URLRequestContext*
1208ChromeContentBrowserClient::OverrideRequestContextForURL(
[email protected]df02aca2012-02-09 21:03:201209 const GURL& url, content::ResourceContext* context) {
[email protected]6133f922011-07-01 21:34:341210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]885c0e92012-11-13 20:27:421211 if (url.SchemeIs(extensions::kExtensionScheme)) {
[email protected]df02aca2012-02-09 21:03:201212 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
[email protected]6133f922011-07-01 21:34:341213 return io_data->extensions_request_context();
1214 }
1215
1216 return NULL;
1217}
1218
[email protected]317f96c92011-05-31 06:53:411219QuotaPermissionContext*
1220ChromeContentBrowserClient::CreateQuotaPermissionContext() {
1221 return new ChromeQuotaPermissionContext();
1222}
1223
[email protected]a0ce3282011-08-19 20:49:521224void ChromeContentBrowserClient::OpenItem(const FilePath& path) {
[email protected]0609b17f2011-05-31 20:13:421225 platform_util::OpenItem(path);
[email protected]0609b17f2011-05-31 20:13:421226}
1227
[email protected]a0ce3282011-08-19 20:49:521228void ChromeContentBrowserClient::ShowItemInFolder(const FilePath& path) {
[email protected]a0ce3282011-08-19 20:49:521229 platform_util::ShowItemInFolder(path);
[email protected]a0ce3282011-08-19 20:49:521230}
1231
[email protected]848dd042011-06-04 18:24:031232void ChromeContentBrowserClient::AllowCertificateError(
[email protected]4cf611e32012-02-13 16:06:171233 int render_process_id,
1234 int render_view_id,
1235 int cert_error,
1236 const net::SSLInfo& ssl_info,
1237 const GURL& request_url,
[email protected]848dd042011-06-04 18:24:031238 bool overridable,
[email protected]d9be47702012-05-16 03:41:221239 bool strict_enforcement,
[email protected]4cf611e32012-02-13 16:06:171240 const base::Callback<void(bool)>& callback,
1241 bool* cancel_request) {
[email protected]f9034cf2011-07-21 12:43:411242 // If the tab is being prerendered, cancel the prerender and the request.
[email protected]83ff91c2012-01-05 20:54:131243 WebContents* tab = tab_util::GetWebContentsByID(
[email protected]4cf611e32012-02-13 16:06:171244 render_process_id, render_view_id);
[email protected]f9034cf2011-07-21 12:43:411245 if (!tab) {
1246 NOTREACHED();
1247 return;
1248 }
1249 prerender::PrerenderManager* prerender_manager =
[email protected]3085c502011-10-05 17:50:501250 prerender::PrerenderManagerFactory::GetForProfile(
[email protected]627e0512011-12-21 22:55:301251 Profile::FromBrowserContext(tab->GetBrowserContext()));
[email protected]3a6ec762012-10-17 16:01:011252 if (prerender_manager && prerender_manager->IsWebContentsPrerendering(tab,
1253 NULL)) {
[email protected]f9034cf2011-07-21 12:43:411254 if (prerender_manager->prerender_tracker()->TryCancel(
[email protected]4cf611e32012-02-13 16:06:171255 render_process_id, render_view_id,
[email protected]f9034cf2011-07-21 12:43:411256 prerender::FINAL_STATUS_SSL_ERROR)) {
[email protected]4cf611e32012-02-13 16:06:171257 *cancel_request = true;
[email protected]f9034cf2011-07-21 12:43:411258 return;
1259 }
1260 }
1261
[email protected]1e87df32012-09-12 04:53:191262#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
[email protected]eb0b9dd2012-09-19 21:36:231263 captive_portal::CaptivePortalTabHelper* captive_portal_tab_helper =
1264 captive_portal::CaptivePortalTabHelper::FromWebContents(tab);
1265 if (captive_portal_tab_helper)
1266 captive_portal_tab_helper->OnSSLCertError(ssl_info);
[email protected]1e87df32012-09-12 04:53:191267#endif
1268
[email protected]f9034cf2011-07-21 12:43:411269 // Otherwise, display an SSL blocking page.
[email protected]d9be47702012-05-16 03:41:221270 new SSLBlockingPage(tab, cert_error, ssl_info, request_url, overridable,
1271 strict_enforcement, callback);
[email protected]848dd042011-06-04 18:24:031272}
1273
[email protected]c99c442e2011-08-24 11:37:301274void ChromeContentBrowserClient::SelectClientCertificate(
[email protected]8ec26472011-06-06 16:52:451275 int render_process_id,
1276 int render_view_id,
[email protected]7a593db2012-02-13 21:19:401277 const net::HttpNetworkSession* network_session,
1278 net::SSLCertRequestInfo* cert_request_info,
1279 const base::Callback<void(net::X509Certificate*)>& callback) {
[email protected]83ff91c2012-01-05 20:54:131280 WebContents* tab = tab_util::GetWebContentsByID(
[email protected]8ec26472011-06-06 16:52:451281 render_process_id, render_view_id);
1282 if (!tab) {
1283 NOTREACHED();
1284 return;
1285 }
1286
[email protected]6786bf402011-12-03 15:19:451287 GURL requesting_url("https://" + cert_request_info->host_and_port);
1288 DCHECK(requesting_url.is_valid()) << "Invalid URL string: https://"
1289 << cert_request_info->host_and_port;
1290
[email protected]627e0512011-12-21 22:55:301291 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
[email protected]6786bf402011-12-03 15:19:451292 scoped_ptr<Value> filter(
1293 profile->GetHostContentSettingsMap()->GetWebsiteSetting(
1294 requesting_url,
1295 requesting_url,
1296 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
1297 std::string(), NULL));
1298
1299 if (filter.get()) {
1300 // Try to automatically select a client certificate.
1301 if (filter->IsType(Value::TYPE_DICTIONARY)) {
1302 DictionaryValue* filter_dict =
1303 static_cast<DictionaryValue*>(filter.get());
1304
1305 const std::vector<scoped_refptr<net::X509Certificate> >&
1306 all_client_certs = cert_request_info->client_certs;
1307 for (size_t i = 0; i < all_client_certs.size(); ++i) {
1308 if (CertMatchesFilter(*all_client_certs[i], *filter_dict)) {
1309 // Use the first certificate that is matched by the filter.
[email protected]7a593db2012-02-13 21:19:401310 callback.Run(all_client_certs[i]);
[email protected]6786bf402011-12-03 15:19:451311 return;
1312 }
1313 }
1314 } else {
1315 NOTREACHED();
1316 }
1317 }
1318
[email protected]11feec322012-09-18 03:58:521319 SSLTabHelper* ssl_tab_helper = SSLTabHelper::FromWebContents(tab);
1320 if (!ssl_tab_helper) {
1321 // If there is no SSLTabHelper for the given WebContents then we can't
[email protected]6786bf402011-12-03 15:19:451322 // show the user a dialog to select a client certificate. So we simply
[email protected]2a349e92011-12-07 12:00:141323 // proceed with no client certificate.
[email protected]7a593db2012-02-13 21:19:401324 callback.Run(NULL);
[email protected]6786bf402011-12-03 15:19:451325 return;
1326 }
[email protected]11feec322012-09-18 03:58:521327 ssl_tab_helper->ShowClientCertificateRequestDialog(
[email protected]7a593db2012-02-13 21:19:401328 network_session, cert_request_info, callback);
[email protected]8ec26472011-06-06 16:52:451329}
1330
[email protected]3b455502012-12-11 18:22:581331void ChromeContentBrowserClient::AddCertificate(
[email protected]8ec26472011-06-06 16:52:451332 net::URLRequest* request,
[email protected]3b455502012-12-11 18:22:581333 net::CertificateMimeType cert_type,
1334 const void* cert_data,
1335 size_t cert_size,
[email protected]8ec26472011-06-06 16:52:451336 int render_process_id,
1337 int render_view_id) {
[email protected]3b455502012-12-11 18:22:581338 chrome::SSLAddCertificate(request, cert_type, cert_data, cert_size,
1339 render_process_id, render_view_id);
[email protected]8ec26472011-06-06 16:52:451340}
1341
[email protected]dc73a7b2012-03-25 15:27:181342content::MediaObserver* ChromeContentBrowserClient::GetMediaObserver() {
1343 return MediaInternals::GetInstance();
1344}
1345
[email protected]941623e2011-06-07 23:06:041346void ChromeContentBrowserClient::RequestDesktopNotificationPermission(
1347 const GURL& source_origin,
1348 int callback_context,
1349 int render_process_id,
1350 int render_view_id) {
[email protected]5fd2e842012-03-01 00:29:111351#if defined(ENABLE_NOTIFICATIONS)
[email protected]d0d9c3ee2012-06-19 03:07:021352 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1353 WebContents* contents =
1354 tab_util::GetWebContentsByID(render_process_id, render_view_id);
1355 if (!contents) {
[email protected]941623e2011-06-07 23:06:041356 NOTREACHED();
1357 return;
1358 }
1359
[email protected]d0d9c3ee2012-06-19 03:07:021360 // Skip showing the infobar if the request comes from an extension, and that
1361 // extension has the 'notify' permission. (If the extension does not have the
1362 // permission, the user will still be prompted.)
1363 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
[email protected]06bdd2b2012-11-30 18:47:131364 ExtensionService* service =
1365 extensions::ExtensionSystem::Get(profile)->extension_service();
[email protected]d0d9c3ee2012-06-19 03:07:021366 const Extension* extension = !service ? NULL :
1367 service->extensions()->GetExtensionOrAppByURL(ExtensionURLInfo(
1368 source_origin));
[email protected]eb4832a2012-12-08 01:57:521369 RenderViewHost* rvh =
1370 RenderViewHost::FromID(render_process_id, render_view_id);
1371 if (IsExtensionWithPermissionOrSuggestInConsole(
1372 APIPermission::kNotification, extension, rvh)) {
[email protected]d0d9c3ee2012-06-19 03:07:021373 if (rvh)
1374 rvh->DesktopNotificationPermissionRequestDone(callback_context);
1375 return;
1376 }
1377
1378 DesktopNotificationService* notifications =
[email protected]3d7474ff2011-07-27 17:47:371379 DesktopNotificationServiceFactory::GetForProfile(profile);
[email protected]d0d9c3ee2012-06-19 03:07:021380 notifications->RequestPermission(source_origin, render_process_id,
1381 render_view_id, callback_context, contents);
[email protected]5fd2e842012-03-01 00:29:111382#else
1383 NOTIMPLEMENTED();
1384#endif
[email protected]941623e2011-06-07 23:06:041385}
1386
1387WebKit::WebNotificationPresenter::Permission
1388 ChromeContentBrowserClient::CheckDesktopNotificationPermission(
[email protected]34eec7ffe32011-11-02 23:49:021389 const GURL& source_origin,
[email protected]df02aca2012-02-09 21:03:201390 content::ResourceContext* context,
[email protected]34eec7ffe32011-11-02 23:49:021391 int render_process_id) {
[email protected]5fd2e842012-03-01 00:29:111392#if defined(ENABLE_NOTIFICATIONS)
[email protected]941623e2011-06-07 23:06:041393 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]df02aca2012-02-09 21:03:201394 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
[email protected]34eec7ffe32011-11-02 23:49:021395 if (io_data->GetExtensionInfoMap()->SecurityOriginHasAPIPermission(
1396 source_origin, render_process_id,
[email protected]c2e66e12012-06-27 06:27:061397 APIPermission::kNotification))
[email protected]941623e2011-06-07 23:06:041398 return WebKit::WebNotificationPresenter::PermissionAllowed;
[email protected]941623e2011-06-07 23:06:041399
1400 // Fall back to the regular notification preferences, which works on an
1401 // origin basis.
1402 return io_data->GetNotificationService() ?
[email protected]c7df61b2011-11-07 22:06:371403 io_data->GetNotificationService()->HasPermission(source_origin) :
[email protected]941623e2011-06-07 23:06:041404 WebKit::WebNotificationPresenter::PermissionNotAllowed;
[email protected]5fd2e842012-03-01 00:29:111405#else
1406 return WebKit::WebNotificationPresenter::PermissionAllowed;
1407#endif
[email protected]941623e2011-06-07 23:06:041408}
1409
1410void ChromeContentBrowserClient::ShowDesktopNotification(
[email protected]0ee57e22011-11-12 01:59:171411 const content::ShowDesktopNotificationHostMsgParams& params,
[email protected]941623e2011-06-07 23:06:041412 int render_process_id,
1413 int render_view_id,
1414 bool worker) {
[email protected]5fd2e842012-03-01 00:29:111415#if defined(ENABLE_NOTIFICATIONS)
[email protected]941623e2011-06-07 23:06:041416 RenderViewHost* rvh = RenderViewHost::FromID(
1417 render_process_id, render_view_id);
1418 if (!rvh) {
1419 NOTREACHED();
1420 return;
1421 }
1422
[email protected]9f76c1e2012-03-05 15:15:581423 content::RenderProcessHost* process = rvh->GetProcess();
[email protected]f3b1a082011-11-18 00:34:301424 Profile* profile = Profile::FromBrowserContext(process->GetBrowserContext());
[email protected]941623e2011-06-07 23:06:041425 DesktopNotificationService* service =
[email protected]3d7474ff2011-07-27 17:47:371426 DesktopNotificationServiceFactory::GetForProfile(profile);
[email protected]941623e2011-06-07 23:06:041427 service->ShowDesktopNotification(
1428 params, render_process_id, render_view_id,
1429 worker ? DesktopNotificationService::WorkerNotification :
1430 DesktopNotificationService::PageNotification);
[email protected]5fd2e842012-03-01 00:29:111431#else
1432 NOTIMPLEMENTED();
1433#endif
[email protected]941623e2011-06-07 23:06:041434}
1435
1436void ChromeContentBrowserClient::CancelDesktopNotification(
1437 int render_process_id,
1438 int render_view_id,
1439 int notification_id) {
[email protected]5fd2e842012-03-01 00:29:111440#if defined(ENABLE_NOTIFICATIONS)
[email protected]941623e2011-06-07 23:06:041441 RenderViewHost* rvh = RenderViewHost::FromID(
1442 render_process_id, render_view_id);
1443 if (!rvh) {
1444 NOTREACHED();
1445 return;
1446 }
1447
[email protected]9f76c1e2012-03-05 15:15:581448 content::RenderProcessHost* process = rvh->GetProcess();
[email protected]f3b1a082011-11-18 00:34:301449 Profile* profile = Profile::FromBrowserContext(process->GetBrowserContext());
[email protected]941623e2011-06-07 23:06:041450 DesktopNotificationService* service =
[email protected]3d7474ff2011-07-27 17:47:371451 DesktopNotificationServiceFactory::GetForProfile(profile);
[email protected]941623e2011-06-07 23:06:041452 service->CancelDesktopNotification(
1453 render_process_id, render_view_id, notification_id);
[email protected]5fd2e842012-03-01 00:29:111454#else
1455 NOTIMPLEMENTED();
1456#endif
[email protected]941623e2011-06-07 23:06:041457}
1458
[email protected]9f3fba52011-06-08 20:37:191459bool ChromeContentBrowserClient::CanCreateWindow(
[email protected]2b751a12012-03-06 03:00:351460 const GURL& opener_url,
[email protected]34eec7ffe32011-11-02 23:49:021461 const GURL& source_origin,
[email protected]9f3fba52011-06-08 20:37:191462 WindowContainerType container_type,
[email protected]df02aca2012-02-09 21:03:201463 content::ResourceContext* context,
[email protected]03b6d552012-03-29 04:03:011464 int render_process_id,
1465 bool* no_javascript_access) {
[email protected]9f3fba52011-06-08 20:37:191466 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]03b6d552012-03-29 04:03:011467
1468 *no_javascript_access = false;
1469
[email protected]9f3fba52011-06-08 20:37:191470 // If the opener is trying to create a background window but doesn't have
1471 // the appropriate permission, fail the attempt.
1472 if (container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) {
[email protected]df02aca2012-02-09 21:03:201473 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
[email protected]7b54ca02012-03-02 18:06:531474 ExtensionInfoMap* map = io_data->GetExtensionInfoMap();
1475
[email protected]03b6d552012-03-29 04:03:011476 if (!map->SecurityOriginHasAPIPermission(
1477 source_origin,
1478 render_process_id,
[email protected]c2e66e12012-06-27 06:27:061479 APIPermission::kBackground)) {
[email protected]03b6d552012-03-29 04:03:011480 return false;
1481 }
1482
[email protected]7b54ca02012-03-02 18:06:531483 // Note: this use of GetExtensionOrAppByURL is safe but imperfect. It may
1484 // return a recently installed Extension even if this CanCreateWindow call
1485 // was made by an old copy of the page in a normal web process. That's ok,
[email protected]03b6d552012-03-29 04:03:011486 // because the permission check above would have caused an early return
1487 // already. We must use the full URL to find hosted apps, though, and not
1488 // just the origin.
[email protected]7b54ca02012-03-02 18:06:531489 const Extension* extension = map->extensions().GetExtensionOrAppByURL(
[email protected]2b751a12012-03-06 03:00:351490 ExtensionURLInfo(opener_url));
[email protected]7b54ca02012-03-02 18:06:531491 if (extension && !extension->allow_background_js_access())
[email protected]03b6d552012-03-29 04:03:011492 *no_javascript_access = true;
[email protected]9f3fba52011-06-08 20:37:191493 }
1494 return true;
1495}
1496
1497std::string ChromeContentBrowserClient::GetWorkerProcessTitle(
[email protected]df02aca2012-02-09 21:03:201498 const GURL& url, content::ResourceContext* context) {
[email protected]9f3fba52011-06-08 20:37:191499 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1500 // Check if it's an extension-created worker, in which case we want to use
1501 // the name of the extension.
[email protected]df02aca2012-02-09 21:03:201502 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
[email protected]9f3fba52011-06-08 20:37:191503 const Extension* extension =
1504 io_data->GetExtensionInfoMap()->extensions().GetByID(url.host());
1505 return extension ? extension->name() : std::string();
1506}
1507
[email protected]99907362012-01-11 05:41:401508void ChromeContentBrowserClient::ResourceDispatcherHostCreated() {
1509 return g_browser_process->ResourceDispatcherHostCreated();
[email protected]3cb054e62011-06-13 05:21:171510}
1511
[email protected]c52b2892012-03-07 11:01:021512content::SpeechRecognitionManagerDelegate*
1513 ChromeContentBrowserClient::GetSpeechRecognitionManagerDelegate() {
[email protected]a03f2d32012-03-14 00:26:321514#if defined(ENABLE_INPUT_SPEECH)
[email protected]c52b2892012-03-07 11:01:021515 return new speech::ChromeSpeechRecognitionManagerDelegate();
[email protected]a03f2d32012-03-14 00:26:321516#else
1517 return NULL;
1518#endif
[email protected]66cfec62012-02-24 17:57:511519}
1520
[email protected]ae6e9912011-07-27 01:18:281521net::NetLog* ChromeContentBrowserClient::GetNetLog() {
1522 return g_browser_process->net_log();
1523}
1524
[email protected]32538d92011-08-25 00:09:231525AccessTokenStore* ChromeContentBrowserClient::CreateAccessTokenStore() {
1526 return new ChromeAccessTokenStore();
1527}
1528
[email protected]dbae6b02011-06-29 23:51:411529bool ChromeContentBrowserClient::IsFastShutdownPossible() {
1530 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
1531 return !browser_command_line.HasSwitch(switches::kChromeFrame);
1532}
1533
[email protected]64d69de42012-02-06 00:19:541534void ChromeContentBrowserClient::OverrideWebkitPrefs(
[email protected]2e21fe292012-03-02 22:52:321535 RenderViewHost* rvh, const GURL& url, WebPreferences* web_prefs) {
[email protected]f3986f82012-01-03 20:00:061536 Profile* profile = Profile::FromBrowserContext(
[email protected]9f76c1e2012-03-05 15:15:581537 rvh->GetProcess()->GetBrowserContext());
[email protected]f3986f82012-01-03 20:00:061538 PrefService* prefs = profile->GetPrefs();
[email protected]f3986f82012-01-03 20:00:061539
[email protected]f3986f82012-01-03 20:00:061540 FillFontFamilyMap(prefs, prefs::kWebKitStandardFontFamilyMap,
[email protected]64d69de42012-02-06 00:19:541541 &web_prefs->standard_font_family_map);
[email protected]f3986f82012-01-03 20:00:061542 FillFontFamilyMap(prefs, prefs::kWebKitFixedFontFamilyMap,
[email protected]64d69de42012-02-06 00:19:541543 &web_prefs->fixed_font_family_map);
[email protected]f3986f82012-01-03 20:00:061544 FillFontFamilyMap(prefs, prefs::kWebKitSerifFontFamilyMap,
[email protected]64d69de42012-02-06 00:19:541545 &web_prefs->serif_font_family_map);
[email protected]f3986f82012-01-03 20:00:061546 FillFontFamilyMap(prefs, prefs::kWebKitSansSerifFontFamilyMap,
[email protected]64d69de42012-02-06 00:19:541547 &web_prefs->sans_serif_font_family_map);
[email protected]f3986f82012-01-03 20:00:061548 FillFontFamilyMap(prefs, prefs::kWebKitCursiveFontFamilyMap,
[email protected]64d69de42012-02-06 00:19:541549 &web_prefs->cursive_font_family_map);
[email protected]f3986f82012-01-03 20:00:061550 FillFontFamilyMap(prefs, prefs::kWebKitFantasyFontFamilyMap,
[email protected]64d69de42012-02-06 00:19:541551 &web_prefs->fantasy_font_family_map);
[email protected]85edc232012-10-05 08:56:031552 FillFontFamilyMap(prefs, prefs::kWebKitPictographFontFamilyMap,
1553 &web_prefs->pictograph_font_family_map);
[email protected]f3986f82012-01-03 20:00:061554
[email protected]64d69de42012-02-06 00:19:541555 web_prefs->default_font_size =
[email protected]ddf72142012-05-22 04:52:401556 prefs->GetInteger(prefs::kWebKitDefaultFontSize);
[email protected]64d69de42012-02-06 00:19:541557 web_prefs->default_fixed_font_size =
[email protected]ddf72142012-05-22 04:52:401558 prefs->GetInteger(prefs::kWebKitDefaultFixedFontSize);
[email protected]64d69de42012-02-06 00:19:541559 web_prefs->minimum_font_size =
[email protected]ddf72142012-05-22 04:52:401560 prefs->GetInteger(prefs::kWebKitMinimumFontSize);
[email protected]64d69de42012-02-06 00:19:541561 web_prefs->minimum_logical_font_size =
[email protected]ddf72142012-05-22 04:52:401562 prefs->GetInteger(prefs::kWebKitMinimumLogicalFontSize);
[email protected]f3986f82012-01-03 20:00:061563
[email protected]ddf72142012-05-22 04:52:401564 web_prefs->default_encoding = prefs->GetString(prefs::kDefaultCharset);
[email protected]f3986f82012-01-03 20:00:061565
[email protected]64d69de42012-02-06 00:19:541566 web_prefs->javascript_can_open_windows_automatically =
[email protected]ddf72142012-05-22 04:52:401567 prefs->GetBoolean(prefs::kWebKitJavascriptCanOpenWindowsAutomatically);
[email protected]64d69de42012-02-06 00:19:541568 web_prefs->dom_paste_enabled =
[email protected]f3986f82012-01-03 20:00:061569 prefs->GetBoolean(prefs::kWebKitDomPasteEnabled);
[email protected]64d69de42012-02-06 00:19:541570 web_prefs->shrinks_standalone_images_to_fit =
[email protected]f3986f82012-01-03 20:00:061571 prefs->GetBoolean(prefs::kWebKitShrinksStandaloneImagesToFit);
1572 const DictionaryValue* inspector_settings =
1573 prefs->GetDictionary(prefs::kWebKitInspectorSettings);
1574 if (inspector_settings) {
1575 for (DictionaryValue::key_iterator iter(inspector_settings->begin_keys());
1576 iter != inspector_settings->end_keys(); ++iter) {
1577 std::string value;
1578 if (inspector_settings->GetStringWithoutPathExpansion(*iter, &value))
[email protected]64d69de42012-02-06 00:19:541579 web_prefs->inspector_settings.push_back(
[email protected]f3986f82012-01-03 20:00:061580 std::make_pair(*iter, value));
1581 }
1582 }
[email protected]64d69de42012-02-06 00:19:541583 web_prefs->tabs_to_links = prefs->GetBoolean(prefs::kWebkitTabsToLinks);
[email protected]f3986f82012-01-03 20:00:061584
[email protected]ddf72142012-05-22 04:52:401585 if (!prefs->GetBoolean(prefs::kWebKitJavascriptEnabled))
[email protected]64d69de42012-02-06 00:19:541586 web_prefs->javascript_enabled = false;
1587 if (!prefs->GetBoolean(prefs::kWebKitWebSecurityEnabled))
1588 web_prefs->web_security_enabled = false;
[email protected]ddf72142012-05-22 04:52:401589 if (!prefs->GetBoolean(prefs::kWebKitPluginsEnabled))
[email protected]64d69de42012-02-06 00:19:541590 web_prefs->plugins_enabled = false;
1591 if (!prefs->GetBoolean(prefs::kWebKitJavaEnabled))
1592 web_prefs->java_enabled = false;
1593 web_prefs->loads_images_automatically =
[email protected]ddf72142012-05-22 04:52:401594 prefs->GetBoolean(prefs::kWebKitLoadsImagesAutomatically);
[email protected]f3986f82012-01-03 20:00:061595
[email protected]64d69de42012-02-06 00:19:541596 if (prefs->GetBoolean(prefs::kDisable3DAPIs))
1597 web_prefs->experimental_webgl_enabled = false;
[email protected]f3986f82012-01-03 20:00:061598
[email protected]64d69de42012-02-06 00:19:541599 web_prefs->memory_info_enabled =
1600 prefs->GetBoolean(prefs::kEnableMemoryInfo);
1601 web_prefs->allow_displaying_insecure_content =
1602 prefs->GetBoolean(prefs::kWebKitAllowDisplayingInsecureContent);
1603 web_prefs->allow_running_insecure_content =
1604 prefs->GetBoolean(prefs::kWebKitAllowRunningInsecureContent);
[email protected]d3b935f2012-10-19 23:14:321605#if defined(OS_ANDROID)
1606 web_prefs->font_scale_factor =
1607 static_cast<float>(prefs->GetDouble(prefs::kWebKitFontScaleFactor));
1608 web_prefs->force_enable_zoom =
1609 prefs->GetBoolean(prefs::kWebKitForceEnableZoom);
1610#endif
[email protected]9d06d88d2012-02-23 22:37:081611 web_prefs->password_echo_enabled = browser_defaults::kPasswordEchoEnabled;
[email protected]f3986f82012-01-03 20:00:061612
[email protected]64d69de42012-02-06 00:19:541613 // The user stylesheet watcher may not exist in a testing profile.
[email protected]13169ab2012-04-06 07:48:151614 UserStyleSheetWatcher* user_style_sheet_watcher =
1615 UserStyleSheetWatcherFactory::GetForProfile(profile);
1616 if (user_style_sheet_watcher) {
[email protected]64d69de42012-02-06 00:19:541617 web_prefs->user_style_sheet_enabled = true;
1618 web_prefs->user_style_sheet_location =
[email protected]13169ab2012-04-06 07:48:151619 user_style_sheet_watcher->user_style_sheet();
[email protected]64d69de42012-02-06 00:19:541620 } else {
1621 web_prefs->user_style_sheet_enabled = false;
[email protected]f3986f82012-01-03 20:00:061622 }
1623
[email protected]b7e44ff2012-02-16 03:37:341624 web_prefs->asynchronous_spell_checking_enabled =
[email protected]37b928e2012-05-30 09:01:101625#if defined(OS_MACOSX)
1626 // TODO(hbono): Bug 107371: Implement asynchronous spellchecking API for
1627 // Mac so it uses NSSpellChecker in the background.
1628 false;
1629#else
[email protected]61806872012-12-12 04:15:361630 true;
[email protected]37b928e2012-05-30 09:01:101631#endif
[email protected]b7e44ff2012-02-16 03:37:341632 web_prefs->unified_textchecker_enabled =
[email protected]57890242012-10-23 17:46:521633 web_prefs->asynchronous_spell_checking_enabled;
[email protected]dd5d0fb2012-01-18 03:37:571634
[email protected]64d69de42012-02-06 00:19:541635 web_prefs->uses_universal_detector =
[email protected]f3986f82012-01-03 20:00:061636 prefs->GetBoolean(prefs::kWebKitUsesUniversalDetector);
[email protected]64d69de42012-02-06 00:19:541637 web_prefs->text_areas_are_resizable =
[email protected]f3986f82012-01-03 20:00:061638 prefs->GetBoolean(prefs::kWebKitTextAreasAreResizable);
[email protected]64d69de42012-02-06 00:19:541639 web_prefs->hyperlink_auditing_enabled =
[email protected]f3986f82012-01-03 20:00:061640 prefs->GetBoolean(prefs::kEnableHyperlinkAuditing);
1641
1642 // Make sure we will set the default_encoding with canonical encoding name.
[email protected]64d69de42012-02-06 00:19:541643 web_prefs->default_encoding =
[email protected]f3986f82012-01-03 20:00:061644 CharacterEncoding::GetCanonicalEncodingNameByAliasName(
[email protected]64d69de42012-02-06 00:19:541645 web_prefs->default_encoding);
1646 if (web_prefs->default_encoding.empty()) {
[email protected]ddf72142012-05-22 04:52:401647 prefs->ClearPref(prefs::kDefaultCharset);
1648 web_prefs->default_encoding = prefs->GetString(prefs::kDefaultCharset);
[email protected]f3986f82012-01-03 20:00:061649 }
[email protected]64d69de42012-02-06 00:19:541650 DCHECK(!web_prefs->default_encoding.empty());
[email protected]f3986f82012-01-03 20:00:061651
[email protected]88ecf66d2012-12-11 22:53:471652 if (content::IsForceCompositingModeEnabled())
1653 web_prefs->force_compositing_mode = true;
1654
[email protected]299d7f12012-05-23 05:31:151655 WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
1656 chrome::ViewType view_type = chrome::GetViewType(web_contents);
[email protected]06bdd2b2012-11-30 18:47:131657 ExtensionService* service =
1658 extensions::ExtensionSystem::Get(profile)->extension_service();
[email protected]f3986f82012-01-03 20:00:061659 if (service) {
[email protected]1bc28312012-11-08 08:31:531660 const GURL& url = rvh->GetSiteInstance()->GetSiteURL();
1661 const Extension* extension = service->extensions()->GetByID(url.host());
1662 // Ensure that we are only granting extension preferences to URLs with
1663 // the correct scheme. Without this check, chrome-guest:// schemes used by
1664 // webview tags as well as hosts that happen to match the id of an
1665 // installed extension would get the wrong preferences.
[email protected]885c0e92012-11-13 20:27:421666 if (url.SchemeIs(extensions::kExtensionScheme)) {
[email protected]1bc28312012-11-08 08:31:531667 extension_webkit_preferences::SetPreferences(
1668 extension, view_type, web_prefs);
1669 }
[email protected]f3986f82012-01-03 20:00:061670 }
1671
[email protected]299d7f12012-05-23 05:31:151672 if (view_type == chrome::VIEW_TYPE_NOTIFICATION) {
[email protected]64d69de42012-02-06 00:19:541673 web_prefs->allow_scripts_to_close_windows = true;
[email protected]299d7f12012-05-23 05:31:151674 } else if (view_type == chrome::VIEW_TYPE_BACKGROUND_CONTENTS) {
[email protected]f3986f82012-01-03 20:00:061675 // Disable all kinds of acceleration for background pages.
1676 // See http://crbug.com/96005 and http://crbug.com/96006
[email protected]64d69de42012-02-06 00:19:541677 web_prefs->force_compositing_mode = false;
1678 web_prefs->accelerated_compositing_enabled = false;
[email protected]f3986f82012-01-03 20:00:061679 }
[email protected]2e21fe292012-03-02 22:52:321680
1681#if defined(FILE_MANAGER_EXTENSION)
1682 // Override the default of suppressing HW compositing for WebUI pages for the
1683 // file manager, which is implemented using WebUI but wants HW acceleration
1684 // for video decode & render.
1685 if (url.spec() == chrome::kChromeUIFileManagerURL) {
1686 web_prefs->accelerated_compositing_enabled = true;
1687 web_prefs->accelerated_2d_canvas_enabled = true;
1688 }
1689#endif
[email protected]181a95ee2011-07-12 19:26:361690}
1691
1692void ChromeContentBrowserClient::UpdateInspectorSetting(
1693 RenderViewHost* rvh, const std::string& key, const std::string& value) {
[email protected]f3986f82012-01-03 20:00:061694 content::BrowserContext* browser_context =
[email protected]9f76c1e2012-03-05 15:15:581695 rvh->GetProcess()->GetBrowserContext();
[email protected]f3986f82012-01-03 20:00:061696 DictionaryPrefUpdate update(
1697 Profile::FromBrowserContext(browser_context)->GetPrefs(),
1698 prefs::kWebKitInspectorSettings);
1699 DictionaryValue* inspector_settings = update.Get();
1700 inspector_settings->SetWithoutPathExpansion(key,
1701 Value::CreateStringValue(value));
[email protected]181a95ee2011-07-12 19:26:361702}
1703
1704void ChromeContentBrowserClient::ClearInspectorSettings(RenderViewHost* rvh) {
[email protected]f3986f82012-01-03 20:00:061705 content::BrowserContext* browser_context =
[email protected]9f76c1e2012-03-05 15:15:581706 rvh->GetProcess()->GetBrowserContext();
[email protected]f3986f82012-01-03 20:00:061707 Profile::FromBrowserContext(browser_context)->GetPrefs()->
1708 ClearPref(prefs::kWebKitInspectorSettings);
[email protected]181a95ee2011-07-12 19:26:361709}
1710
[email protected]b8148ac2011-07-13 22:03:251711void ChromeContentBrowserClient::BrowserURLHandlerCreated(
1712 BrowserURLHandler* handler) {
1713 // Add the default URL handlers.
1714 handler->AddHandlerPair(&ExtensionWebUI::HandleChromeURLOverride,
1715 BrowserURLHandler::null_handler());
1716 handler->AddHandlerPair(BrowserURLHandler::null_handler(),
1717 &ExtensionWebUI::HandleChromeURLOverrideReverse);
1718
[email protected]b3adbd02011-11-30 22:23:271719 // about: handler. Must come before chrome: handler, since it will
1720 // rewrite about: urls to chrome: URLs and then expect chrome: to
1721 // actually handle them.
[email protected]b8148ac2011-07-13 22:03:251722 handler->AddHandlerPair(&WillHandleBrowserAboutURL,
1723 BrowserURLHandler::null_handler());
1724 // chrome: & friends.
[email protected]f8f93eb2012-09-25 03:06:241725 handler->AddHandlerPair(&HandleWebUI, &HandleWebUIReverse);
[email protected]b8148ac2011-07-13 22:03:251726}
1727
1728void ChromeContentBrowserClient::ClearCache(RenderViewHost* rvh) {
[email protected]3d7474ff2011-07-27 17:47:371729 Profile* profile = Profile::FromBrowserContext(
[email protected]9f76c1e2012-03-05 15:15:581730 rvh->GetSiteInstance()->GetProcess()->GetBrowserContext());
[email protected]38b892b42012-09-04 13:25:471731 BrowsingDataRemover* remover =
1732 BrowsingDataRemover::CreateForUnboundedRange(profile);
[email protected]3d4d4cf2012-06-04 10:40:551733 remover->Remove(BrowsingDataRemover::REMOVE_CACHE,
1734 BrowsingDataHelper::UNPROTECTED_WEB);
[email protected]b8148ac2011-07-13 22:03:251735 // BrowsingDataRemover takes care of deleting itself when done.
1736}
1737
1738void ChromeContentBrowserClient::ClearCookies(RenderViewHost* rvh) {
[email protected]3d7474ff2011-07-27 17:47:371739 Profile* profile = Profile::FromBrowserContext(
[email protected]9f76c1e2012-03-05 15:15:581740 rvh->GetSiteInstance()->GetProcess()->GetBrowserContext());
[email protected]38b892b42012-09-04 13:25:471741 BrowsingDataRemover* remover =
1742 BrowsingDataRemover::CreateForUnboundedRange(profile);
[email protected]dceaa912011-09-06 17:17:231743 int remove_mask = BrowsingDataRemover::REMOVE_SITE_DATA;
[email protected]3d4d4cf2012-06-04 10:40:551744 remover->Remove(remove_mask, BrowsingDataHelper::UNPROTECTED_WEB);
[email protected]b8148ac2011-07-13 22:03:251745 // BrowsingDataRemover takes care of deleting itself when done.
1746}
1747
[email protected]e1d16eb92011-08-18 23:19:321748FilePath ChromeContentBrowserClient::GetDefaultDownloadDirectory() {
1749 return download_util::GetDefaultDownloadDirectory();
1750}
1751
[email protected]c9b6eb62011-10-18 20:49:391752std::string ChromeContentBrowserClient::GetDefaultDownloadName() {
1753 return l10n_util::GetStringUTF8(IDS_DEFAULT_DOWNLOAD_FILENAME);
1754}
1755
[email protected]b7631cc2012-09-15 05:08:381756void ChromeContentBrowserClient::DidCreatePpapiPlugin(
1757 content::BrowserPpapiHost* browser_host) {
[email protected]6d17f6392012-12-05 05:24:541758#if defined(ENABLE_PLUGINS)
[email protected]b7631cc2012-09-15 05:08:381759 browser_host->GetPpapiHost()->AddHostFactoryFilter(
1760 scoped_ptr<ppapi::host::HostFactory>(
1761 new ChromeBrowserPepperHostFactory(browser_host)));
[email protected]6d17f6392012-12-05 05:24:541762#endif
[email protected]b7631cc2012-09-15 05:08:381763}
1764
[email protected]0c7193742012-11-07 19:05:031765content::BrowserPpapiHost*
1766 ChromeContentBrowserClient::GetExternalBrowserPpapiHost(
1767 int plugin_process_id) {
1768 BrowserChildProcessHostIterator iter(content::PROCESS_TYPE_NACL_LOADER);
1769 while (!iter.Done()) {
1770 NaClProcessHost* host = static_cast<NaClProcessHost*>(iter.GetDelegate());
1771 if (host->process() &&
1772 host->process()->GetData().id == plugin_process_id) {
1773 // Found the plugin.
1774 return host->browser_ppapi_host();
1775 }
1776 ++iter;
1777 }
1778 return NULL;
1779}
1780
[email protected]38cd8f7f2012-06-15 22:06:071781bool ChromeContentBrowserClient::AllowPepperSocketAPI(
[email protected]157cc902012-11-02 06:31:581782 content::BrowserContext* browser_context,
1783 const GURL& url,
1784 const content::SocketPermissionRequest& params) {
[email protected]a658d452012-03-02 12:45:291785 if (!url.is_valid())
1786 return false;
1787
1788 std::string host = url.host();
[email protected]885c0e92012-11-13 20:27:421789 if (url.SchemeIs(extensions::kExtensionScheme) &&
1790 allowed_socket_origins_.count(host)) {
[email protected]a658d452012-03-02 12:45:291791 return true;
[email protected]885c0e92012-11-13 20:27:421792 }
[email protected]a658d452012-03-02 12:45:291793
[email protected]9a5940d2012-04-27 19:16:231794 Profile* profile = Profile::FromBrowserContext(browser_context);
1795 const Extension* extension = NULL;
[email protected]2ee3da9d62012-12-05 20:17:191796 ExtensionService* extension_service = !profile ? NULL :
[email protected]06bdd2b2012-11-30 18:47:131797 extensions::ExtensionSystem::Get(profile)->extension_service();
1798 if (extension_service) {
1799 extension = extension_service->extensions()->
[email protected]9a5940d2012-04-27 19:16:231800 GetExtensionOrAppByURL(ExtensionURLInfo(url));
1801 }
1802
[email protected]f237c0f2012-03-10 07:49:101803 // Need to check this now and not on construction because otherwise it won't
1804 // work with browser_tests.
1805 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1806 std::string allowed_list =
1807 command_line.GetSwitchValueASCII(switches::kAllowNaClSocketAPI);
[email protected]9a5940d2012-04-27 19:16:231808 if (allowed_list == "*") {
1809 // The wildcard allows socket API only for packaged and platform apps.
1810 return extension &&
[email protected]c4f459d2012-09-28 04:40:101811 (extension->GetType() == Extension::TYPE_LEGACY_PACKAGED_APP ||
[email protected]9a5940d2012-04-27 19:16:231812 extension->GetType() == Extension::TYPE_PLATFORM_APP);
1813 } else if (!allowed_list.empty()) {
[email protected]f237c0f2012-03-10 07:49:101814 StringTokenizer t(allowed_list, ",");
1815 while (t.GetNext()) {
1816 if (t.token() == host)
1817 return true;
1818 }
1819 }
1820
[email protected]a658d452012-03-02 12:45:291821 if (!extension)
1822 return false;
1823
[email protected]157cc902012-11-02 06:31:581824 extensions::SocketPermission::CheckParam extension_params(
1825 params.type, params.host, params.port);
1826 if (extension->CheckAPIPermissionWithParam(APIPermission::kSocket,
1827 &extension_params))
[email protected]a658d452012-03-02 12:45:291828 return true;
1829
1830 return false;
[email protected]e461da2f2012-02-16 19:06:401831}
1832
[email protected]a7944aa2012-10-15 10:12:141833FilePath ChromeContentBrowserClient::GetHyphenDictionaryDirectory() {
1834 FilePath directory;
1835 PathService::Get(chrome::DIR_APP_DICTIONARIES, &directory);
1836 return directory.Append(FILE_PATH_LITERAL("Hyphen"));
1837}
1838
[email protected]e60c0232011-11-11 19:56:351839#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]a1733df2012-06-22 11:24:181840void ChromeContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
1841 const CommandLine& command_line,
[email protected]40da3e0c2012-10-24 22:03:381842 int child_process_id,
[email protected]c7abd422012-09-25 00:20:081843 std::vector<FileDescriptorInfo>* mappings) {
[email protected]29699c22012-10-03 23:57:391844#if defined(OS_ANDROID)
1845 FilePath data_path;
1846 PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &data_path);
1847 DCHECK(!data_path.empty());
1848
1849 int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ;
1850 FilePath chrome_pak = data_path.AppendASCII("chrome.pak");
1851 base::PlatformFile f =
1852 base::CreatePlatformFile(chrome_pak, flags, NULL, NULL);
1853 DCHECK(f != base::kInvalidPlatformFileValue);
1854 mappings->push_back(FileDescriptorInfo(kAndroidChromePakDescriptor,
1855 FileDescriptor(f, true)));
1856
1857 FilePath chrome_resources_pak =
1858 data_path.AppendASCII("chrome_100_percent.pak");
1859 f = base::CreatePlatformFile(chrome_resources_pak, flags, NULL, NULL);
1860 DCHECK(f != base::kInvalidPlatformFileValue);
1861 mappings->push_back(FileDescriptorInfo(kAndroidUIResourcesPakDescriptor,
1862 FileDescriptor(f, true)));
1863
1864 const std::string locale = GetApplicationLocale();
1865 FilePath locale_pak = ResourceBundle::GetSharedInstance().
1866 GetLocaleFilePath(locale, false);
1867 f = base::CreatePlatformFile(locale_pak, flags, NULL, NULL);
1868 DCHECK(f != base::kInvalidPlatformFileValue);
1869 mappings->push_back(FileDescriptorInfo(kAndroidLocalePakDescriptor,
1870 FileDescriptor(f, true)));
[email protected]40da3e0c2012-10-24 22:03:381871
1872#if defined(USE_LINUX_BREAKPAD)
1873 f = crash_dump_manager_->CreateMinidumpFile(child_process_id);
1874 if (f == base::kInvalidPlatformFileValue) {
1875 LOG(ERROR) << "Failed to create file for minidump, crash reporting will be "
1876 "disabled for this process.";
1877 } else {
1878 mappings->push_back(FileDescriptorInfo(kAndroidMinidumpDescriptor,
1879 FileDescriptor(f, true)));
1880 }
1881#endif // defined(USE_LINUX_BREAKPAD)
1882
1883#else
1884 int crash_signal_fd = GetCrashSignalFD(command_line);
1885 if (crash_signal_fd >= 0) {
1886 mappings->push_back(FileDescriptorInfo(kCrashDumpSignal,
1887 FileDescriptor(crash_signal_fd,
1888 false)));
1889 }
[email protected]29699c22012-10-03 23:57:391890#endif // defined(OS_ANDROID)
[email protected]b80f68432011-05-02 17:22:301891}
[email protected]e60c0232011-11-11 19:56:351892#endif // defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]b80f68432011-05-02 17:22:301893
[email protected]4a65826d2011-08-25 16:04:011894#if defined(OS_WIN)
1895const wchar_t* ChromeContentBrowserClient::GetResourceDllName() {
1896 return chrome::kBrowserResourcesDll;
1897}
1898#endif
1899
[email protected]40da3e0c2012-10-24 22:03:381900#if defined(OS_ANDROID)
1901void ChromeContentBrowserClient::InitCrashDumpManager() {
1902 if (!crash_dump_manager_.get())
1903 crash_dump_manager_.reset(new CrashDumpManager());
1904}
1905#endif
1906
[email protected]37a72af2011-06-13 05:42:011907#if defined(USE_NSS)
1908crypto::CryptoModuleBlockingPasswordDelegate*
1909 ChromeContentBrowserClient::GetCryptoPasswordDelegate(
1910 const GURL& url) {
[email protected]6246ac52012-09-24 01:55:291911 return chrome::NewCryptoModuleBlockingDialogDelegate(
1912 chrome::kCryptoModulePasswordKeygen, url.host());
[email protected]37a72af2011-06-13 05:42:011913}
1914#endif
1915
[email protected]e9a32a52012-06-14 23:32:431916void ChromeContentBrowserClient::SetApplicationLocale(
1917 const std::string& locale) {
1918 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1919
1920 // This object is guaranteed to outlive all threads so we don't have to
1921 // worry about the lack of refcounting and can just post as Unretained.
1922 //
1923 // The common case is that this function is called early in Chrome startup
1924 // before any threads are created (it will also be called later if the user
1925 // changes the pref). In this case, there will be no threads created and
1926 // posting will fail. When there are no threads, we can just set the string
1927 // without worrying about threadsafety.
1928 if (!BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
1929 base::Bind(
1930 &ChromeContentBrowserClient::SetApplicationLocaleOnIOThread,
1931 base::Unretained(this), locale)))
1932 io_thread_application_locale_ = locale;
1933}
1934
1935void ChromeContentBrowserClient::SetApplicationLocaleOnIOThread(
1936 const std::string& locale) {
1937 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1938 io_thread_application_locale_ = locale;
1939}
1940
[email protected]d977f9c2011-03-14 16:10:261941} // namespace chrome