blob: d6dcc572a977587eb893aaca7130ce25a9831f08 [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"
21#include "chrome/browser/prefs/pref_service.h"
[email protected]05fcf982011-04-19 00:44:1422#include "chrome/browser/printing/printing_message_filter.h"
23#include "chrome/browser/profiles/profile.h"
[email protected]8093a542011-05-13 07:29:3224#include "chrome/browser/profiles/profile_io_data.h"
[email protected]05fcf982011-04-19 00:44:1425#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
[email protected]53a0afa2011-04-28 02:09:3326#include "chrome/browser/renderer_host/chrome_render_view_host_observer.h"
[email protected]d4cff272011-05-02 15:46:0127#include "chrome/browser/renderer_host/text_input_client_message_filter.h"
[email protected]05fcf982011-04-19 00:44:1428#include "chrome/browser/search_engines/search_provider_install_state_message_filter.h"
29#include "chrome/browser/spellcheck_message_filter.h"
[email protected]1fd1a502011-03-30 16:55:5630#include "chrome/browser/ui/webui/chrome_web_ui_factory.h"
[email protected]b80f68432011-05-02 17:22:3031#include "chrome/common/child_process_logging.h"
32#include "chrome/common/chrome_switches.h"
[email protected]c5dbef02011-05-13 05:06:0933#include "chrome/common/extensions/extension_messages.h"
[email protected]763ec4ca2011-04-29 15:48:1234#include "chrome/common/pref_names.h"
[email protected]3e69bc82011-05-26 23:22:3835#include "chrome/common/render_messages.h"
[email protected]c5dbef02011-05-13 05:06:0936#include "chrome/common/url_constants.h"
37#include "content/browser/browsing_instance.h"
38#include "content/browser/child_process_security_policy.h"
[email protected]97e6c4c2011-05-18 16:08:5139#include "content/browser/plugin_process_host.h"
[email protected]05fcf982011-04-19 00:44:1440#include "content/browser/renderer_host/browser_render_process_host.h"
[email protected]d977f9c2011-03-14 16:10:2641#include "content/browser/renderer_host/render_view_host.h"
[email protected]a2176792011-05-08 19:30:4942#include "content/browser/resource_context.h"
[email protected]c5dbef02011-05-13 05:06:0943#include "content/browser/site_instance.h"
[email protected]763ec4ca2011-04-29 15:48:1244#include "content/browser/tab_contents/tab_contents.h"
[email protected]5327dfb2011-05-03 17:50:3645#include "content/browser/worker_host/worker_process_host.h"
[email protected]c5dbef02011-05-13 05:06:0946#include "content/common/bindings_policy.h"
[email protected]ed24fad2011-05-10 22:44:0147#include "net/base/cookie_monster.h"
48#include "net/base/cookie_options.h"
[email protected]d977f9c2011-03-14 16:10:2649
[email protected]b80f68432011-05-02 17:22:3050#if defined(OS_LINUX)
51#include "base/linux_util.h"
52#include "chrome/browser/crash_handler_host_linux.h"
[email protected]1fd5302c2011-05-28 04:06:4353#endif
[email protected]b80f68432011-05-02 17:22:3054
[email protected]c5dbef02011-05-13 05:06:0955namespace {
56
57void InitRenderViewHostForExtensions(RenderViewHost* render_view_host) {
58 // Note that due to GetEffectiveURL(), even hosted apps will have a
59 // chrome-extension:// URL for their site, so we can ignore that wrinkle here.
60 SiteInstance* site_instance = render_view_host->site_instance();
61 const GURL& site = site_instance->site();
62 RenderProcessHost* process = render_view_host->process();
63
64 if (!site.SchemeIs(chrome::kExtensionScheme))
65 return;
66
67 Profile* profile = site_instance->browsing_instance()->profile();
68 ExtensionService* service = profile->GetExtensionService();
69 if (!service)
70 return;
71
72 ExtensionProcessManager* process_manager =
73 profile->GetExtensionProcessManager();
74 CHECK(process_manager);
75
76 // This can happen if somebody typos a chrome-extension:// URL.
77 const Extension* extension = service->GetExtensionByURL(site);
78 if (!extension)
79 return;
80
81 site_instance->GetProcess()->mark_is_extension_process();
82
83 // Register the association between extension and process with
84 // ExtensionProcessManager.
85 process_manager->RegisterExtensionProcess(extension->id(), process->id());
86
87 // Record which, if any, installed app is associated with this process.
88 // TODO(aa): Totally lame to store this state in a global map in extension
89 // service. Can we get it from EPM instead?
90 if (extension->is_app())
91 service->SetInstalledAppForRenderer(process->id(), extension);
92
93 // Some extensions use chrome:// URLs.
94 Extension::Type type = extension->GetType();
95 if (type == Extension::TYPE_EXTENSION ||
96 type == Extension::TYPE_PACKAGED_APP) {
97 ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
98 process->id(), chrome::kChromeUIScheme);
99 }
100
101 // Enable extension bindings for the renderer. Currently only extensions,
102 // packaged apps, and hosted component apps use extension bindings.
103 if (type == Extension::TYPE_EXTENSION ||
[email protected]2333bf22011-05-19 02:16:51104 type == Extension::TYPE_USER_SCRIPT ||
[email protected]c5dbef02011-05-13 05:06:09105 type == Extension::TYPE_PACKAGED_APP ||
106 (type == Extension::TYPE_HOSTED_APP &&
107 extension->location() == Extension::COMPONENT)) {
108 render_view_host->Send(new ExtensionMsg_ActivateExtension(extension->id()));
109 render_view_host->AllowBindings(BindingsPolicy::EXTENSION);
110 }
111}
112
113}
114
[email protected]d977f9c2011-03-14 16:10:26115namespace chrome {
116
[email protected]f364d1392011-04-08 21:03:10117void ChromeContentBrowserClient::RenderViewHostCreated(
118 RenderViewHost* render_view_host) {
[email protected]53a0afa2011-04-28 02:09:33119 new ChromeRenderViewHostObserver(render_view_host);
[email protected]f364d1392011-04-08 21:03:10120 new DesktopNotificationHandler(render_view_host);
121 new DevToolsHandler(render_view_host);
122 new ExtensionMessageHandler(render_view_host);
[email protected]f364d1392011-04-08 21:03:10123
[email protected]c5dbef02011-05-13 05:06:09124 InitRenderViewHostForExtensions(render_view_host);
[email protected]d977f9c2011-03-14 16:10:26125}
126
[email protected]05fcf982011-04-19 00:44:14127void ChromeContentBrowserClient::BrowserRenderProcessHostCreated(
128 BrowserRenderProcessHost* host) {
[email protected]c47cfd62011-04-29 21:27:02129 int id = host->id();
130 Profile* profile = host->profile();
[email protected]05fcf982011-04-19 00:44:14131 host->channel()->AddFilter(new ChromeRenderMessageFilter(
[email protected]c47cfd62011-04-29 21:27:02132 id, profile, profile->GetRequestContextForRenderProcess(id)));
[email protected]05fcf982011-04-19 00:44:14133 host->channel()->AddFilter(new PrintingMessageFilter());
134 host->channel()->AddFilter(
[email protected]c47cfd62011-04-29 21:27:02135 new SearchProviderInstallStateMessageFilter(id, profile));
136 host->channel()->AddFilter(new SpellCheckMessageFilter(id));
[email protected]d4cff272011-05-02 15:46:01137#if defined(OS_MACOSX)
138 host->channel()->AddFilter(new TextInputClientMessageFilter(host->id()));
139#endif
[email protected]3e69bc82011-05-26 23:22:38140
141 host->Send(new ViewMsg_SetIsIncognitoProcess(profile->IsOffTheRecord()));
[email protected]05fcf982011-04-19 00:44:14142}
143
[email protected]97e6c4c2011-05-18 16:08:51144void ChromeContentBrowserClient::PluginProcessHostCreated(
145 PluginProcessHost* host) {
146 host->AddFilter(new ChromePluginMessageFilter(host));
147}
148
[email protected]5327dfb2011-05-03 17:50:36149void ChromeContentBrowserClient::WorkerProcessHostCreated(
150 WorkerProcessHost* host) {
151 host->AddFilter(new ChromeWorkerMessageFilter(host));
152}
153
[email protected]1fd1a502011-03-30 16:55:56154content::WebUIFactory* ChromeContentBrowserClient::GetWebUIFactory() {
155 return ChromeWebUIFactory::GetInstance();
156}
157
[email protected]36fb2c7c2011-04-04 15:49:08158GURL ChromeContentBrowserClient::GetEffectiveURL(Profile* profile,
159 const GURL& url) {
160 // Get the effective URL for the given actual URL. If the URL is part of an
161 // installed app, the effective URL is an extension URL with the ID of that
162 // extension as the host. This has the effect of grouping apps together in
163 // a common SiteInstance.
164 if (!profile || !profile->GetExtensionService())
165 return url;
166
167 const Extension* extension =
168 profile->GetExtensionService()->GetExtensionByWebExtent(url);
169 if (!extension)
170 return url;
171
172 // If the URL is part of an extension's web extent, convert it to an
173 // extension URL.
174 return extension->GetResourceURL(url.path());
175}
176
[email protected]0f012df82011-05-19 14:15:29177bool ChromeContentBrowserClient::IsURLSameAsAnySiteInstance(const GURL& url) {
178 return url.spec() == chrome::kAboutKillURL ||
179 url.spec() == chrome::kAboutHangURL ||
180 url.spec() == chrome::kAboutShorthangURL;
181}
182
[email protected]763ec4ca2011-04-29 15:48:12183std::string ChromeContentBrowserClient::GetCanonicalEncodingNameByAliasName(
184 const std::string& alias_name) {
185 return CharacterEncoding::GetCanonicalEncodingNameByAliasName(alias_name);
186}
187
[email protected]b80f68432011-05-02 17:22:30188void ChromeContentBrowserClient::AppendExtraCommandLineSwitches(
189 CommandLine* command_line, int child_process_id) {
190#if defined(USE_LINUX_BREAKPAD)
191 if (IsCrashReporterEnabled()) {
192 command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
193 child_process_logging::GetClientId() + "," + base::GetLinuxDistro());
194 }
195#elif defined(OS_MACOSX)
196 if (IsCrashReporterEnabled()) {
197 command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
198 child_process_logging::GetClientId());
199 }
200#endif // OS_MACOSX
201
202 std::string process_type =
203 command_line->GetSwitchValueASCII(switches::kProcessType);
204 if (process_type == switches::kExtensionProcess ||
205 process_type == switches::kRendererProcess) {
206 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
207 FilePath user_data_dir =
208 browser_command_line.GetSwitchValuePath(switches::kUserDataDir);
209 if (!user_data_dir.empty())
210 command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir);
211#if defined(OS_CHROMEOS)
212 const std::string& login_profile =
213 browser_command_line.GetSwitchValueASCII(switches::kLoginProfile);
214 if (!login_profile.empty())
215 command_line->AppendSwitchASCII(switches::kLoginProfile, login_profile);
216#endif
217
218 RenderProcessHost* process = RenderProcessHost::FromID(child_process_id);
219
220 PrefService* prefs = process->profile()->GetPrefs();
221 // Currently this pref is only registered if applied via a policy.
222 if (prefs->HasPrefPath(prefs::kDisable3DAPIs) &&
223 prefs->GetBoolean(prefs::kDisable3DAPIs)) {
224 // Turn this policy into a command line switch.
225 command_line->AppendSwitch(switches::kDisable3DAPIs);
226 }
227
228 // Disable client-side phishing detection in the renderer if it is disabled
229 // in the browser process.
230 if (!g_browser_process->safe_browsing_detection_service())
231 command_line->AppendSwitch(switches::kDisableClientSidePhishingDetection);
232 }
233}
234
235std::string ChromeContentBrowserClient::GetApplicationLocale() {
236 return g_browser_process->GetApplicationLocale();
237}
238
[email protected]b5cca982011-05-26 04:42:08239std::string ChromeContentBrowserClient::GetAcceptLangs(const TabContents* tab) {
240 return tab->profile()->GetPrefs()->GetString(prefs::kAcceptLanguages);
241}
242
[email protected]a2176792011-05-08 19:30:49243bool ChromeContentBrowserClient::AllowAppCache(
[email protected]5b52ad42011-05-26 14:26:09244 const GURL& manifest_url,
245 const content::ResourceContext& context) {
[email protected]8093a542011-05-13 07:29:32246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
247 ProfileIOData* io_data =
248 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09249 // FIXME(jochen): get the correct top-level origin.
[email protected]efa55212011-05-13 16:19:38250 ContentSetting setting = io_data->GetHostContentSettingsMap()->
[email protected]5b52ad42011-05-26 14:26:09251 GetCookieContentSetting(manifest_url, manifest_url, true);
[email protected]a2176792011-05-08 19:30:49252 DCHECK(setting != CONTENT_SETTING_DEFAULT);
253 return setting != CONTENT_SETTING_BLOCK;
254}
255
[email protected]ed24fad2011-05-10 22:44:01256bool ChromeContentBrowserClient::AllowGetCookie(
257 const GURL& url,
258 const GURL& first_party,
259 const net::CookieList& cookie_list,
260 const content::ResourceContext& context,
261 int render_process_id,
262 int render_view_id) {
263 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]8093a542011-05-13 07:29:32264 ProfileIOData* io_data =
265 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09266 ContentSetting setting = io_data->GetHostContentSettingsMap()->
267 GetCookieContentSetting(url, first_party, false);
268 bool allow = setting == CONTENT_SETTING_ALLOW ||
269 setting == CONTENT_SETTING_SESSION_ONLY;
[email protected]ed24fad2011-05-10 22:44:01270
[email protected]8093a542011-05-13 07:29:32271 BrowserThread::PostTask(
272 BrowserThread::UI, FROM_HERE,
273 NewRunnableFunction(
274 &TabSpecificContentSettings::CookiesRead,
275 render_process_id, render_view_id, url, cookie_list, !allow));
[email protected]ed24fad2011-05-10 22:44:01276 return allow;
277}
278
279bool ChromeContentBrowserClient::AllowSetCookie(
280 const GURL& url,
281 const GURL& first_party,
282 const std::string& cookie_line,
283 const content::ResourceContext& context,
284 int render_process_id,
285 int render_view_id,
286 net::CookieOptions* options) {
287 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]8093a542011-05-13 07:29:32288 ProfileIOData* io_data =
289 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09290 ContentSetting setting = io_data->GetHostContentSettingsMap()->
291 GetCookieContentSetting(url, first_party, true);
[email protected]ed24fad2011-05-10 22:44:01292
[email protected]5b52ad42011-05-26 14:26:09293 if (setting == CONTENT_SETTING_SESSION_ONLY)
294 options->set_force_session();
[email protected]ed24fad2011-05-10 22:44:01295
[email protected]5b52ad42011-05-26 14:26:09296 bool allow = setting == CONTENT_SETTING_ALLOW ||
297 setting == CONTENT_SETTING_SESSION_ONLY;
[email protected]ed24fad2011-05-10 22:44:01298
[email protected]8093a542011-05-13 07:29:32299 BrowserThread::PostTask(
300 BrowserThread::UI, FROM_HERE,
301 NewRunnableFunction(
302 &TabSpecificContentSettings::CookieChanged,
303 render_process_id, render_view_id, url, cookie_line, *options,
304 !allow));
[email protected]ed24fad2011-05-10 22:44:01305 return allow;
306}
307
[email protected]317f96c92011-05-31 06:53:41308QuotaPermissionContext*
309ChromeContentBrowserClient::CreateQuotaPermissionContext() {
310 return new ChromeQuotaPermissionContext();
311}
312
[email protected]b80f68432011-05-02 17:22:30313#if defined(OS_LINUX)
314int ChromeContentBrowserClient::GetCrashSignalFD(
315 const std::string& process_type) {
316 if (process_type == switches::kRendererProcess)
317 return RendererCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
318
319 if (process_type == switches::kPluginProcess)
320 return PluginCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
321
322 if (process_type == switches::kPpapiPluginProcess)
323 return PpapiCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
324
325 if (process_type == switches::kGpuProcess)
326 return GpuCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
327
328 return -1;
329}
330#endif
331
[email protected]d977f9c2011-03-14 16:10:26332} // namespace chrome