blob: 692f406373fb0a9160b437294bc89d40312c4b76 [file] [log] [blame]
[email protected]d977f9c2011-03-14 16:10:261// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/chrome_content_browser_client.h"
6
[email protected]b80f68432011-05-02 17:22:307#include "base/command_line.h"
8#include "chrome/app/breakpad_mac.h"
9#include "chrome/browser/browser_process.h"
[email protected]763ec4ca2011-04-29 15:48:1210#include "chrome/browser/character_encoding.h"
[email protected]97e6c4c2011-05-18 16:08:5111#include "chrome/browser/chrome_plugin_message_filter.h"
[email protected]317f96c92011-05-31 06:53:4112#include "chrome/browser/chrome_quota_permission_context.h"
[email protected]5327dfb2011-05-03 17:50:3613#include "chrome/browser/chrome_worker_message_filter.h"
[email protected]a2176792011-05-08 19:30:4914#include "chrome/browser/content_settings/host_content_settings_map.h"
[email protected]8093a542011-05-13 07:29:3215#include "chrome/browser/content_settings/tab_specific_content_settings.h"
[email protected]f364d1392011-04-08 21:03:1016#include "chrome/browser/debugger/devtools_handler.h"
17#include "chrome/browser/desktop_notification_handler.h"
[email protected]f364d1392011-04-08 21:03:1018#include "chrome/browser/extensions/extension_message_handler.h"
[email protected]d977f9c2011-03-14 16:10:2619#include "chrome/browser/extensions/extension_service.h"
[email protected]763ec4ca2011-04-29 15:48:1220#include "chrome/browser/google/google_util.h"
[email protected]0609b17f2011-05-31 20:13:4221#include "chrome/browser/platform_util.h"
[email protected]763ec4ca2011-04-29 15:48:1222#include "chrome/browser/prefs/pref_service.h"
[email protected]05fcf982011-04-19 00:44:1423#include "chrome/browser/printing/printing_message_filter.h"
24#include "chrome/browser/profiles/profile.h"
[email protected]8093a542011-05-13 07:29:3225#include "chrome/browser/profiles/profile_io_data.h"
[email protected]05fcf982011-04-19 00:44:1426#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
[email protected]53a0afa2011-04-28 02:09:3327#include "chrome/browser/renderer_host/chrome_render_view_host_observer.h"
[email protected]d4cff272011-05-02 15:46:0128#include "chrome/browser/renderer_host/text_input_client_message_filter.h"
[email protected]05fcf982011-04-19 00:44:1429#include "chrome/browser/search_engines/search_provider_install_state_message_filter.h"
30#include "chrome/browser/spellcheck_message_filter.h"
[email protected]8ec26472011-06-06 16:52:4531#include "chrome/browser/ssl/ssl_add_cert_handler.h"
[email protected]848dd042011-06-04 18:24:0332#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]8ec26472011-06-06 16:52:4533#include "chrome/browser/tab_contents/tab_contents_ssl_helper.h"
34#include "chrome/browser/tab_contents/tab_util.h"
35#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]1fd1a502011-03-30 16:55:5636#include "chrome/browser/ui/webui/chrome_web_ui_factory.h"
[email protected]b80f68432011-05-02 17:22:3037#include "chrome/common/child_process_logging.h"
38#include "chrome/common/chrome_switches.h"
[email protected]c5dbef02011-05-13 05:06:0939#include "chrome/common/extensions/extension_messages.h"
[email protected]763ec4ca2011-04-29 15:48:1240#include "chrome/common/pref_names.h"
[email protected]3e69bc82011-05-26 23:22:3841#include "chrome/common/render_messages.h"
[email protected]c5dbef02011-05-13 05:06:0942#include "chrome/common/url_constants.h"
43#include "content/browser/browsing_instance.h"
44#include "content/browser/child_process_security_policy.h"
[email protected]97e6c4c2011-05-18 16:08:5145#include "content/browser/plugin_process_host.h"
[email protected]05fcf982011-04-19 00:44:1446#include "content/browser/renderer_host/browser_render_process_host.h"
[email protected]d977f9c2011-03-14 16:10:2647#include "content/browser/renderer_host/render_view_host.h"
[email protected]a2176792011-05-08 19:30:4948#include "content/browser/resource_context.h"
[email protected]c5dbef02011-05-13 05:06:0949#include "content/browser/site_instance.h"
[email protected]8ec26472011-06-06 16:52:4550#include "content/browser/ssl/ssl_client_auth_handler.h"
[email protected]763ec4ca2011-04-29 15:48:1251#include "content/browser/tab_contents/tab_contents.h"
[email protected]5327dfb2011-05-03 17:50:3652#include "content/browser/worker_host/worker_process_host.h"
[email protected]c5dbef02011-05-13 05:06:0953#include "content/common/bindings_policy.h"
[email protected]ed24fad2011-05-10 22:44:0154#include "net/base/cookie_monster.h"
55#include "net/base/cookie_options.h"
[email protected]d977f9c2011-03-14 16:10:2656
[email protected]b80f68432011-05-02 17:22:3057#if defined(OS_LINUX)
58#include "base/linux_util.h"
59#include "chrome/browser/crash_handler_host_linux.h"
[email protected]1fd5302c2011-05-28 04:06:4360#endif
[email protected]b80f68432011-05-02 17:22:3061
[email protected]c5dbef02011-05-13 05:06:0962namespace {
63
64void InitRenderViewHostForExtensions(RenderViewHost* render_view_host) {
65 // Note that due to GetEffectiveURL(), even hosted apps will have a
66 // chrome-extension:// URL for their site, so we can ignore that wrinkle here.
67 SiteInstance* site_instance = render_view_host->site_instance();
68 const GURL& site = site_instance->site();
69 RenderProcessHost* process = render_view_host->process();
70
71 if (!site.SchemeIs(chrome::kExtensionScheme))
72 return;
73
74 Profile* profile = site_instance->browsing_instance()->profile();
75 ExtensionService* service = profile->GetExtensionService();
76 if (!service)
77 return;
78
79 ExtensionProcessManager* process_manager =
80 profile->GetExtensionProcessManager();
81 CHECK(process_manager);
82
83 // This can happen if somebody typos a chrome-extension:// URL.
84 const Extension* extension = service->GetExtensionByURL(site);
85 if (!extension)
86 return;
87
88 site_instance->GetProcess()->mark_is_extension_process();
89
90 // Register the association between extension and process with
91 // ExtensionProcessManager.
92 process_manager->RegisterExtensionProcess(extension->id(), process->id());
93
94 // Record which, if any, installed app is associated with this process.
95 // TODO(aa): Totally lame to store this state in a global map in extension
96 // service. Can we get it from EPM instead?
97 if (extension->is_app())
98 service->SetInstalledAppForRenderer(process->id(), extension);
99
100 // Some extensions use chrome:// URLs.
101 Extension::Type type = extension->GetType();
102 if (type == Extension::TYPE_EXTENSION ||
103 type == Extension::TYPE_PACKAGED_APP) {
104 ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
105 process->id(), chrome::kChromeUIScheme);
106 }
107
108 // Enable extension bindings for the renderer. Currently only extensions,
109 // packaged apps, and hosted component apps use extension bindings.
110 if (type == Extension::TYPE_EXTENSION ||
[email protected]2333bf22011-05-19 02:16:51111 type == Extension::TYPE_USER_SCRIPT ||
[email protected]c5dbef02011-05-13 05:06:09112 type == Extension::TYPE_PACKAGED_APP ||
113 (type == Extension::TYPE_HOSTED_APP &&
114 extension->location() == Extension::COMPONENT)) {
115 render_view_host->Send(new ExtensionMsg_ActivateExtension(extension->id()));
116 render_view_host->AllowBindings(BindingsPolicy::EXTENSION);
117 }
118}
119
120}
121
[email protected]d977f9c2011-03-14 16:10:26122namespace chrome {
123
[email protected]f364d1392011-04-08 21:03:10124void ChromeContentBrowserClient::RenderViewHostCreated(
125 RenderViewHost* render_view_host) {
[email protected]53a0afa2011-04-28 02:09:33126 new ChromeRenderViewHostObserver(render_view_host);
[email protected]f364d1392011-04-08 21:03:10127 new DesktopNotificationHandler(render_view_host);
128 new DevToolsHandler(render_view_host);
129 new ExtensionMessageHandler(render_view_host);
[email protected]f364d1392011-04-08 21:03:10130
[email protected]c5dbef02011-05-13 05:06:09131 InitRenderViewHostForExtensions(render_view_host);
[email protected]d977f9c2011-03-14 16:10:26132}
133
[email protected]05fcf982011-04-19 00:44:14134void ChromeContentBrowserClient::BrowserRenderProcessHostCreated(
135 BrowserRenderProcessHost* host) {
[email protected]c47cfd62011-04-29 21:27:02136 int id = host->id();
137 Profile* profile = host->profile();
[email protected]05fcf982011-04-19 00:44:14138 host->channel()->AddFilter(new ChromeRenderMessageFilter(
[email protected]c47cfd62011-04-29 21:27:02139 id, profile, profile->GetRequestContextForRenderProcess(id)));
[email protected]05fcf982011-04-19 00:44:14140 host->channel()->AddFilter(new PrintingMessageFilter());
141 host->channel()->AddFilter(
[email protected]c47cfd62011-04-29 21:27:02142 new SearchProviderInstallStateMessageFilter(id, profile));
143 host->channel()->AddFilter(new SpellCheckMessageFilter(id));
[email protected]d4cff272011-05-02 15:46:01144#if defined(OS_MACOSX)
145 host->channel()->AddFilter(new TextInputClientMessageFilter(host->id()));
146#endif
[email protected]3e69bc82011-05-26 23:22:38147
148 host->Send(new ViewMsg_SetIsIncognitoProcess(profile->IsOffTheRecord()));
[email protected]05fcf982011-04-19 00:44:14149}
150
[email protected]97e6c4c2011-05-18 16:08:51151void ChromeContentBrowserClient::PluginProcessHostCreated(
152 PluginProcessHost* host) {
153 host->AddFilter(new ChromePluginMessageFilter(host));
154}
155
[email protected]5327dfb2011-05-03 17:50:36156void ChromeContentBrowserClient::WorkerProcessHostCreated(
157 WorkerProcessHost* host) {
158 host->AddFilter(new ChromeWorkerMessageFilter(host));
159}
160
[email protected]1fd1a502011-03-30 16:55:56161content::WebUIFactory* ChromeContentBrowserClient::GetWebUIFactory() {
162 return ChromeWebUIFactory::GetInstance();
163}
164
[email protected]36fb2c7c2011-04-04 15:49:08165GURL ChromeContentBrowserClient::GetEffectiveURL(Profile* profile,
166 const GURL& url) {
167 // Get the effective URL for the given actual URL. If the URL is part of an
168 // installed app, the effective URL is an extension URL with the ID of that
169 // extension as the host. This has the effect of grouping apps together in
170 // a common SiteInstance.
171 if (!profile || !profile->GetExtensionService())
172 return url;
173
174 const Extension* extension =
175 profile->GetExtensionService()->GetExtensionByWebExtent(url);
176 if (!extension)
177 return url;
178
179 // If the URL is part of an extension's web extent, convert it to an
180 // extension URL.
181 return extension->GetResourceURL(url.path());
182}
183
[email protected]0f012df82011-05-19 14:15:29184bool ChromeContentBrowserClient::IsURLSameAsAnySiteInstance(const GURL& url) {
185 return url.spec() == chrome::kAboutKillURL ||
186 url.spec() == chrome::kAboutHangURL ||
187 url.spec() == chrome::kAboutShorthangURL;
188}
189
[email protected]763ec4ca2011-04-29 15:48:12190std::string ChromeContentBrowserClient::GetCanonicalEncodingNameByAliasName(
191 const std::string& alias_name) {
192 return CharacterEncoding::GetCanonicalEncodingNameByAliasName(alias_name);
193}
194
[email protected]b80f68432011-05-02 17:22:30195void ChromeContentBrowserClient::AppendExtraCommandLineSwitches(
196 CommandLine* command_line, int child_process_id) {
197#if defined(USE_LINUX_BREAKPAD)
198 if (IsCrashReporterEnabled()) {
199 command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
200 child_process_logging::GetClientId() + "," + base::GetLinuxDistro());
201 }
202#elif defined(OS_MACOSX)
203 if (IsCrashReporterEnabled()) {
204 command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
205 child_process_logging::GetClientId());
206 }
207#endif // OS_MACOSX
208
209 std::string process_type =
210 command_line->GetSwitchValueASCII(switches::kProcessType);
211 if (process_type == switches::kExtensionProcess ||
212 process_type == switches::kRendererProcess) {
213 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
214 FilePath user_data_dir =
215 browser_command_line.GetSwitchValuePath(switches::kUserDataDir);
216 if (!user_data_dir.empty())
217 command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir);
218#if defined(OS_CHROMEOS)
219 const std::string& login_profile =
220 browser_command_line.GetSwitchValueASCII(switches::kLoginProfile);
221 if (!login_profile.empty())
222 command_line->AppendSwitchASCII(switches::kLoginProfile, login_profile);
223#endif
224
225 RenderProcessHost* process = RenderProcessHost::FromID(child_process_id);
226
227 PrefService* prefs = process->profile()->GetPrefs();
228 // Currently this pref is only registered if applied via a policy.
229 if (prefs->HasPrefPath(prefs::kDisable3DAPIs) &&
230 prefs->GetBoolean(prefs::kDisable3DAPIs)) {
231 // Turn this policy into a command line switch.
232 command_line->AppendSwitch(switches::kDisable3DAPIs);
233 }
234
235 // Disable client-side phishing detection in the renderer if it is disabled
236 // in the browser process.
237 if (!g_browser_process->safe_browsing_detection_service())
238 command_line->AppendSwitch(switches::kDisableClientSidePhishingDetection);
239 }
240}
241
242std::string ChromeContentBrowserClient::GetApplicationLocale() {
243 return g_browser_process->GetApplicationLocale();
244}
245
[email protected]b5cca982011-05-26 04:42:08246std::string ChromeContentBrowserClient::GetAcceptLangs(const TabContents* tab) {
247 return tab->profile()->GetPrefs()->GetString(prefs::kAcceptLanguages);
248}
249
[email protected]a2176792011-05-08 19:30:49250bool ChromeContentBrowserClient::AllowAppCache(
[email protected]5b52ad42011-05-26 14:26:09251 const GURL& manifest_url,
252 const content::ResourceContext& context) {
[email protected]8093a542011-05-13 07:29:32253 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
254 ProfileIOData* io_data =
255 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09256 // FIXME(jochen): get the correct top-level origin.
[email protected]efa55212011-05-13 16:19:38257 ContentSetting setting = io_data->GetHostContentSettingsMap()->
[email protected]5b52ad42011-05-26 14:26:09258 GetCookieContentSetting(manifest_url, manifest_url, true);
[email protected]a2176792011-05-08 19:30:49259 DCHECK(setting != CONTENT_SETTING_DEFAULT);
260 return setting != CONTENT_SETTING_BLOCK;
261}
262
[email protected]ed24fad2011-05-10 22:44:01263bool ChromeContentBrowserClient::AllowGetCookie(
264 const GURL& url,
265 const GURL& first_party,
266 const net::CookieList& cookie_list,
267 const content::ResourceContext& context,
268 int render_process_id,
269 int render_view_id) {
270 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]8093a542011-05-13 07:29:32271 ProfileIOData* io_data =
272 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09273 ContentSetting setting = io_data->GetHostContentSettingsMap()->
274 GetCookieContentSetting(url, first_party, false);
275 bool allow = setting == CONTENT_SETTING_ALLOW ||
276 setting == CONTENT_SETTING_SESSION_ONLY;
[email protected]ed24fad2011-05-10 22:44:01277
[email protected]8093a542011-05-13 07:29:32278 BrowserThread::PostTask(
279 BrowserThread::UI, FROM_HERE,
280 NewRunnableFunction(
281 &TabSpecificContentSettings::CookiesRead,
282 render_process_id, render_view_id, url, cookie_list, !allow));
[email protected]ed24fad2011-05-10 22:44:01283 return allow;
284}
285
286bool ChromeContentBrowserClient::AllowSetCookie(
287 const GURL& url,
288 const GURL& first_party,
289 const std::string& cookie_line,
290 const content::ResourceContext& context,
291 int render_process_id,
292 int render_view_id,
293 net::CookieOptions* options) {
294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]8093a542011-05-13 07:29:32295 ProfileIOData* io_data =
296 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09297 ContentSetting setting = io_data->GetHostContentSettingsMap()->
298 GetCookieContentSetting(url, first_party, true);
[email protected]ed24fad2011-05-10 22:44:01299
[email protected]5b52ad42011-05-26 14:26:09300 if (setting == CONTENT_SETTING_SESSION_ONLY)
301 options->set_force_session();
[email protected]ed24fad2011-05-10 22:44:01302
[email protected]5b52ad42011-05-26 14:26:09303 bool allow = setting == CONTENT_SETTING_ALLOW ||
304 setting == CONTENT_SETTING_SESSION_ONLY;
[email protected]ed24fad2011-05-10 22:44:01305
[email protected]8093a542011-05-13 07:29:32306 BrowserThread::PostTask(
307 BrowserThread::UI, FROM_HERE,
308 NewRunnableFunction(
309 &TabSpecificContentSettings::CookieChanged,
310 render_process_id, render_view_id, url, cookie_line, *options,
311 !allow));
[email protected]ed24fad2011-05-10 22:44:01312 return allow;
313}
314
[email protected]317f96c92011-05-31 06:53:41315QuotaPermissionContext*
316ChromeContentBrowserClient::CreateQuotaPermissionContext() {
317 return new ChromeQuotaPermissionContext();
318}
319
[email protected]0609b17f2011-05-31 20:13:42320void ChromeContentBrowserClient::RevealFolderInOS(const FilePath& path) {
321 // On Mac, this call needs to be done on the UI thread. On other platforms,
322 // do it on the FILE thread so we don't slow down UI.
323#if defined(OS_MACOSX)
324 platform_util::OpenItem(path);
325#else
326 BrowserThread::PostTask(
327 BrowserThread::FILE, FROM_HERE,
328 NewRunnableFunction(&platform_util::OpenItem, path));
329#endif
330}
331
[email protected]848dd042011-06-04 18:24:03332void ChromeContentBrowserClient::AllowCertificateError(
333 SSLCertErrorHandler* handler,
334 bool overridable,
335 Callback2<SSLCertErrorHandler*, bool>::Type* callback) {
336 SSLBlockingPage* blocking_page = new SSLBlockingPage(
337 handler, overridable, callback);
338 blocking_page->Show();
339}
340
[email protected]8ec26472011-06-06 16:52:45341void ChromeContentBrowserClient::ShowClientCertificateRequestDialog(
342 int render_process_id,
343 int render_view_id,
344 SSLClientAuthHandler* handler) {
345 TabContents* tab = tab_util::GetTabContentsByID(
346 render_process_id, render_view_id);
347 if (!tab) {
348 NOTREACHED();
349 return;
350 }
351
352 TabContentsWrapper* wrapper =
353 TabContentsWrapper::GetCurrentWrapperForContents(tab);
354 wrapper->ssl_helper()->ShowClientCertificateRequestDialog(handler);
355}
356
357void ChromeContentBrowserClient::AddNewCertificate(
358 net::URLRequest* request,
359 net::X509Certificate* cert,
360 int render_process_id,
361 int render_view_id) {
362 // The handler will run the UI and delete itself when it's finished.
363 new SSLAddCertHandler(request, cert, render_process_id, render_view_id);
364}
365
[email protected]b80f68432011-05-02 17:22:30366#if defined(OS_LINUX)
367int ChromeContentBrowserClient::GetCrashSignalFD(
368 const std::string& process_type) {
369 if (process_type == switches::kRendererProcess)
370 return RendererCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
371
372 if (process_type == switches::kPluginProcess)
373 return PluginCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
374
375 if (process_type == switches::kPpapiPluginProcess)
376 return PpapiCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
377
378 if (process_type == switches::kGpuProcess)
379 return GpuCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
380
381 return -1;
382}
383#endif
384
[email protected]d977f9c2011-03-14 16:10:26385} // namespace chrome