blob: 5ff62fe60c702bd72f7c49c85b58d896cc1eda19 [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]941623e2011-06-07 23:06:0424#include "chrome/browser/notifications/desktop_notification_service.h"
25#include "chrome/browser/notifications/desktop_notification_service_factory.h"
[email protected]0609b17f2011-05-31 20:13:4226#include "chrome/browser/platform_util.h"
[email protected]763ec4ca2011-04-29 15:48:1227#include "chrome/browser/prefs/pref_service.h"
[email protected]05fcf982011-04-19 00:44:1428#include "chrome/browser/printing/printing_message_filter.h"
29#include "chrome/browser/profiles/profile.h"
[email protected]8093a542011-05-13 07:29:3230#include "chrome/browser/profiles/profile_io_data.h"
[email protected]05fcf982011-04-19 00:44:1431#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
[email protected]53a0afa2011-04-28 02:09:3332#include "chrome/browser/renderer_host/chrome_render_view_host_observer.h"
[email protected]d4cff272011-05-02 15:46:0133#include "chrome/browser/renderer_host/text_input_client_message_filter.h"
[email protected]05fcf982011-04-19 00:44:1434#include "chrome/browser/search_engines/search_provider_install_state_message_filter.h"
35#include "chrome/browser/spellcheck_message_filter.h"
[email protected]8ec26472011-06-06 16:52:4536#include "chrome/browser/ssl/ssl_add_cert_handler.h"
[email protected]848dd042011-06-04 18:24:0337#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]181a95ee2011-07-12 19:26:3638#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
[email protected]8ec26472011-06-06 16:52:4539#include "chrome/browser/tab_contents/tab_contents_ssl_helper.h"
40#include "chrome/browser/tab_contents/tab_util.h"
41#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]1fd1a502011-03-30 16:55:5642#include "chrome/browser/ui/webui/chrome_web_ui_factory.h"
[email protected]b80f68432011-05-02 17:22:3043#include "chrome/common/child_process_logging.h"
44#include "chrome/common/chrome_switches.h"
[email protected]941623e2011-06-07 23:06:0445#include "chrome/common/extensions/extension.h"
[email protected]c5dbef02011-05-13 05:06:0946#include "chrome/common/extensions/extension_messages.h"
[email protected]f1933792011-06-14 00:49:3447#include "chrome/common/logging_chrome.h"
[email protected]763ec4ca2011-04-29 15:48:1248#include "chrome/common/pref_names.h"
[email protected]3e69bc82011-05-26 23:22:3849#include "chrome/common/render_messages.h"
[email protected]c5dbef02011-05-13 05:06:0950#include "chrome/common/url_constants.h"
[email protected]b8148ac2011-07-13 22:03:2551#include "content/browser/browser_url_handler.h"
[email protected]c5dbef02011-05-13 05:06:0952#include "content/browser/browsing_instance.h"
53#include "content/browser/child_process_security_policy.h"
[email protected]b46442d7e2011-06-29 02:16:0654#include "content/browser/debugger/devtools_handler.h"
[email protected]97e6c4c2011-05-18 16:08:5155#include "content/browser/plugin_process_host.h"
[email protected]05fcf982011-04-19 00:44:1456#include "content/browser/renderer_host/browser_render_process_host.h"
[email protected]d977f9c2011-03-14 16:10:2657#include "content/browser/renderer_host/render_view_host.h"
[email protected]a2176792011-05-08 19:30:4958#include "content/browser/resource_context.h"
[email protected]c5dbef02011-05-13 05:06:0959#include "content/browser/site_instance.h"
[email protected]8ec26472011-06-06 16:52:4560#include "content/browser/ssl/ssl_client_auth_handler.h"
[email protected]763ec4ca2011-04-29 15:48:1261#include "content/browser/tab_contents/tab_contents.h"
[email protected]5327dfb2011-05-03 17:50:3662#include "content/browser/worker_host/worker_process_host.h"
[email protected]c5dbef02011-05-13 05:06:0963#include "content/common/bindings_policy.h"
[email protected]941623e2011-06-07 23:06:0464#include "content/common/desktop_notification_messages.h"
[email protected]29b25d092011-06-29 20:57:3465#include "grit/ui_resources.h"
[email protected]ed24fad2011-05-10 22:44:0166#include "net/base/cookie_monster.h"
67#include "net/base/cookie_options.h"
[email protected]ac55e292011-06-24 05:16:0868#include "ui/base/resource/resource_bundle.h"
[email protected]d977f9c2011-03-14 16:10:2669
[email protected]b80f68432011-05-02 17:22:3070#if defined(OS_LINUX)
71#include "base/linux_util.h"
72#include "chrome/browser/crash_handler_host_linux.h"
[email protected]1fd5302c2011-05-28 04:06:4373#endif
[email protected]b80f68432011-05-02 17:22:3074
[email protected]37a72af2011-06-13 05:42:0175#if defined(USE_NSS)
76#include "chrome/browser/ui/crypto_module_password_dialog.h"
77#endif
78
[email protected]c5dbef02011-05-13 05:06:0979namespace {
80
81void InitRenderViewHostForExtensions(RenderViewHost* render_view_host) {
82 // Note that due to GetEffectiveURL(), even hosted apps will have a
83 // chrome-extension:// URL for their site, so we can ignore that wrinkle here.
84 SiteInstance* site_instance = render_view_host->site_instance();
85 const GURL& site = site_instance->site();
86 RenderProcessHost* process = render_view_host->process();
87
88 if (!site.SchemeIs(chrome::kExtensionScheme))
89 return;
90
91 Profile* profile = site_instance->browsing_instance()->profile();
92 ExtensionService* service = profile->GetExtensionService();
93 if (!service)
94 return;
95
96 ExtensionProcessManager* process_manager =
97 profile->GetExtensionProcessManager();
98 CHECK(process_manager);
99
100 // This can happen if somebody typos a chrome-extension:// URL.
101 const Extension* extension = service->GetExtensionByURL(site);
102 if (!extension)
103 return;
104
105 site_instance->GetProcess()->mark_is_extension_process();
106
[email protected]056ad2a2011-07-12 02:13:55107 // Register the association between extension and SiteInstance with
[email protected]c5dbef02011-05-13 05:06:09108 // ExtensionProcessManager.
[email protected]056ad2a2011-07-12 02:13:55109 // TODO(creis): Use this to replace SetInstalledAppForRenderer below.
110 process_manager->RegisterExtensionSiteInstance(site_instance->id(),
111 extension->id());
[email protected]c5dbef02011-05-13 05:06:09112
[email protected]80675fc2011-06-21 02:05:49113 if (extension->is_app()) {
114 render_view_host->Send(
115 new ExtensionMsg_ActivateApplication(extension->id()));
116 // Record which, if any, installed app is associated with this process.
117 // TODO(aa): Totally lame to store this state in a global map in extension
118 // service. Can we get it from EPM instead?
[email protected]c5dbef02011-05-13 05:06:09119 service->SetInstalledAppForRenderer(process->id(), extension);
[email protected]80675fc2011-06-21 02:05:49120 }
[email protected]c5dbef02011-05-13 05:06:09121
122 // Some extensions use chrome:// URLs.
123 Extension::Type type = extension->GetType();
124 if (type == Extension::TYPE_EXTENSION ||
125 type == Extension::TYPE_PACKAGED_APP) {
126 ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
127 process->id(), chrome::kChromeUIScheme);
128 }
129
130 // Enable extension bindings for the renderer. Currently only extensions,
131 // packaged apps, and hosted component apps use extension bindings.
132 if (type == Extension::TYPE_EXTENSION ||
[email protected]2333bf22011-05-19 02:16:51133 type == Extension::TYPE_USER_SCRIPT ||
[email protected]c5dbef02011-05-13 05:06:09134 type == Extension::TYPE_PACKAGED_APP ||
135 (type == Extension::TYPE_HOSTED_APP &&
136 extension->location() == Extension::COMPONENT)) {
137 render_view_host->Send(new ExtensionMsg_ActivateExtension(extension->id()));
138 render_view_host->AllowBindings(BindingsPolicy::EXTENSION);
139 }
140}
141
[email protected]b8148ac2011-07-13 22:03:25142// Handles rewriting Web UI URLs.
143static bool HandleWebUI(GURL* url, Profile* profile) {
144 if (!ChromeWebUIFactory::GetInstance()->UseWebUIForURL(profile, *url))
145 return false;
146
147 // Special case the new tab page. In older versions of Chrome, the new tab
148 // page was hosted at chrome-internal:<blah>. This might be in people's saved
149 // sessions or bookmarks, so we say any URL with that scheme triggers the new
150 // tab page.
151 if (url->SchemeIs(chrome::kChromeInternalScheme)) {
152 // Rewrite it with the proper new tab URL.
153 *url = GURL(chrome::kChromeUINewTabURL);
154 }
155
156 return true;
157}
158
[email protected]9dbfff12011-07-01 19:37:07159} // namespace
[email protected]c5dbef02011-05-13 05:06:09160
[email protected]d977f9c2011-03-14 16:10:26161namespace chrome {
162
[email protected]f364d1392011-04-08 21:03:10163void ChromeContentBrowserClient::RenderViewHostCreated(
164 RenderViewHost* render_view_host) {
[email protected]53a0afa2011-04-28 02:09:33165 new ChromeRenderViewHostObserver(render_view_host);
[email protected]f364d1392011-04-08 21:03:10166 new DevToolsHandler(render_view_host);
167 new ExtensionMessageHandler(render_view_host);
[email protected]f364d1392011-04-08 21:03:10168
[email protected]c5dbef02011-05-13 05:06:09169 InitRenderViewHostForExtensions(render_view_host);
[email protected]d977f9c2011-03-14 16:10:26170}
171
[email protected]05fcf982011-04-19 00:44:14172void ChromeContentBrowserClient::BrowserRenderProcessHostCreated(
173 BrowserRenderProcessHost* host) {
[email protected]c47cfd62011-04-29 21:27:02174 int id = host->id();
175 Profile* profile = host->profile();
[email protected]05fcf982011-04-19 00:44:14176 host->channel()->AddFilter(new ChromeRenderMessageFilter(
[email protected]c47cfd62011-04-29 21:27:02177 id, profile, profile->GetRequestContextForRenderProcess(id)));
[email protected]05fcf982011-04-19 00:44:14178 host->channel()->AddFilter(new PrintingMessageFilter());
179 host->channel()->AddFilter(
[email protected]c47cfd62011-04-29 21:27:02180 new SearchProviderInstallStateMessageFilter(id, profile));
181 host->channel()->AddFilter(new SpellCheckMessageFilter(id));
[email protected]d4cff272011-05-02 15:46:01182#if defined(OS_MACOSX)
183 host->channel()->AddFilter(new TextInputClientMessageFilter(host->id()));
184#endif
[email protected]3e69bc82011-05-26 23:22:38185
186 host->Send(new ViewMsg_SetIsIncognitoProcess(profile->IsOffTheRecord()));
[email protected]05fcf982011-04-19 00:44:14187}
188
[email protected]97e6c4c2011-05-18 16:08:51189void ChromeContentBrowserClient::PluginProcessHostCreated(
190 PluginProcessHost* host) {
191 host->AddFilter(new ChromePluginMessageFilter(host));
192}
193
[email protected]5327dfb2011-05-03 17:50:36194void ChromeContentBrowserClient::WorkerProcessHostCreated(
195 WorkerProcessHost* host) {
196 host->AddFilter(new ChromeWorkerMessageFilter(host));
197}
198
[email protected]1fd1a502011-03-30 16:55:56199content::WebUIFactory* ChromeContentBrowserClient::GetWebUIFactory() {
200 return ChromeWebUIFactory::GetInstance();
201}
202
[email protected]36fb2c7c2011-04-04 15:49:08203GURL ChromeContentBrowserClient::GetEffectiveURL(Profile* profile,
204 const GURL& url) {
205 // Get the effective URL for the given actual URL. If the URL is part of an
206 // installed app, the effective URL is an extension URL with the ID of that
207 // extension as the host. This has the effect of grouping apps together in
208 // a common SiteInstance.
209 if (!profile || !profile->GetExtensionService())
210 return url;
211
212 const Extension* extension =
213 profile->GetExtensionService()->GetExtensionByWebExtent(url);
214 if (!extension)
215 return url;
216
217 // If the URL is part of an extension's web extent, convert it to an
218 // extension URL.
219 return extension->GetResourceURL(url.path());
220}
221
[email protected]056ad2a2011-07-12 02:13:55222bool ChromeContentBrowserClient::ShouldUseProcessPerSite(
223 Profile* profile,
224 const GURL& effective_url) {
225 // Non-extension URLs should generally use process-per-site-instance.
226 // Because we expect to use the effective URL, hosted apps URLs should have
227 // an extension scheme by now.
228 if (!effective_url.SchemeIs(chrome::kExtensionScheme))
229 return false;
230
231 if (!profile || !profile->GetExtensionService())
232 return false;
233
234 const Extension* extension =
235 profile->GetExtensionService()->GetExtensionByURL(effective_url);
236 if (!extension)
237 return false;
238
239 // If the URL is part of a hosted app that does not have the background
240 // permission, we want to give each instance its own process to improve
241 // responsiveness.
242 if (extension->GetType() == Extension::TYPE_HOSTED_APP &&
243 !extension->HasAPIPermission(ExtensionAPIPermission::kBackground))
244 return false;
245
246 // Hosted apps that have the background permission must use process per site,
247 // since all instances can make synchronous calls to the background window.
248 // Other extensions should use process per site as well.
249 return true;
250}
251
[email protected]0f012df82011-05-19 14:15:29252bool ChromeContentBrowserClient::IsURLSameAsAnySiteInstance(const GURL& url) {
[email protected]89f550b2011-06-08 18:34:03253 return url == GURL(chrome::kChromeUICrashURL) ||
254 url == GURL(chrome::kChromeUIKillURL) ||
255 url == GURL(chrome::kChromeUIHangURL) ||
256 url == GURL(chrome::kChromeUIShorthangURL);
[email protected]0f012df82011-05-19 14:15:29257}
258
[email protected]763ec4ca2011-04-29 15:48:12259std::string ChromeContentBrowserClient::GetCanonicalEncodingNameByAliasName(
260 const std::string& alias_name) {
261 return CharacterEncoding::GetCanonicalEncodingNameByAliasName(alias_name);
262}
263
[email protected]b80f68432011-05-02 17:22:30264void ChromeContentBrowserClient::AppendExtraCommandLineSwitches(
265 CommandLine* command_line, int child_process_id) {
266#if defined(USE_LINUX_BREAKPAD)
267 if (IsCrashReporterEnabled()) {
268 command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
269 child_process_logging::GetClientId() + "," + base::GetLinuxDistro());
270 }
271#elif defined(OS_MACOSX)
272 if (IsCrashReporterEnabled()) {
273 command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
274 child_process_logging::GetClientId());
275 }
276#endif // OS_MACOSX
277
[email protected]f1933792011-06-14 00:49:34278 if (logging::DialogsAreSuppressed())
279 command_line->AppendSwitch(switches::kNoErrorDialogs);
280
[email protected]b80f68432011-05-02 17:22:30281 std::string process_type =
282 command_line->GetSwitchValueASCII(switches::kProcessType);
[email protected]3cb054e62011-06-13 05:21:17283 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
[email protected]b80f68432011-05-02 17:22:30284 if (process_type == switches::kExtensionProcess ||
285 process_type == switches::kRendererProcess) {
[email protected]b80f68432011-05-02 17:22:30286 FilePath user_data_dir =
287 browser_command_line.GetSwitchValuePath(switches::kUserDataDir);
288 if (!user_data_dir.empty())
289 command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir);
290#if defined(OS_CHROMEOS)
291 const std::string& login_profile =
292 browser_command_line.GetSwitchValueASCII(switches::kLoginProfile);
293 if (!login_profile.empty())
294 command_line->AppendSwitchASCII(switches::kLoginProfile, login_profile);
295#endif
296
297 RenderProcessHost* process = RenderProcessHost::FromID(child_process_id);
298
299 PrefService* prefs = process->profile()->GetPrefs();
300 // Currently this pref is only registered if applied via a policy.
301 if (prefs->HasPrefPath(prefs::kDisable3DAPIs) &&
302 prefs->GetBoolean(prefs::kDisable3DAPIs)) {
303 // Turn this policy into a command line switch.
304 command_line->AppendSwitch(switches::kDisable3DAPIs);
305 }
306
307 // Disable client-side phishing detection in the renderer if it is disabled
[email protected]8c40da62011-07-13 22:58:46308 // in the Profile preferences or the browser process.
309 if (!prefs->GetBoolean(prefs::kSafeBrowsingEnabled) ||
310 !g_browser_process->safe_browsing_detection_service()) {
[email protected]b80f68432011-05-02 17:22:30311 command_line->AppendSwitch(switches::kDisableClientSidePhishingDetection);
[email protected]8c40da62011-07-13 22:58:46312 }
[email protected]4287a3d2011-06-13 23:56:51313
314 static const char* const kSwitchNames[] = {
315 switches::kAllowHTTPBackgroundPage,
316 switches::kAllowScriptingGallery,
317 switches::kAppsCheckoutURL,
318 switches::kAppsGalleryURL,
[email protected]be9d9c82011-07-13 04:17:31319 switches::kCloudPrintServiceURL,
[email protected]4287a3d2011-06-13 23:56:51320 switches::kDebugPrint,
321#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
322 // Enabled by default in Google Chrome builds, except on CrOS.
323 switches::kDisablePrintPreview,
324#else
325 // Disabled by default in Chromium builds and on CrOS.
326 switches::kEnablePrintPreview,
327#endif
328 switches::kDomAutomationController,
329 switches::kDumpHistogramsOnExit,
330 switches::kEnableClickToPlay,
331 switches::kEnableCrxlessWebApps,
332 switches::kEnableExperimentalExtensionApis,
333 switches::kEnableInBrowserThumbnailing,
334 switches::kEnableIPCFuzzing,
335 switches::kEnableNaCl,
336 switches::kEnableRemoting,
337 switches::kEnableResourceContentSettings,
338 switches::kEnableSearchProviderApiV2,
339 switches::kEnableWatchdog,
340 switches::kExperimentalSpellcheckerFeatures,
341 switches::kMemoryProfiling,
342 switches::kMessageLoopHistogrammer,
343 switches::kPpapiFlashArgs,
344 switches::kPpapiFlashInProcess,
345 switches::kPpapiFlashPath,
346 switches::kPpapiFlashVersion,
347 switches::kProfilingAtStart,
348 switches::kProfilingFile,
349 switches::kProfilingFlush,
350 switches::kRemoteShellPort,
351 switches::kSilentDumpOnDCHECK,
352 };
353
354 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
355 arraysize(kSwitchNames));
[email protected]3cb054e62011-06-13 05:21:17356 } else if (process_type == switches::kUtilityProcess) {
357 if (browser_command_line.HasSwitch(
358 switches::kEnableExperimentalExtensionApis)) {
359 command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
360 }
[email protected]4287a3d2011-06-13 23:56:51361 } else if (process_type == switches::kPluginProcess) {
362 static const char* const kSwitchNames[] = {
363 #if defined(OS_CHROMEOS)
364 switches::kLoginProfile,
365 #endif
366 switches::kMemoryProfiling,
367 switches::kSilentDumpOnDCHECK,
368 switches::kUserDataDir,
369 };
370
371 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
372 arraysize(kSwitchNames));
373 } else if (process_type == switches::kZygoteProcess) {
374 static const char* const kSwitchNames[] = {
375 switches::kEnableRemoting,
376 switches::kUserDataDir, // Make logs go to the right file.
377 // Load (in-process) Pepper plugins in-process in the zygote pre-sandbox.
378 switches::kPpapiFlashInProcess,
379 switches::kPpapiFlashPath,
380 switches::kPpapiFlashVersion,
381 };
382
383 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
384 arraysize(kSwitchNames));
[email protected]b80f68432011-05-02 17:22:30385 }
386}
387
388std::string ChromeContentBrowserClient::GetApplicationLocale() {
389 return g_browser_process->GetApplicationLocale();
390}
391
[email protected]b5cca982011-05-26 04:42:08392std::string ChromeContentBrowserClient::GetAcceptLangs(const TabContents* tab) {
393 return tab->profile()->GetPrefs()->GetString(prefs::kAcceptLanguages);
394}
395
[email protected]ac55e292011-06-24 05:16:08396SkBitmap* ChromeContentBrowserClient::GetDefaultFavicon() {
397 ResourceBundle &rb = ResourceBundle::GetSharedInstance();
398 return rb.GetBitmapNamed(IDR_DEFAULT_FAVICON);
399}
400
[email protected]a2176792011-05-08 19:30:49401bool ChromeContentBrowserClient::AllowAppCache(
[email protected]5b52ad42011-05-26 14:26:09402 const GURL& manifest_url,
403 const content::ResourceContext& context) {
[email protected]8093a542011-05-13 07:29:32404 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
405 ProfileIOData* io_data =
406 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09407 // FIXME(jochen): get the correct top-level origin.
[email protected]efa55212011-05-13 16:19:38408 ContentSetting setting = io_data->GetHostContentSettingsMap()->
[email protected]5b52ad42011-05-26 14:26:09409 GetCookieContentSetting(manifest_url, manifest_url, true);
[email protected]a2176792011-05-08 19:30:49410 DCHECK(setting != CONTENT_SETTING_DEFAULT);
411 return setting != CONTENT_SETTING_BLOCK;
412}
413
[email protected]ed24fad2011-05-10 22:44:01414bool ChromeContentBrowserClient::AllowGetCookie(
415 const GURL& url,
416 const GURL& first_party,
417 const net::CookieList& cookie_list,
418 const content::ResourceContext& context,
419 int render_process_id,
420 int render_view_id) {
421 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]8093a542011-05-13 07:29:32422 ProfileIOData* io_data =
423 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09424 ContentSetting setting = io_data->GetHostContentSettingsMap()->
425 GetCookieContentSetting(url, first_party, false);
426 bool allow = setting == CONTENT_SETTING_ALLOW ||
427 setting == CONTENT_SETTING_SESSION_ONLY;
[email protected]ed24fad2011-05-10 22:44:01428
[email protected]8093a542011-05-13 07:29:32429 BrowserThread::PostTask(
430 BrowserThread::UI, FROM_HERE,
431 NewRunnableFunction(
432 &TabSpecificContentSettings::CookiesRead,
433 render_process_id, render_view_id, url, cookie_list, !allow));
[email protected]ed24fad2011-05-10 22:44:01434 return allow;
435}
436
437bool ChromeContentBrowserClient::AllowSetCookie(
438 const GURL& url,
439 const GURL& first_party,
440 const std::string& cookie_line,
441 const content::ResourceContext& context,
442 int render_process_id,
443 int render_view_id,
444 net::CookieOptions* options) {
445 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]8093a542011-05-13 07:29:32446 ProfileIOData* io_data =
447 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09448 ContentSetting setting = io_data->GetHostContentSettingsMap()->
449 GetCookieContentSetting(url, first_party, true);
[email protected]ed24fad2011-05-10 22:44:01450
[email protected]5b52ad42011-05-26 14:26:09451 if (setting == CONTENT_SETTING_SESSION_ONLY)
452 options->set_force_session();
[email protected]ed24fad2011-05-10 22:44:01453
[email protected]5b52ad42011-05-26 14:26:09454 bool allow = setting == CONTENT_SETTING_ALLOW ||
455 setting == CONTENT_SETTING_SESSION_ONLY;
[email protected]ed24fad2011-05-10 22:44:01456
[email protected]8093a542011-05-13 07:29:32457 BrowserThread::PostTask(
458 BrowserThread::UI, FROM_HERE,
459 NewRunnableFunction(
460 &TabSpecificContentSettings::CookieChanged,
461 render_process_id, render_view_id, url, cookie_line, *options,
462 !allow));
[email protected]ed24fad2011-05-10 22:44:01463 return allow;
464}
465
[email protected]d5a19162011-06-30 18:51:54466bool ChromeContentBrowserClient::AllowSaveLocalState(
467 const content::ResourceContext& context) {
468 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
469 ProfileIOData* io_data =
470 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
471 return !io_data->clear_local_state_on_exit()->GetValue();
472}
473
[email protected]6133f922011-07-01 21:34:34474net::URLRequestContext*
475ChromeContentBrowserClient::OverrideRequestContextForURL(
476 const GURL& url, const content::ResourceContext& context) {
477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
478 if (url.SchemeIs(chrome::kExtensionScheme)) {
479 ProfileIOData* io_data =
480 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
481 return io_data->extensions_request_context();
482 }
483
484 return NULL;
485}
486
[email protected]317f96c92011-05-31 06:53:41487QuotaPermissionContext*
488ChromeContentBrowserClient::CreateQuotaPermissionContext() {
489 return new ChromeQuotaPermissionContext();
490}
491
[email protected]0609b17f2011-05-31 20:13:42492void ChromeContentBrowserClient::RevealFolderInOS(const FilePath& path) {
493 // On Mac, this call needs to be done on the UI thread. On other platforms,
494 // do it on the FILE thread so we don't slow down UI.
495#if defined(OS_MACOSX)
496 platform_util::OpenItem(path);
497#else
498 BrowserThread::PostTask(
499 BrowserThread::FILE, FROM_HERE,
500 NewRunnableFunction(&platform_util::OpenItem, path));
501#endif
502}
503
[email protected]848dd042011-06-04 18:24:03504void ChromeContentBrowserClient::AllowCertificateError(
505 SSLCertErrorHandler* handler,
506 bool overridable,
507 Callback2<SSLCertErrorHandler*, bool>::Type* callback) {
508 SSLBlockingPage* blocking_page = new SSLBlockingPage(
509 handler, overridable, callback);
510 blocking_page->Show();
511}
512
[email protected]8ec26472011-06-06 16:52:45513void ChromeContentBrowserClient::ShowClientCertificateRequestDialog(
514 int render_process_id,
515 int render_view_id,
516 SSLClientAuthHandler* handler) {
517 TabContents* tab = tab_util::GetTabContentsByID(
518 render_process_id, render_view_id);
519 if (!tab) {
520 NOTREACHED();
521 return;
522 }
523
524 TabContentsWrapper* wrapper =
525 TabContentsWrapper::GetCurrentWrapperForContents(tab);
526 wrapper->ssl_helper()->ShowClientCertificateRequestDialog(handler);
527}
528
529void ChromeContentBrowserClient::AddNewCertificate(
530 net::URLRequest* request,
531 net::X509Certificate* cert,
532 int render_process_id,
533 int render_view_id) {
534 // The handler will run the UI and delete itself when it's finished.
535 new SSLAddCertHandler(request, cert, render_process_id, render_view_id);
536}
537
[email protected]941623e2011-06-07 23:06:04538void ChromeContentBrowserClient::RequestDesktopNotificationPermission(
539 const GURL& source_origin,
540 int callback_context,
541 int render_process_id,
542 int render_view_id) {
543 RenderViewHost* rvh = RenderViewHost::FromID(
544 render_process_id, render_view_id);
545 if (!rvh) {
546 NOTREACHED();
547 return;
548 }
549
550 RenderProcessHost* process = rvh->process();
551 DesktopNotificationService* service =
552 DesktopNotificationServiceFactory::GetForProfile(process->profile());
553 service->RequestPermission(
554 source_origin, render_process_id, render_view_id, callback_context,
555 tab_util::GetTabContentsByID(render_process_id, render_view_id));
556}
557
558WebKit::WebNotificationPresenter::Permission
559 ChromeContentBrowserClient::CheckDesktopNotificationPermission(
560 const GURL& source_url,
561 const content::ResourceContext& context) {
562 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
563 ProfileIOData* io_data =
564 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
565
566 const Extension* extension =
567 io_data->GetExtensionInfoMap()->extensions().GetByURL(source_url);
568 if (extension &&
[email protected]0d3e4a22011-06-23 19:02:52569 extension->HasAPIPermission(ExtensionAPIPermission::kNotification)) {
[email protected]941623e2011-06-07 23:06:04570 return WebKit::WebNotificationPresenter::PermissionAllowed;
571 }
572
573 // Fall back to the regular notification preferences, which works on an
574 // origin basis.
575 return io_data->GetNotificationService() ?
576 io_data->GetNotificationService()->HasPermission(source_url.GetOrigin()) :
577 WebKit::WebNotificationPresenter::PermissionNotAllowed;
578}
579
580void ChromeContentBrowserClient::ShowDesktopNotification(
581 const DesktopNotificationHostMsg_Show_Params& params,
582 int render_process_id,
583 int render_view_id,
584 bool worker) {
585 RenderViewHost* rvh = RenderViewHost::FromID(
586 render_process_id, render_view_id);
587 if (!rvh) {
588 NOTREACHED();
589 return;
590 }
591
592 RenderProcessHost* process = rvh->process();
593 DesktopNotificationService* service =
594 DesktopNotificationServiceFactory::GetForProfile(process->profile());
595 service->ShowDesktopNotification(
596 params, render_process_id, render_view_id,
597 worker ? DesktopNotificationService::WorkerNotification :
598 DesktopNotificationService::PageNotification);
599}
600
601void ChromeContentBrowserClient::CancelDesktopNotification(
602 int render_process_id,
603 int render_view_id,
604 int notification_id) {
605 RenderViewHost* rvh = RenderViewHost::FromID(
606 render_process_id, render_view_id);
607 if (!rvh) {
608 NOTREACHED();
609 return;
610 }
611
612 RenderProcessHost* process = rvh->process();
613 DesktopNotificationService* service =
614 DesktopNotificationServiceFactory::GetForProfile(process->profile());
615 service->CancelDesktopNotification(
616 render_process_id, render_view_id, notification_id);
617}
618
[email protected]9f3fba52011-06-08 20:37:19619bool ChromeContentBrowserClient::CanCreateWindow(
620 const GURL& source_url,
621 WindowContainerType container_type,
622 const content::ResourceContext& context) {
623 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
624 // If the opener is trying to create a background window but doesn't have
625 // the appropriate permission, fail the attempt.
626 if (container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) {
627 ProfileIOData* io_data =
628 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
629 const Extension* extension =
630 io_data->GetExtensionInfoMap()->extensions().GetByURL(source_url);
631 return (extension &&
[email protected]0d3e4a22011-06-23 19:02:52632 extension->HasAPIPermission(ExtensionAPIPermission::kBackground));
[email protected]9f3fba52011-06-08 20:37:19633 }
634 return true;
635}
636
637std::string ChromeContentBrowserClient::GetWorkerProcessTitle(
638 const GURL& url, const content::ResourceContext& context) {
639 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
640 // Check if it's an extension-created worker, in which case we want to use
641 // the name of the extension.
642 ProfileIOData* io_data =
643 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
644 const Extension* extension =
645 io_data->GetExtensionInfoMap()->extensions().GetByID(url.host());
646 return extension ? extension->name() : std::string();
647}
648
[email protected]3cb054e62011-06-13 05:21:17649ResourceDispatcherHost*
650 ChromeContentBrowserClient::GetResourceDispatcherHost() {
651 return g_browser_process->resource_dispatcher_host();
652}
653
654ui::Clipboard* ChromeContentBrowserClient::GetClipboard() {
655 return g_browser_process->clipboard();
656}
657
[email protected]8f6a3b852011-07-19 16:48:56658MHTMLGenerationManager*
659 ChromeContentBrowserClient::GetMHTMLGenerationManager() {
660 return g_browser_process->mhtml_generation_manager();
661}
662
[email protected]dbae6b02011-06-29 23:51:41663bool ChromeContentBrowserClient::IsFastShutdownPossible() {
664 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
665 return !browser_command_line.HasSwitch(switches::kChromeFrame);
666}
667
[email protected]181a95ee2011-07-12 19:26:36668WebPreferences ChromeContentBrowserClient::GetWebkitPrefs(Profile* profile,
669 bool is_web_ui) {
670 return RenderViewHostDelegateHelper::GetWebkitPrefs(profile, is_web_ui);
671}
672
673void ChromeContentBrowserClient::UpdateInspectorSetting(
674 RenderViewHost* rvh, const std::string& key, const std::string& value) {
675 RenderViewHostDelegateHelper::UpdateInspectorSetting(
676 rvh->process()->profile(), key, value);
677}
678
679void ChromeContentBrowserClient::ClearInspectorSettings(RenderViewHost* rvh) {
680 RenderViewHostDelegateHelper::ClearInspectorSettings(
681 rvh->process()->profile());
682}
683
[email protected]b8148ac2011-07-13 22:03:25684void ChromeContentBrowserClient::BrowserURLHandlerCreated(
685 BrowserURLHandler* handler) {
686 // Add the default URL handlers.
687 handler->AddHandlerPair(&ExtensionWebUI::HandleChromeURLOverride,
688 BrowserURLHandler::null_handler());
689 handler->AddHandlerPair(BrowserURLHandler::null_handler(),
690 &ExtensionWebUI::HandleChromeURLOverrideReverse);
691
692 // about:
693 handler->AddHandlerPair(&WillHandleBrowserAboutURL,
694 BrowserURLHandler::null_handler());
695 // chrome: & friends.
696 handler->AddHandlerPair(&HandleWebUI,
697 BrowserURLHandler::null_handler());
698}
699
700void ChromeContentBrowserClient::ClearCache(RenderViewHost* rvh) {
701 Profile* profile = rvh->site_instance()->GetProcess()->profile();
702 BrowsingDataRemover* remover = new BrowsingDataRemover(profile,
703 BrowsingDataRemover::EVERYTHING,
704 base::Time());
705 remover->Remove(BrowsingDataRemover::REMOVE_CACHE);
706 // BrowsingDataRemover takes care of deleting itself when done.
707}
708
709void ChromeContentBrowserClient::ClearCookies(RenderViewHost* rvh) {
710 Profile* profile = rvh->site_instance()->GetProcess()->profile();
711 BrowsingDataRemover* remover = new BrowsingDataRemover(profile,
712 BrowsingDataRemover::EVERYTHING,
713 base::Time());
714 int remove_mask = BrowsingDataRemover::REMOVE_COOKIES;
715 remover->Remove(remove_mask);
716 // BrowsingDataRemover takes care of deleting itself when done.
717}
718
[email protected]0ffaa482011-07-14 23:41:28719void ChromeContentBrowserClient::ChooseSavePath(
[email protected]680d2d42011-07-18 22:58:21720 const base::WeakPtr<SavePackage>& save_package,
[email protected]0ffaa482011-07-14 23:41:28721 const FilePath& suggested_path,
722 bool can_save_as_complete) {
723 // Deletes itself.
724 new SavePackageFilePicker(
725 save_package, suggested_path, can_save_as_complete);
726}
727
[email protected]b80f68432011-05-02 17:22:30728#if defined(OS_LINUX)
729int ChromeContentBrowserClient::GetCrashSignalFD(
730 const std::string& process_type) {
731 if (process_type == switches::kRendererProcess)
732 return RendererCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
733
[email protected]9dbfff12011-07-01 19:37:07734 if (process_type == switches::kExtensionProcess) {
735 ExtensionCrashHandlerHostLinux* crash_handler =
736 ExtensionCrashHandlerHostLinux::GetInstance();
737 return crash_handler->GetDeathSignalSocket();
738 }
739
[email protected]b80f68432011-05-02 17:22:30740 if (process_type == switches::kPluginProcess)
741 return PluginCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
742
743 if (process_type == switches::kPpapiPluginProcess)
744 return PpapiCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
745
746 if (process_type == switches::kGpuProcess)
747 return GpuCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
748
749 return -1;
750}
[email protected]9dbfff12011-07-01 19:37:07751#endif // defined(OS_LINUX)
[email protected]b80f68432011-05-02 17:22:30752
[email protected]37a72af2011-06-13 05:42:01753#if defined(USE_NSS)
754crypto::CryptoModuleBlockingPasswordDelegate*
755 ChromeContentBrowserClient::GetCryptoPasswordDelegate(
756 const GURL& url) {
757 return browser::NewCryptoModuleBlockingDialogDelegate(
758 browser::kCryptoModulePasswordKeygen, url.host());
759}
760#endif
761
[email protected]d977f9c2011-03-14 16:10:26762} // namespace chrome