blob: a47c0072de077e0bd7903d8af09247dbd804c94b [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"
[email protected]b8148ac2011-07-13 22:03:259#include "chrome/browser/browser_about_handler.h"
[email protected]b80f68432011-05-02 17:22:3010#include "chrome/browser/browser_process.h"
[email protected]3b8f7e32011-07-13 11:52:2311#include "chrome/browser/browsing_data_remover.h"
[email protected]763ec4ca2011-04-29 15:48:1212#include "chrome/browser/character_encoding.h"
[email protected]97e6c4c2011-05-18 16:08:5113#include "chrome/browser/chrome_plugin_message_filter.h"
[email protected]317f96c92011-05-31 06:53:4114#include "chrome/browser/chrome_quota_permission_context.h"
[email protected]5327dfb2011-05-03 17:50:3615#include "chrome/browser/chrome_worker_message_filter.h"
[email protected]a2176792011-05-08 19:30:4916#include "chrome/browser/content_settings/host_content_settings_map.h"
[email protected]8093a542011-05-13 07:29:3217#include "chrome/browser/content_settings/tab_specific_content_settings.h"
[email protected]0ffaa482011-07-14 23:41:2818#include "chrome/browser/download/save_package_file_picker.h"
[email protected]941623e2011-06-07 23:06:0419#include "chrome/browser/extensions/extension_info_map.h"
[email protected]f364d1392011-04-08 21:03:1020#include "chrome/browser/extensions/extension_message_handler.h"
[email protected]d977f9c2011-03-14 16:10:2621#include "chrome/browser/extensions/extension_service.h"
[email protected]b8148ac2011-07-13 22:03:2522#include "chrome/browser/extensions/extension_web_ui.h"
[email protected]763ec4ca2011-04-29 15:48:1223#include "chrome/browser/google/google_util.h"
[email protected]ae6e9912011-07-27 01:18:2824#include "chrome/browser/net/chrome_net_log.h"
[email protected]941623e2011-06-07 23:06:0425#include "chrome/browser/notifications/desktop_notification_service.h"
26#include "chrome/browser/notifications/desktop_notification_service_factory.h"
[email protected]0609b17f2011-05-31 20:13:4227#include "chrome/browser/platform_util.h"
[email protected]d90965842011-07-26 22:50:5028#include "chrome/browser/prefs/pref_member.h"
[email protected]763ec4ca2011-04-29 15:48:1229#include "chrome/browser/prefs/pref_service.h"
[email protected]f9034cf2011-07-21 12:43:4130#include "chrome/browser/prerender/prerender_manager.h"
31#include "chrome/browser/prerender/prerender_tracker.h"
[email protected]05fcf982011-04-19 00:44:1432#include "chrome/browser/printing/printing_message_filter.h"
33#include "chrome/browser/profiles/profile.h"
[email protected]8093a542011-05-13 07:29:3234#include "chrome/browser/profiles/profile_io_data.h"
[email protected]05fcf982011-04-19 00:44:1435#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
[email protected]53a0afa2011-04-28 02:09:3336#include "chrome/browser/renderer_host/chrome_render_view_host_observer.h"
[email protected]d4cff272011-05-02 15:46:0137#include "chrome/browser/renderer_host/text_input_client_message_filter.h"
[email protected]05fcf982011-04-19 00:44:1438#include "chrome/browser/search_engines/search_provider_install_state_message_filter.h"
39#include "chrome/browser/spellcheck_message_filter.h"
[email protected]8ec26472011-06-06 16:52:4540#include "chrome/browser/ssl/ssl_add_cert_handler.h"
[email protected]848dd042011-06-04 18:24:0341#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]181a95ee2011-07-12 19:26:3642#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
[email protected]8ec26472011-06-06 16:52:4543#include "chrome/browser/tab_contents/tab_contents_ssl_helper.h"
44#include "chrome/browser/tab_contents/tab_util.h"
45#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]1fd1a502011-03-30 16:55:5646#include "chrome/browser/ui/webui/chrome_web_ui_factory.h"
[email protected]b80f68432011-05-02 17:22:3047#include "chrome/common/child_process_logging.h"
48#include "chrome/common/chrome_switches.h"
[email protected]941623e2011-06-07 23:06:0449#include "chrome/common/extensions/extension.h"
[email protected]c5dbef02011-05-13 05:06:0950#include "chrome/common/extensions/extension_messages.h"
[email protected]f1933792011-06-14 00:49:3451#include "chrome/common/logging_chrome.h"
[email protected]763ec4ca2011-04-29 15:48:1252#include "chrome/common/pref_names.h"
[email protected]3e69bc82011-05-26 23:22:3853#include "chrome/common/render_messages.h"
[email protected]c5dbef02011-05-13 05:06:0954#include "chrome/common/url_constants.h"
[email protected]b8148ac2011-07-13 22:03:2555#include "content/browser/browser_url_handler.h"
[email protected]c5dbef02011-05-13 05:06:0956#include "content/browser/browsing_instance.h"
57#include "content/browser/child_process_security_policy.h"
[email protected]b46442d7e2011-06-29 02:16:0658#include "content/browser/debugger/devtools_handler.h"
[email protected]97e6c4c2011-05-18 16:08:5159#include "content/browser/plugin_process_host.h"
[email protected]05fcf982011-04-19 00:44:1460#include "content/browser/renderer_host/browser_render_process_host.h"
[email protected]d977f9c2011-03-14 16:10:2661#include "content/browser/renderer_host/render_view_host.h"
[email protected]a2176792011-05-08 19:30:4962#include "content/browser/resource_context.h"
[email protected]c5dbef02011-05-13 05:06:0963#include "content/browser/site_instance.h"
[email protected]f9034cf2011-07-21 12:43:4164#include "content/browser/ssl/ssl_cert_error_handler.h"
[email protected]8ec26472011-06-06 16:52:4565#include "content/browser/ssl/ssl_client_auth_handler.h"
[email protected]763ec4ca2011-04-29 15:48:1266#include "content/browser/tab_contents/tab_contents.h"
[email protected]5327dfb2011-05-03 17:50:3667#include "content/browser/worker_host/worker_process_host.h"
[email protected]c5dbef02011-05-13 05:06:0968#include "content/common/bindings_policy.h"
[email protected]941623e2011-06-07 23:06:0469#include "content/common/desktop_notification_messages.h"
[email protected]29b25d092011-06-29 20:57:3470#include "grit/ui_resources.h"
[email protected]ed24fad2011-05-10 22:44:0171#include "net/base/cookie_monster.h"
72#include "net/base/cookie_options.h"
[email protected]ac55e292011-06-24 05:16:0873#include "ui/base/resource/resource_bundle.h"
[email protected]d977f9c2011-03-14 16:10:2674
[email protected]b80f68432011-05-02 17:22:3075#if defined(OS_LINUX)
76#include "base/linux_util.h"
77#include "chrome/browser/crash_handler_host_linux.h"
[email protected]1fd5302c2011-05-28 04:06:4378#endif
[email protected]b80f68432011-05-02 17:22:3079
[email protected]37a72af2011-06-13 05:42:0180#if defined(USE_NSS)
81#include "chrome/browser/ui/crypto_module_password_dialog.h"
82#endif
83
[email protected]c5dbef02011-05-13 05:06:0984namespace {
85
86void InitRenderViewHostForExtensions(RenderViewHost* render_view_host) {
87 // Note that due to GetEffectiveURL(), even hosted apps will have a
88 // chrome-extension:// URL for their site, so we can ignore that wrinkle here.
89 SiteInstance* site_instance = render_view_host->site_instance();
90 const GURL& site = site_instance->site();
[email protected]c5dbef02011-05-13 05:06:0991
92 if (!site.SchemeIs(chrome::kExtensionScheme))
93 return;
94
[email protected]3d7474ff2011-07-27 17:47:3795 Profile* profile = Profile::FromBrowserContext(
96 site_instance->browsing_instance()->browser_context());
[email protected]c5dbef02011-05-13 05:06:0997 ExtensionService* service = profile->GetExtensionService();
98 if (!service)
99 return;
100
101 ExtensionProcessManager* process_manager =
102 profile->GetExtensionProcessManager();
103 CHECK(process_manager);
104
105 // This can happen if somebody typos a chrome-extension:// URL.
106 const Extension* extension = service->GetExtensionByURL(site);
107 if (!extension)
108 return;
109
110 site_instance->GetProcess()->mark_is_extension_process();
111
[email protected]056ad2a2011-07-12 02:13:55112 // Register the association between extension and SiteInstance with
[email protected]c5dbef02011-05-13 05:06:09113 // ExtensionProcessManager.
[email protected]056ad2a2011-07-12 02:13:55114 // TODO(creis): Use this to replace SetInstalledAppForRenderer below.
115 process_manager->RegisterExtensionSiteInstance(site_instance->id(),
116 extension->id());
[email protected]c5dbef02011-05-13 05:06:09117
[email protected]1ab4ddf2011-07-21 04:48:04118 RenderProcessHost* process = render_view_host->process();
119
[email protected]80675fc2011-06-21 02:05:49120 if (extension->is_app()) {
121 render_view_host->Send(
122 new ExtensionMsg_ActivateApplication(extension->id()));
123 // Record which, if any, installed app is associated with this process.
124 // TODO(aa): Totally lame to store this state in a global map in extension
125 // service. Can we get it from EPM instead?
[email protected]c5dbef02011-05-13 05:06:09126 service->SetInstalledAppForRenderer(process->id(), extension);
[email protected]80675fc2011-06-21 02:05:49127 }
[email protected]c5dbef02011-05-13 05:06:09128
129 // Some extensions use chrome:// URLs.
130 Extension::Type type = extension->GetType();
131 if (type == Extension::TYPE_EXTENSION ||
132 type == Extension::TYPE_PACKAGED_APP) {
133 ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
134 process->id(), chrome::kChromeUIScheme);
135 }
136
137 // Enable extension bindings for the renderer. Currently only extensions,
138 // packaged apps, and hosted component apps use extension bindings.
139 if (type == Extension::TYPE_EXTENSION ||
[email protected]2333bf22011-05-19 02:16:51140 type == Extension::TYPE_USER_SCRIPT ||
[email protected]c5dbef02011-05-13 05:06:09141 type == Extension::TYPE_PACKAGED_APP ||
142 (type == Extension::TYPE_HOSTED_APP &&
143 extension->location() == Extension::COMPONENT)) {
144 render_view_host->Send(new ExtensionMsg_ActivateExtension(extension->id()));
145 render_view_host->AllowBindings(BindingsPolicy::EXTENSION);
146 }
147}
148
[email protected]b8148ac2011-07-13 22:03:25149// Handles rewriting Web UI URLs.
[email protected]3d7474ff2011-07-27 17:47:37150static bool HandleWebUI(GURL* url, content::BrowserContext* browser_context) {
151 if (!ChromeWebUIFactory::GetInstance()->UseWebUIForURL(browser_context, *url))
[email protected]b8148ac2011-07-13 22:03:25152 return false;
153
154 // Special case the new tab page. In older versions of Chrome, the new tab
155 // page was hosted at chrome-internal:<blah>. This might be in people's saved
156 // sessions or bookmarks, so we say any URL with that scheme triggers the new
157 // tab page.
158 if (url->SchemeIs(chrome::kChromeInternalScheme)) {
159 // Rewrite it with the proper new tab URL.
160 *url = GURL(chrome::kChromeUINewTabURL);
161 }
162
163 return true;
164}
165
[email protected]9dbfff12011-07-01 19:37:07166} // namespace
[email protected]c5dbef02011-05-13 05:06:09167
[email protected]d977f9c2011-03-14 16:10:26168namespace chrome {
169
[email protected]f364d1392011-04-08 21:03:10170void ChromeContentBrowserClient::RenderViewHostCreated(
171 RenderViewHost* render_view_host) {
[email protected]53a0afa2011-04-28 02:09:33172 new ChromeRenderViewHostObserver(render_view_host);
[email protected]f364d1392011-04-08 21:03:10173 new DevToolsHandler(render_view_host);
174 new ExtensionMessageHandler(render_view_host);
[email protected]f364d1392011-04-08 21:03:10175
[email protected]c5dbef02011-05-13 05:06:09176 InitRenderViewHostForExtensions(render_view_host);
[email protected]d977f9c2011-03-14 16:10:26177}
178
[email protected]05fcf982011-04-19 00:44:14179void ChromeContentBrowserClient::BrowserRenderProcessHostCreated(
180 BrowserRenderProcessHost* host) {
[email protected]c47cfd62011-04-29 21:27:02181 int id = host->id();
[email protected]3d7474ff2011-07-27 17:47:37182 Profile* profile = Profile::FromBrowserContext(host->browser_context());
[email protected]05fcf982011-04-19 00:44:14183 host->channel()->AddFilter(new ChromeRenderMessageFilter(
[email protected]c47cfd62011-04-29 21:27:02184 id, profile, profile->GetRequestContextForRenderProcess(id)));
[email protected]05fcf982011-04-19 00:44:14185 host->channel()->AddFilter(new PrintingMessageFilter());
186 host->channel()->AddFilter(
[email protected]c47cfd62011-04-29 21:27:02187 new SearchProviderInstallStateMessageFilter(id, profile));
188 host->channel()->AddFilter(new SpellCheckMessageFilter(id));
[email protected]d4cff272011-05-02 15:46:01189#if defined(OS_MACOSX)
190 host->channel()->AddFilter(new TextInputClientMessageFilter(host->id()));
191#endif
[email protected]3e69bc82011-05-26 23:22:38192
193 host->Send(new ViewMsg_SetIsIncognitoProcess(profile->IsOffTheRecord()));
[email protected]05fcf982011-04-19 00:44:14194}
195
[email protected]97e6c4c2011-05-18 16:08:51196void ChromeContentBrowserClient::PluginProcessHostCreated(
197 PluginProcessHost* host) {
198 host->AddFilter(new ChromePluginMessageFilter(host));
199}
200
[email protected]5327dfb2011-05-03 17:50:36201void ChromeContentBrowserClient::WorkerProcessHostCreated(
202 WorkerProcessHost* host) {
203 host->AddFilter(new ChromeWorkerMessageFilter(host));
204}
205
[email protected]1fd1a502011-03-30 16:55:56206content::WebUIFactory* ChromeContentBrowserClient::GetWebUIFactory() {
207 return ChromeWebUIFactory::GetInstance();
208}
209
[email protected]3d7474ff2011-07-27 17:47:37210GURL ChromeContentBrowserClient::GetEffectiveURL(
211 content::BrowserContext* browser_context, const GURL& url) {
212 Profile* profile = Profile::FromBrowserContext(browser_context);
[email protected]36fb2c7c2011-04-04 15:49:08213 // Get the effective URL for the given actual URL. If the URL is part of an
214 // installed app, the effective URL is an extension URL with the ID of that
215 // extension as the host. This has the effect of grouping apps together in
216 // a common SiteInstance.
217 if (!profile || !profile->GetExtensionService())
218 return url;
219
220 const Extension* extension =
221 profile->GetExtensionService()->GetExtensionByWebExtent(url);
222 if (!extension)
223 return url;
224
225 // If the URL is part of an extension's web extent, convert it to an
226 // extension URL.
227 return extension->GetResourceURL(url.path());
228}
229
[email protected]056ad2a2011-07-12 02:13:55230bool ChromeContentBrowserClient::ShouldUseProcessPerSite(
[email protected]3d7474ff2011-07-27 17:47:37231 content::BrowserContext* browser_context, const GURL& effective_url) {
[email protected]056ad2a2011-07-12 02:13:55232 // Non-extension URLs should generally use process-per-site-instance.
233 // Because we expect to use the effective URL, hosted apps URLs should have
234 // an extension scheme by now.
235 if (!effective_url.SchemeIs(chrome::kExtensionScheme))
236 return false;
237
[email protected]3d7474ff2011-07-27 17:47:37238 Profile* profile = Profile::FromBrowserContext(browser_context);
[email protected]056ad2a2011-07-12 02:13:55239 if (!profile || !profile->GetExtensionService())
240 return false;
241
242 const Extension* extension =
243 profile->GetExtensionService()->GetExtensionByURL(effective_url);
244 if (!extension)
245 return false;
246
247 // If the URL is part of a hosted app that does not have the background
248 // permission, we want to give each instance its own process to improve
249 // responsiveness.
250 if (extension->GetType() == Extension::TYPE_HOSTED_APP &&
251 !extension->HasAPIPermission(ExtensionAPIPermission::kBackground))
252 return false;
253
254 // Hosted apps that have the background permission must use process per site,
255 // since all instances can make synchronous calls to the background window.
256 // Other extensions should use process per site as well.
257 return true;
258}
259
[email protected]0f012df82011-05-19 14:15:29260bool ChromeContentBrowserClient::IsURLSameAsAnySiteInstance(const GURL& url) {
[email protected]89f550b2011-06-08 18:34:03261 return url == GURL(chrome::kChromeUICrashURL) ||
262 url == GURL(chrome::kChromeUIKillURL) ||
263 url == GURL(chrome::kChromeUIHangURL) ||
264 url == GURL(chrome::kChromeUIShorthangURL);
[email protected]0f012df82011-05-19 14:15:29265}
266
[email protected]763ec4ca2011-04-29 15:48:12267std::string ChromeContentBrowserClient::GetCanonicalEncodingNameByAliasName(
268 const std::string& alias_name) {
269 return CharacterEncoding::GetCanonicalEncodingNameByAliasName(alias_name);
270}
271
[email protected]b80f68432011-05-02 17:22:30272void ChromeContentBrowserClient::AppendExtraCommandLineSwitches(
273 CommandLine* command_line, int child_process_id) {
274#if defined(USE_LINUX_BREAKPAD)
275 if (IsCrashReporterEnabled()) {
276 command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
277 child_process_logging::GetClientId() + "," + base::GetLinuxDistro());
278 }
279#elif defined(OS_MACOSX)
280 if (IsCrashReporterEnabled()) {
281 command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
282 child_process_logging::GetClientId());
283 }
284#endif // OS_MACOSX
285
[email protected]f1933792011-06-14 00:49:34286 if (logging::DialogsAreSuppressed())
287 command_line->AppendSwitch(switches::kNoErrorDialogs);
288
[email protected]b80f68432011-05-02 17:22:30289 std::string process_type =
290 command_line->GetSwitchValueASCII(switches::kProcessType);
[email protected]3cb054e62011-06-13 05:21:17291 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
[email protected]b80f68432011-05-02 17:22:30292 if (process_type == switches::kExtensionProcess ||
293 process_type == switches::kRendererProcess) {
[email protected]b80f68432011-05-02 17:22:30294 FilePath user_data_dir =
295 browser_command_line.GetSwitchValuePath(switches::kUserDataDir);
296 if (!user_data_dir.empty())
297 command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir);
298#if defined(OS_CHROMEOS)
299 const std::string& login_profile =
300 browser_command_line.GetSwitchValueASCII(switches::kLoginProfile);
301 if (!login_profile.empty())
302 command_line->AppendSwitchASCII(switches::kLoginProfile, login_profile);
303#endif
304
305 RenderProcessHost* process = RenderProcessHost::FromID(child_process_id);
306
[email protected]3d7474ff2011-07-27 17:47:37307 Profile* profile = Profile::FromBrowserContext(process->browser_context());
308 PrefService* prefs = profile->GetPrefs();
[email protected]b80f68432011-05-02 17:22:30309 // Currently this pref is only registered if applied via a policy.
310 if (prefs->HasPrefPath(prefs::kDisable3DAPIs) &&
311 prefs->GetBoolean(prefs::kDisable3DAPIs)) {
312 // Turn this policy into a command line switch.
313 command_line->AppendSwitch(switches::kDisable3DAPIs);
314 }
315
316 // Disable client-side phishing detection in the renderer if it is disabled
[email protected]8c40da62011-07-13 22:58:46317 // in the Profile preferences or the browser process.
318 if (!prefs->GetBoolean(prefs::kSafeBrowsingEnabled) ||
319 !g_browser_process->safe_browsing_detection_service()) {
[email protected]b80f68432011-05-02 17:22:30320 command_line->AppendSwitch(switches::kDisableClientSidePhishingDetection);
[email protected]8c40da62011-07-13 22:58:46321 }
[email protected]4287a3d2011-06-13 23:56:51322
323 static const char* const kSwitchNames[] = {
324 switches::kAllowHTTPBackgroundPage,
325 switches::kAllowScriptingGallery,
326 switches::kAppsCheckoutURL,
327 switches::kAppsGalleryURL,
[email protected]be9d9c82011-07-13 04:17:31328 switches::kCloudPrintServiceURL,
[email protected]4287a3d2011-06-13 23:56:51329 switches::kDebugPrint,
[email protected]6490abc2011-07-22 15:11:08330#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS)
[email protected]4287a3d2011-06-13 23:56:51331 // Enabled by default in Google Chrome builds, except on CrOS.
332 switches::kDisablePrintPreview,
333#else
334 // Disabled by default in Chromium builds and on CrOS.
335 switches::kEnablePrintPreview,
336#endif
337 switches::kDomAutomationController,
338 switches::kDumpHistogramsOnExit,
339 switches::kEnableClickToPlay,
340 switches::kEnableCrxlessWebApps,
341 switches::kEnableExperimentalExtensionApis,
342 switches::kEnableInBrowserThumbnailing,
343 switches::kEnableIPCFuzzing,
344 switches::kEnableNaCl,
345 switches::kEnableRemoting,
346 switches::kEnableResourceContentSettings,
347 switches::kEnableSearchProviderApiV2,
348 switches::kEnableWatchdog,
349 switches::kExperimentalSpellcheckerFeatures,
350 switches::kMemoryProfiling,
351 switches::kMessageLoopHistogrammer,
352 switches::kPpapiFlashArgs,
353 switches::kPpapiFlashInProcess,
354 switches::kPpapiFlashPath,
355 switches::kPpapiFlashVersion,
356 switches::kProfilingAtStart,
357 switches::kProfilingFile,
358 switches::kProfilingFlush,
[email protected]4287a3d2011-06-13 23:56:51359 switches::kSilentDumpOnDCHECK,
360 };
361
362 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
363 arraysize(kSwitchNames));
[email protected]3cb054e62011-06-13 05:21:17364 } else if (process_type == switches::kUtilityProcess) {
365 if (browser_command_line.HasSwitch(
366 switches::kEnableExperimentalExtensionApis)) {
367 command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
368 }
[email protected]4287a3d2011-06-13 23:56:51369 } else if (process_type == switches::kPluginProcess) {
370 static const char* const kSwitchNames[] = {
371 #if defined(OS_CHROMEOS)
372 switches::kLoginProfile,
373 #endif
374 switches::kMemoryProfiling,
375 switches::kSilentDumpOnDCHECK,
376 switches::kUserDataDir,
377 };
378
379 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
380 arraysize(kSwitchNames));
381 } else if (process_type == switches::kZygoteProcess) {
382 static const char* const kSwitchNames[] = {
383 switches::kEnableRemoting,
384 switches::kUserDataDir, // Make logs go to the right file.
385 // Load (in-process) Pepper plugins in-process in the zygote pre-sandbox.
386 switches::kPpapiFlashInProcess,
387 switches::kPpapiFlashPath,
388 switches::kPpapiFlashVersion,
389 };
390
391 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
392 arraysize(kSwitchNames));
[email protected]b80f68432011-05-02 17:22:30393 }
394}
395
396std::string ChromeContentBrowserClient::GetApplicationLocale() {
397 return g_browser_process->GetApplicationLocale();
398}
399
[email protected]b5cca982011-05-26 04:42:08400std::string ChromeContentBrowserClient::GetAcceptLangs(const TabContents* tab) {
[email protected]3d7474ff2011-07-27 17:47:37401 Profile* profile = Profile::FromBrowserContext(tab->browser_context());
402 return profile->GetPrefs()->GetString(prefs::kAcceptLanguages);
[email protected]b5cca982011-05-26 04:42:08403}
404
[email protected]ac55e292011-06-24 05:16:08405SkBitmap* ChromeContentBrowserClient::GetDefaultFavicon() {
406 ResourceBundle &rb = ResourceBundle::GetSharedInstance();
407 return rb.GetBitmapNamed(IDR_DEFAULT_FAVICON);
408}
409
[email protected]a2176792011-05-08 19:30:49410bool ChromeContentBrowserClient::AllowAppCache(
[email protected]5b52ad42011-05-26 14:26:09411 const GURL& manifest_url,
412 const content::ResourceContext& context) {
[email protected]8093a542011-05-13 07:29:32413 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
414 ProfileIOData* io_data =
415 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09416 // FIXME(jochen): get the correct top-level origin.
[email protected]efa55212011-05-13 16:19:38417 ContentSetting setting = io_data->GetHostContentSettingsMap()->
[email protected]5b52ad42011-05-26 14:26:09418 GetCookieContentSetting(manifest_url, manifest_url, true);
[email protected]a2176792011-05-08 19:30:49419 DCHECK(setting != CONTENT_SETTING_DEFAULT);
420 return setting != CONTENT_SETTING_BLOCK;
421}
422
[email protected]ed24fad2011-05-10 22:44:01423bool ChromeContentBrowserClient::AllowGetCookie(
424 const GURL& url,
425 const GURL& first_party,
426 const net::CookieList& cookie_list,
427 const content::ResourceContext& context,
428 int render_process_id,
429 int render_view_id) {
430 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]8093a542011-05-13 07:29:32431 ProfileIOData* io_data =
432 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09433 ContentSetting setting = io_data->GetHostContentSettingsMap()->
434 GetCookieContentSetting(url, first_party, false);
435 bool allow = setting == CONTENT_SETTING_ALLOW ||
436 setting == CONTENT_SETTING_SESSION_ONLY;
[email protected]ed24fad2011-05-10 22:44:01437
[email protected]8093a542011-05-13 07:29:32438 BrowserThread::PostTask(
439 BrowserThread::UI, FROM_HERE,
440 NewRunnableFunction(
441 &TabSpecificContentSettings::CookiesRead,
442 render_process_id, render_view_id, url, cookie_list, !allow));
[email protected]ed24fad2011-05-10 22:44:01443 return allow;
444}
445
446bool ChromeContentBrowserClient::AllowSetCookie(
447 const GURL& url,
448 const GURL& first_party,
449 const std::string& cookie_line,
450 const content::ResourceContext& context,
451 int render_process_id,
452 int render_view_id,
453 net::CookieOptions* options) {
454 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]8093a542011-05-13 07:29:32455 ProfileIOData* io_data =
456 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09457 ContentSetting setting = io_data->GetHostContentSettingsMap()->
458 GetCookieContentSetting(url, first_party, true);
[email protected]ed24fad2011-05-10 22:44:01459
[email protected]5b52ad42011-05-26 14:26:09460 if (setting == CONTENT_SETTING_SESSION_ONLY)
461 options->set_force_session();
[email protected]ed24fad2011-05-10 22:44:01462
[email protected]5b52ad42011-05-26 14:26:09463 bool allow = setting == CONTENT_SETTING_ALLOW ||
464 setting == CONTENT_SETTING_SESSION_ONLY;
[email protected]ed24fad2011-05-10 22:44:01465
[email protected]8093a542011-05-13 07:29:32466 BrowserThread::PostTask(
467 BrowserThread::UI, FROM_HERE,
468 NewRunnableFunction(
469 &TabSpecificContentSettings::CookieChanged,
470 render_process_id, render_view_id, url, cookie_line, *options,
471 !allow));
[email protected]ed24fad2011-05-10 22:44:01472 return allow;
473}
474
[email protected]d5a19162011-06-30 18:51:54475bool ChromeContentBrowserClient::AllowSaveLocalState(
476 const content::ResourceContext& context) {
477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
478 ProfileIOData* io_data =
479 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
480 return !io_data->clear_local_state_on_exit()->GetValue();
481}
482
[email protected]6133f922011-07-01 21:34:34483net::URLRequestContext*
484ChromeContentBrowserClient::OverrideRequestContextForURL(
485 const GURL& url, const content::ResourceContext& context) {
486 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
487 if (url.SchemeIs(chrome::kExtensionScheme)) {
488 ProfileIOData* io_data =
489 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
490 return io_data->extensions_request_context();
491 }
492
493 return NULL;
494}
495
[email protected]317f96c92011-05-31 06:53:41496QuotaPermissionContext*
497ChromeContentBrowserClient::CreateQuotaPermissionContext() {
498 return new ChromeQuotaPermissionContext();
499}
500
[email protected]0609b17f2011-05-31 20:13:42501void ChromeContentBrowserClient::RevealFolderInOS(const FilePath& path) {
502 // On Mac, this call needs to be done on the UI thread. On other platforms,
503 // do it on the FILE thread so we don't slow down UI.
504#if defined(OS_MACOSX)
505 platform_util::OpenItem(path);
506#else
507 BrowserThread::PostTask(
508 BrowserThread::FILE, FROM_HERE,
509 NewRunnableFunction(&platform_util::OpenItem, path));
510#endif
511}
512
[email protected]848dd042011-06-04 18:24:03513void ChromeContentBrowserClient::AllowCertificateError(
514 SSLCertErrorHandler* handler,
515 bool overridable,
516 Callback2<SSLCertErrorHandler*, bool>::Type* callback) {
[email protected]f9034cf2011-07-21 12:43:41517 // If the tab is being prerendered, cancel the prerender and the request.
518 TabContents* tab = tab_util::GetTabContentsByID(
519 handler->render_process_host_id(),
520 handler->tab_contents_id());
521 if (!tab) {
522 NOTREACHED();
523 return;
524 }
525 prerender::PrerenderManager* prerender_manager =
526 tab->profile()->GetPrerenderManager();
527 if (prerender_manager && prerender_manager->IsTabContentsPrerendering(tab)) {
528 if (prerender_manager->prerender_tracker()->TryCancel(
529 handler->render_process_host_id(),
530 handler->tab_contents_id(),
531 prerender::FINAL_STATUS_SSL_ERROR)) {
532 handler->CancelRequest();
533 return;
534 }
535 }
536
537 // Otherwise, display an SSL blocking page.
[email protected]848dd042011-06-04 18:24:03538 SSLBlockingPage* blocking_page = new SSLBlockingPage(
539 handler, overridable, callback);
540 blocking_page->Show();
541}
542
[email protected]8ec26472011-06-06 16:52:45543void ChromeContentBrowserClient::ShowClientCertificateRequestDialog(
544 int render_process_id,
545 int render_view_id,
546 SSLClientAuthHandler* handler) {
547 TabContents* tab = tab_util::GetTabContentsByID(
548 render_process_id, render_view_id);
549 if (!tab) {
550 NOTREACHED();
551 return;
552 }
553
554 TabContentsWrapper* wrapper =
555 TabContentsWrapper::GetCurrentWrapperForContents(tab);
556 wrapper->ssl_helper()->ShowClientCertificateRequestDialog(handler);
557}
558
559void ChromeContentBrowserClient::AddNewCertificate(
560 net::URLRequest* request,
561 net::X509Certificate* cert,
562 int render_process_id,
563 int render_view_id) {
564 // The handler will run the UI and delete itself when it's finished.
565 new SSLAddCertHandler(request, cert, render_process_id, render_view_id);
566}
567
[email protected]941623e2011-06-07 23:06:04568void ChromeContentBrowserClient::RequestDesktopNotificationPermission(
569 const GURL& source_origin,
570 int callback_context,
571 int render_process_id,
572 int render_view_id) {
573 RenderViewHost* rvh = RenderViewHost::FromID(
574 render_process_id, render_view_id);
575 if (!rvh) {
576 NOTREACHED();
577 return;
578 }
579
580 RenderProcessHost* process = rvh->process();
[email protected]3d7474ff2011-07-27 17:47:37581 Profile* profile = Profile::FromBrowserContext(process->browser_context());
[email protected]941623e2011-06-07 23:06:04582 DesktopNotificationService* service =
[email protected]3d7474ff2011-07-27 17:47:37583 DesktopNotificationServiceFactory::GetForProfile(profile);
[email protected]941623e2011-06-07 23:06:04584 service->RequestPermission(
585 source_origin, render_process_id, render_view_id, callback_context,
586 tab_util::GetTabContentsByID(render_process_id, render_view_id));
587}
588
589WebKit::WebNotificationPresenter::Permission
590 ChromeContentBrowserClient::CheckDesktopNotificationPermission(
591 const GURL& source_url,
592 const content::ResourceContext& context) {
593 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
594 ProfileIOData* io_data =
595 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
596
597 const Extension* extension =
598 io_data->GetExtensionInfoMap()->extensions().GetByURL(source_url);
599 if (extension &&
[email protected]0d3e4a22011-06-23 19:02:52600 extension->HasAPIPermission(ExtensionAPIPermission::kNotification)) {
[email protected]941623e2011-06-07 23:06:04601 return WebKit::WebNotificationPresenter::PermissionAllowed;
602 }
603
604 // Fall back to the regular notification preferences, which works on an
605 // origin basis.
606 return io_data->GetNotificationService() ?
607 io_data->GetNotificationService()->HasPermission(source_url.GetOrigin()) :
608 WebKit::WebNotificationPresenter::PermissionNotAllowed;
609}
610
611void ChromeContentBrowserClient::ShowDesktopNotification(
612 const DesktopNotificationHostMsg_Show_Params& params,
613 int render_process_id,
614 int render_view_id,
615 bool worker) {
616 RenderViewHost* rvh = RenderViewHost::FromID(
617 render_process_id, render_view_id);
618 if (!rvh) {
619 NOTREACHED();
620 return;
621 }
622
623 RenderProcessHost* process = rvh->process();
[email protected]3d7474ff2011-07-27 17:47:37624 Profile* profile = Profile::FromBrowserContext(process->browser_context());
[email protected]941623e2011-06-07 23:06:04625 DesktopNotificationService* service =
[email protected]3d7474ff2011-07-27 17:47:37626 DesktopNotificationServiceFactory::GetForProfile(profile);
[email protected]941623e2011-06-07 23:06:04627 service->ShowDesktopNotification(
628 params, render_process_id, render_view_id,
629 worker ? DesktopNotificationService::WorkerNotification :
630 DesktopNotificationService::PageNotification);
631}
632
633void ChromeContentBrowserClient::CancelDesktopNotification(
634 int render_process_id,
635 int render_view_id,
636 int notification_id) {
637 RenderViewHost* rvh = RenderViewHost::FromID(
638 render_process_id, render_view_id);
639 if (!rvh) {
640 NOTREACHED();
641 return;
642 }
643
644 RenderProcessHost* process = rvh->process();
[email protected]3d7474ff2011-07-27 17:47:37645 Profile* profile = Profile::FromBrowserContext(process->browser_context());
[email protected]941623e2011-06-07 23:06:04646 DesktopNotificationService* service =
[email protected]3d7474ff2011-07-27 17:47:37647 DesktopNotificationServiceFactory::GetForProfile(profile);
[email protected]941623e2011-06-07 23:06:04648 service->CancelDesktopNotification(
649 render_process_id, render_view_id, notification_id);
650}
651
[email protected]9f3fba52011-06-08 20:37:19652bool ChromeContentBrowserClient::CanCreateWindow(
653 const GURL& source_url,
654 WindowContainerType container_type,
655 const content::ResourceContext& context) {
656 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
657 // If the opener is trying to create a background window but doesn't have
658 // the appropriate permission, fail the attempt.
659 if (container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) {
660 ProfileIOData* io_data =
661 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
662 const Extension* extension =
663 io_data->GetExtensionInfoMap()->extensions().GetByURL(source_url);
664 return (extension &&
[email protected]0d3e4a22011-06-23 19:02:52665 extension->HasAPIPermission(ExtensionAPIPermission::kBackground));
[email protected]9f3fba52011-06-08 20:37:19666 }
667 return true;
668}
669
670std::string ChromeContentBrowserClient::GetWorkerProcessTitle(
671 const GURL& url, const content::ResourceContext& context) {
672 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
673 // Check if it's an extension-created worker, in which case we want to use
674 // the name of the extension.
675 ProfileIOData* io_data =
676 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
677 const Extension* extension =
678 io_data->GetExtensionInfoMap()->extensions().GetByID(url.host());
679 return extension ? extension->name() : std::string();
680}
681
[email protected]3cb054e62011-06-13 05:21:17682ResourceDispatcherHost*
683 ChromeContentBrowserClient::GetResourceDispatcherHost() {
684 return g_browser_process->resource_dispatcher_host();
685}
686
687ui::Clipboard* ChromeContentBrowserClient::GetClipboard() {
688 return g_browser_process->clipboard();
689}
690
[email protected]8f6a3b852011-07-19 16:48:56691MHTMLGenerationManager*
692 ChromeContentBrowserClient::GetMHTMLGenerationManager() {
693 return g_browser_process->mhtml_generation_manager();
694}
695
[email protected]dce502762011-07-20 08:53:49696DevToolsManager* ChromeContentBrowserClient::GetDevToolsManager() {
697 return g_browser_process->devtools_manager();
698}
699
[email protected]ae6e9912011-07-27 01:18:28700net::NetLog* ChromeContentBrowserClient::GetNetLog() {
701 return g_browser_process->net_log();
702}
703
[email protected]dbae6b02011-06-29 23:51:41704bool ChromeContentBrowserClient::IsFastShutdownPossible() {
705 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
706 return !browser_command_line.HasSwitch(switches::kChromeFrame);
707}
708
[email protected]3d7474ff2011-07-27 17:47:37709WebPreferences ChromeContentBrowserClient::GetWebkitPrefs(
710 content::BrowserContext* browser_context, bool is_web_ui) {
711 return RenderViewHostDelegateHelper::GetWebkitPrefs(browser_context,
712 is_web_ui);
[email protected]181a95ee2011-07-12 19:26:36713}
714
715void ChromeContentBrowserClient::UpdateInspectorSetting(
716 RenderViewHost* rvh, const std::string& key, const std::string& value) {
717 RenderViewHostDelegateHelper::UpdateInspectorSetting(
[email protected]3d7474ff2011-07-27 17:47:37718 rvh->process()->browser_context(), key, value);
[email protected]181a95ee2011-07-12 19:26:36719}
720
721void ChromeContentBrowserClient::ClearInspectorSettings(RenderViewHost* rvh) {
722 RenderViewHostDelegateHelper::ClearInspectorSettings(
[email protected]3d7474ff2011-07-27 17:47:37723 rvh->process()->browser_context());
[email protected]181a95ee2011-07-12 19:26:36724}
725
[email protected]b8148ac2011-07-13 22:03:25726void ChromeContentBrowserClient::BrowserURLHandlerCreated(
727 BrowserURLHandler* handler) {
728 // Add the default URL handlers.
729 handler->AddHandlerPair(&ExtensionWebUI::HandleChromeURLOverride,
730 BrowserURLHandler::null_handler());
731 handler->AddHandlerPair(BrowserURLHandler::null_handler(),
732 &ExtensionWebUI::HandleChromeURLOverrideReverse);
733
734 // about:
735 handler->AddHandlerPair(&WillHandleBrowserAboutURL,
736 BrowserURLHandler::null_handler());
737 // chrome: & friends.
738 handler->AddHandlerPair(&HandleWebUI,
739 BrowserURLHandler::null_handler());
740}
741
742void ChromeContentBrowserClient::ClearCache(RenderViewHost* rvh) {
[email protected]3d7474ff2011-07-27 17:47:37743 Profile* profile = Profile::FromBrowserContext(
744 rvh->site_instance()->GetProcess()->browser_context());
[email protected]b8148ac2011-07-13 22:03:25745 BrowsingDataRemover* remover = new BrowsingDataRemover(profile,
746 BrowsingDataRemover::EVERYTHING,
747 base::Time());
748 remover->Remove(BrowsingDataRemover::REMOVE_CACHE);
749 // BrowsingDataRemover takes care of deleting itself when done.
750}
751
752void ChromeContentBrowserClient::ClearCookies(RenderViewHost* rvh) {
[email protected]3d7474ff2011-07-27 17:47:37753 Profile* profile = Profile::FromBrowserContext(
754 rvh->site_instance()->GetProcess()->browser_context());
[email protected]b8148ac2011-07-13 22:03:25755 BrowsingDataRemover* remover = new BrowsingDataRemover(profile,
756 BrowsingDataRemover::EVERYTHING,
757 base::Time());
758 int remove_mask = BrowsingDataRemover::REMOVE_COOKIES;
759 remover->Remove(remove_mask);
760 // BrowsingDataRemover takes care of deleting itself when done.
761}
762
[email protected]d90965842011-07-26 22:50:50763void ChromeContentBrowserClient::GetSaveDir(TabContents* tab_contents,
764 FilePath* website_save_dir,
765 FilePath* download_save_dir) {
766 PrefService* prefs = tab_contents->profile()->GetPrefs();
767
768 // Check whether the preference has the preferred directory for saving file.
769 // If not, initialize it with default directory.
770 if (!prefs->FindPreference(prefs::kSaveFileDefaultDirectory)) {
771 DCHECK(prefs->FindPreference(prefs::kDownloadDefaultDirectory));
772 FilePath default_save_path = prefs->GetFilePath(
773 prefs::kDownloadDefaultDirectory);
774 prefs->RegisterFilePathPref(prefs::kSaveFileDefaultDirectory,
775 default_save_path,
776 PrefService::UNSYNCABLE_PREF);
777 }
778
779 // Get the directory from preference.
780 *website_save_dir = prefs->GetFilePath(prefs::kSaveFileDefaultDirectory);
781 DCHECK(!website_save_dir->empty());
782
783 *download_save_dir = prefs->GetFilePath(prefs::kDownloadDefaultDirectory);
784}
785
[email protected]0ffaa482011-07-14 23:41:28786void ChromeContentBrowserClient::ChooseSavePath(
[email protected]680d2d42011-07-18 22:58:21787 const base::WeakPtr<SavePackage>& save_package,
[email protected]0ffaa482011-07-14 23:41:28788 const FilePath& suggested_path,
789 bool can_save_as_complete) {
790 // Deletes itself.
791 new SavePackageFilePicker(
792 save_package, suggested_path, can_save_as_complete);
793}
794
[email protected]b80f68432011-05-02 17:22:30795#if defined(OS_LINUX)
796int ChromeContentBrowserClient::GetCrashSignalFD(
797 const std::string& process_type) {
798 if (process_type == switches::kRendererProcess)
799 return RendererCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
800
[email protected]9dbfff12011-07-01 19:37:07801 if (process_type == switches::kExtensionProcess) {
802 ExtensionCrashHandlerHostLinux* crash_handler =
803 ExtensionCrashHandlerHostLinux::GetInstance();
804 return crash_handler->GetDeathSignalSocket();
805 }
806
[email protected]b80f68432011-05-02 17:22:30807 if (process_type == switches::kPluginProcess)
808 return PluginCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
809
810 if (process_type == switches::kPpapiPluginProcess)
811 return PpapiCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
812
813 if (process_type == switches::kGpuProcess)
814 return GpuCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
815
816 return -1;
817}
[email protected]9dbfff12011-07-01 19:37:07818#endif // defined(OS_LINUX)
[email protected]b80f68432011-05-02 17:22:30819
[email protected]37a72af2011-06-13 05:42:01820#if defined(USE_NSS)
821crypto::CryptoModuleBlockingPasswordDelegate*
822 ChromeContentBrowserClient::GetCryptoPasswordDelegate(
823 const GURL& url) {
824 return browser::NewCryptoModuleBlockingDialogDelegate(
825 browser::kCryptoModulePasswordKeygen, url.host());
826}
827#endif
828
[email protected]d977f9c2011-03-14 16:10:26829} // namespace chrome