blob: 9758443f2ac9f017f6a731c482991ddf8146fa2c [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]941623e2011-06-07 23:06:0418#include "chrome/browser/extensions/extension_info_map.h"
[email protected]f364d1392011-04-08 21:03:1019#include "chrome/browser/extensions/extension_message_handler.h"
[email protected]d977f9c2011-03-14 16:10:2620#include "chrome/browser/extensions/extension_service.h"
[email protected]b8148ac2011-07-13 22:03:2521#include "chrome/browser/extensions/extension_web_ui.h"
[email protected]763ec4ca2011-04-29 15:48:1222#include "chrome/browser/google/google_util.h"
[email protected]941623e2011-06-07 23:06:0423#include "chrome/browser/notifications/desktop_notification_service.h"
24#include "chrome/browser/notifications/desktop_notification_service_factory.h"
[email protected]0609b17f2011-05-31 20:13:4225#include "chrome/browser/platform_util.h"
[email protected]763ec4ca2011-04-29 15:48:1226#include "chrome/browser/prefs/pref_service.h"
[email protected]05fcf982011-04-19 00:44:1427#include "chrome/browser/printing/printing_message_filter.h"
28#include "chrome/browser/profiles/profile.h"
[email protected]8093a542011-05-13 07:29:3229#include "chrome/browser/profiles/profile_io_data.h"
[email protected]05fcf982011-04-19 00:44:1430#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
[email protected]53a0afa2011-04-28 02:09:3331#include "chrome/browser/renderer_host/chrome_render_view_host_observer.h"
[email protected]d4cff272011-05-02 15:46:0132#include "chrome/browser/renderer_host/text_input_client_message_filter.h"
[email protected]05fcf982011-04-19 00:44:1433#include "chrome/browser/search_engines/search_provider_install_state_message_filter.h"
34#include "chrome/browser/spellcheck_message_filter.h"
[email protected]8ec26472011-06-06 16:52:4535#include "chrome/browser/ssl/ssl_add_cert_handler.h"
[email protected]848dd042011-06-04 18:24:0336#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]181a95ee2011-07-12 19:26:3637#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
[email protected]8ec26472011-06-06 16:52:4538#include "chrome/browser/tab_contents/tab_contents_ssl_helper.h"
39#include "chrome/browser/tab_contents/tab_util.h"
40#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]1fd1a502011-03-30 16:55:5641#include "chrome/browser/ui/webui/chrome_web_ui_factory.h"
[email protected]b80f68432011-05-02 17:22:3042#include "chrome/common/child_process_logging.h"
43#include "chrome/common/chrome_switches.h"
[email protected]941623e2011-06-07 23:06:0444#include "chrome/common/extensions/extension.h"
[email protected]c5dbef02011-05-13 05:06:0945#include "chrome/common/extensions/extension_messages.h"
[email protected]f1933792011-06-14 00:49:3446#include "chrome/common/logging_chrome.h"
[email protected]763ec4ca2011-04-29 15:48:1247#include "chrome/common/pref_names.h"
[email protected]3e69bc82011-05-26 23:22:3848#include "chrome/common/render_messages.h"
[email protected]c5dbef02011-05-13 05:06:0949#include "chrome/common/url_constants.h"
[email protected]b8148ac2011-07-13 22:03:2550#include "content/browser/browser_url_handler.h"
[email protected]c5dbef02011-05-13 05:06:0951#include "content/browser/browsing_instance.h"
52#include "content/browser/child_process_security_policy.h"
[email protected]b46442d7e2011-06-29 02:16:0653#include "content/browser/debugger/devtools_handler.h"
[email protected]97e6c4c2011-05-18 16:08:5154#include "content/browser/plugin_process_host.h"
[email protected]05fcf982011-04-19 00:44:1455#include "content/browser/renderer_host/browser_render_process_host.h"
[email protected]d977f9c2011-03-14 16:10:2656#include "content/browser/renderer_host/render_view_host.h"
[email protected]a2176792011-05-08 19:30:4957#include "content/browser/resource_context.h"
[email protected]c5dbef02011-05-13 05:06:0958#include "content/browser/site_instance.h"
[email protected]8ec26472011-06-06 16:52:4559#include "content/browser/ssl/ssl_client_auth_handler.h"
[email protected]763ec4ca2011-04-29 15:48:1260#include "content/browser/tab_contents/tab_contents.h"
[email protected]5327dfb2011-05-03 17:50:3661#include "content/browser/worker_host/worker_process_host.h"
[email protected]c5dbef02011-05-13 05:06:0962#include "content/common/bindings_policy.h"
[email protected]941623e2011-06-07 23:06:0463#include "content/common/desktop_notification_messages.h"
[email protected]29b25d092011-06-29 20:57:3464#include "grit/ui_resources.h"
[email protected]ed24fad2011-05-10 22:44:0165#include "net/base/cookie_monster.h"
66#include "net/base/cookie_options.h"
[email protected]ac55e292011-06-24 05:16:0867#include "ui/base/resource/resource_bundle.h"
[email protected]d977f9c2011-03-14 16:10:2668
[email protected]b80f68432011-05-02 17:22:3069#if defined(OS_LINUX)
70#include "base/linux_util.h"
71#include "chrome/browser/crash_handler_host_linux.h"
[email protected]1fd5302c2011-05-28 04:06:4372#endif
[email protected]b80f68432011-05-02 17:22:3073
[email protected]37a72af2011-06-13 05:42:0174#if defined(USE_NSS)
75#include "chrome/browser/ui/crypto_module_password_dialog.h"
76#endif
77
[email protected]c5dbef02011-05-13 05:06:0978namespace {
79
80void InitRenderViewHostForExtensions(RenderViewHost* render_view_host) {
81 // Note that due to GetEffectiveURL(), even hosted apps will have a
82 // chrome-extension:// URL for their site, so we can ignore that wrinkle here.
83 SiteInstance* site_instance = render_view_host->site_instance();
84 const GURL& site = site_instance->site();
85 RenderProcessHost* process = render_view_host->process();
86
87 if (!site.SchemeIs(chrome::kExtensionScheme))
88 return;
89
90 Profile* profile = site_instance->browsing_instance()->profile();
91 ExtensionService* service = profile->GetExtensionService();
92 if (!service)
93 return;
94
95 ExtensionProcessManager* process_manager =
96 profile->GetExtensionProcessManager();
97 CHECK(process_manager);
98
99 // This can happen if somebody typos a chrome-extension:// URL.
100 const Extension* extension = service->GetExtensionByURL(site);
101 if (!extension)
102 return;
103
104 site_instance->GetProcess()->mark_is_extension_process();
105
[email protected]056ad2a2011-07-12 02:13:55106 // Register the association between extension and SiteInstance with
[email protected]c5dbef02011-05-13 05:06:09107 // ExtensionProcessManager.
[email protected]056ad2a2011-07-12 02:13:55108 // TODO(creis): Use this to replace SetInstalledAppForRenderer below.
109 process_manager->RegisterExtensionSiteInstance(site_instance->id(),
110 extension->id());
[email protected]c5dbef02011-05-13 05:06:09111
[email protected]80675fc2011-06-21 02:05:49112 if (extension->is_app()) {
113 render_view_host->Send(
114 new ExtensionMsg_ActivateApplication(extension->id()));
115 // Record which, if any, installed app is associated with this process.
116 // TODO(aa): Totally lame to store this state in a global map in extension
117 // service. Can we get it from EPM instead?
[email protected]c5dbef02011-05-13 05:06:09118 service->SetInstalledAppForRenderer(process->id(), extension);
[email protected]80675fc2011-06-21 02:05:49119 }
[email protected]c5dbef02011-05-13 05:06:09120
121 // Some extensions use chrome:// URLs.
122 Extension::Type type = extension->GetType();
123 if (type == Extension::TYPE_EXTENSION ||
124 type == Extension::TYPE_PACKAGED_APP) {
125 ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
126 process->id(), chrome::kChromeUIScheme);
127 }
128
129 // Enable extension bindings for the renderer. Currently only extensions,
130 // packaged apps, and hosted component apps use extension bindings.
131 if (type == Extension::TYPE_EXTENSION ||
[email protected]2333bf22011-05-19 02:16:51132 type == Extension::TYPE_USER_SCRIPT ||
[email protected]c5dbef02011-05-13 05:06:09133 type == Extension::TYPE_PACKAGED_APP ||
134 (type == Extension::TYPE_HOSTED_APP &&
135 extension->location() == Extension::COMPONENT)) {
136 render_view_host->Send(new ExtensionMsg_ActivateExtension(extension->id()));
137 render_view_host->AllowBindings(BindingsPolicy::EXTENSION);
138 }
139}
140
[email protected]b8148ac2011-07-13 22:03:25141// Handles rewriting Web UI URLs.
142static bool HandleWebUI(GURL* url, Profile* profile) {
143 if (!ChromeWebUIFactory::GetInstance()->UseWebUIForURL(profile, *url))
144 return false;
145
146 // Special case the new tab page. In older versions of Chrome, the new tab
147 // page was hosted at chrome-internal:<blah>. This might be in people's saved
148 // sessions or bookmarks, so we say any URL with that scheme triggers the new
149 // tab page.
150 if (url->SchemeIs(chrome::kChromeInternalScheme)) {
151 // Rewrite it with the proper new tab URL.
152 *url = GURL(chrome::kChromeUINewTabURL);
153 }
154
155 return true;
156}
157
[email protected]9dbfff12011-07-01 19:37:07158} // namespace
[email protected]c5dbef02011-05-13 05:06:09159
[email protected]d977f9c2011-03-14 16:10:26160namespace chrome {
161
[email protected]f364d1392011-04-08 21:03:10162void ChromeContentBrowserClient::RenderViewHostCreated(
163 RenderViewHost* render_view_host) {
[email protected]53a0afa2011-04-28 02:09:33164 new ChromeRenderViewHostObserver(render_view_host);
[email protected]f364d1392011-04-08 21:03:10165 new DevToolsHandler(render_view_host);
166 new ExtensionMessageHandler(render_view_host);
[email protected]f364d1392011-04-08 21:03:10167
[email protected]c5dbef02011-05-13 05:06:09168 InitRenderViewHostForExtensions(render_view_host);
[email protected]d977f9c2011-03-14 16:10:26169}
170
[email protected]05fcf982011-04-19 00:44:14171void ChromeContentBrowserClient::BrowserRenderProcessHostCreated(
172 BrowserRenderProcessHost* host) {
[email protected]c47cfd62011-04-29 21:27:02173 int id = host->id();
174 Profile* profile = host->profile();
[email protected]05fcf982011-04-19 00:44:14175 host->channel()->AddFilter(new ChromeRenderMessageFilter(
[email protected]c47cfd62011-04-29 21:27:02176 id, profile, profile->GetRequestContextForRenderProcess(id)));
[email protected]05fcf982011-04-19 00:44:14177 host->channel()->AddFilter(new PrintingMessageFilter());
178 host->channel()->AddFilter(
[email protected]c47cfd62011-04-29 21:27:02179 new SearchProviderInstallStateMessageFilter(id, profile));
180 host->channel()->AddFilter(new SpellCheckMessageFilter(id));
[email protected]d4cff272011-05-02 15:46:01181#if defined(OS_MACOSX)
182 host->channel()->AddFilter(new TextInputClientMessageFilter(host->id()));
183#endif
[email protected]3e69bc82011-05-26 23:22:38184
185 host->Send(new ViewMsg_SetIsIncognitoProcess(profile->IsOffTheRecord()));
[email protected]05fcf982011-04-19 00:44:14186}
187
[email protected]97e6c4c2011-05-18 16:08:51188void ChromeContentBrowserClient::PluginProcessHostCreated(
189 PluginProcessHost* host) {
190 host->AddFilter(new ChromePluginMessageFilter(host));
191}
192
[email protected]5327dfb2011-05-03 17:50:36193void ChromeContentBrowserClient::WorkerProcessHostCreated(
194 WorkerProcessHost* host) {
195 host->AddFilter(new ChromeWorkerMessageFilter(host));
196}
197
[email protected]1fd1a502011-03-30 16:55:56198content::WebUIFactory* ChromeContentBrowserClient::GetWebUIFactory() {
199 return ChromeWebUIFactory::GetInstance();
200}
201
[email protected]36fb2c7c2011-04-04 15:49:08202GURL ChromeContentBrowserClient::GetEffectiveURL(Profile* profile,
203 const GURL& url) {
204 // Get the effective URL for the given actual URL. If the URL is part of an
205 // installed app, the effective URL is an extension URL with the ID of that
206 // extension as the host. This has the effect of grouping apps together in
207 // a common SiteInstance.
208 if (!profile || !profile->GetExtensionService())
209 return url;
210
211 const Extension* extension =
212 profile->GetExtensionService()->GetExtensionByWebExtent(url);
213 if (!extension)
214 return url;
215
216 // If the URL is part of an extension's web extent, convert it to an
217 // extension URL.
218 return extension->GetResourceURL(url.path());
219}
220
[email protected]056ad2a2011-07-12 02:13:55221bool ChromeContentBrowserClient::ShouldUseProcessPerSite(
222 Profile* profile,
223 const GURL& effective_url) {
224 // Non-extension URLs should generally use process-per-site-instance.
225 // Because we expect to use the effective URL, hosted apps URLs should have
226 // an extension scheme by now.
227 if (!effective_url.SchemeIs(chrome::kExtensionScheme))
228 return false;
229
230 if (!profile || !profile->GetExtensionService())
231 return false;
232
233 const Extension* extension =
234 profile->GetExtensionService()->GetExtensionByURL(effective_url);
235 if (!extension)
236 return false;
237
238 // If the URL is part of a hosted app that does not have the background
239 // permission, we want to give each instance its own process to improve
240 // responsiveness.
241 if (extension->GetType() == Extension::TYPE_HOSTED_APP &&
242 !extension->HasAPIPermission(ExtensionAPIPermission::kBackground))
243 return false;
244
245 // Hosted apps that have the background permission must use process per site,
246 // since all instances can make synchronous calls to the background window.
247 // Other extensions should use process per site as well.
248 return true;
249}
250
[email protected]0f012df82011-05-19 14:15:29251bool ChromeContentBrowserClient::IsURLSameAsAnySiteInstance(const GURL& url) {
[email protected]89f550b2011-06-08 18:34:03252 return url == GURL(chrome::kChromeUICrashURL) ||
253 url == GURL(chrome::kChromeUIKillURL) ||
254 url == GURL(chrome::kChromeUIHangURL) ||
255 url == GURL(chrome::kChromeUIShorthangURL);
[email protected]0f012df82011-05-19 14:15:29256}
257
[email protected]763ec4ca2011-04-29 15:48:12258std::string ChromeContentBrowserClient::GetCanonicalEncodingNameByAliasName(
259 const std::string& alias_name) {
260 return CharacterEncoding::GetCanonicalEncodingNameByAliasName(alias_name);
261}
262
[email protected]b80f68432011-05-02 17:22:30263void ChromeContentBrowserClient::AppendExtraCommandLineSwitches(
264 CommandLine* command_line, int child_process_id) {
265#if defined(USE_LINUX_BREAKPAD)
266 if (IsCrashReporterEnabled()) {
267 command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
268 child_process_logging::GetClientId() + "," + base::GetLinuxDistro());
269 }
270#elif defined(OS_MACOSX)
271 if (IsCrashReporterEnabled()) {
272 command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
273 child_process_logging::GetClientId());
274 }
275#endif // OS_MACOSX
276
[email protected]f1933792011-06-14 00:49:34277 if (logging::DialogsAreSuppressed())
278 command_line->AppendSwitch(switches::kNoErrorDialogs);
279
[email protected]b80f68432011-05-02 17:22:30280 std::string process_type =
281 command_line->GetSwitchValueASCII(switches::kProcessType);
[email protected]3cb054e62011-06-13 05:21:17282 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
[email protected]b80f68432011-05-02 17:22:30283 if (process_type == switches::kExtensionProcess ||
284 process_type == switches::kRendererProcess) {
[email protected]b80f68432011-05-02 17:22:30285 FilePath user_data_dir =
286 browser_command_line.GetSwitchValuePath(switches::kUserDataDir);
287 if (!user_data_dir.empty())
288 command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir);
289#if defined(OS_CHROMEOS)
290 const std::string& login_profile =
291 browser_command_line.GetSwitchValueASCII(switches::kLoginProfile);
292 if (!login_profile.empty())
293 command_line->AppendSwitchASCII(switches::kLoginProfile, login_profile);
294#endif
295
296 RenderProcessHost* process = RenderProcessHost::FromID(child_process_id);
297
298 PrefService* prefs = process->profile()->GetPrefs();
299 // Currently this pref is only registered if applied via a policy.
300 if (prefs->HasPrefPath(prefs::kDisable3DAPIs) &&
301 prefs->GetBoolean(prefs::kDisable3DAPIs)) {
302 // Turn this policy into a command line switch.
303 command_line->AppendSwitch(switches::kDisable3DAPIs);
304 }
305
306 // Disable client-side phishing detection in the renderer if it is disabled
[email protected]8c40da62011-07-13 22:58:46307 // in the Profile preferences or the browser process.
308 if (!prefs->GetBoolean(prefs::kSafeBrowsingEnabled) ||
309 !g_browser_process->safe_browsing_detection_service()) {
[email protected]b80f68432011-05-02 17:22:30310 command_line->AppendSwitch(switches::kDisableClientSidePhishingDetection);
[email protected]8c40da62011-07-13 22:58:46311 }
[email protected]4287a3d2011-06-13 23:56:51312
313 static const char* const kSwitchNames[] = {
314 switches::kAllowHTTPBackgroundPage,
315 switches::kAllowScriptingGallery,
316 switches::kAppsCheckoutURL,
317 switches::kAppsGalleryURL,
[email protected]be9d9c82011-07-13 04:17:31318 switches::kCloudPrintServiceURL,
[email protected]4287a3d2011-06-13 23:56:51319 switches::kDebugPrint,
320#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
321 // Enabled by default in Google Chrome builds, except on CrOS.
322 switches::kDisablePrintPreview,
323#else
324 // Disabled by default in Chromium builds and on CrOS.
325 switches::kEnablePrintPreview,
326#endif
327 switches::kDomAutomationController,
328 switches::kDumpHistogramsOnExit,
329 switches::kEnableClickToPlay,
330 switches::kEnableCrxlessWebApps,
331 switches::kEnableExperimentalExtensionApis,
332 switches::kEnableInBrowserThumbnailing,
333 switches::kEnableIPCFuzzing,
334 switches::kEnableNaCl,
335 switches::kEnableRemoting,
336 switches::kEnableResourceContentSettings,
337 switches::kEnableSearchProviderApiV2,
338 switches::kEnableWatchdog,
339 switches::kExperimentalSpellcheckerFeatures,
340 switches::kMemoryProfiling,
341 switches::kMessageLoopHistogrammer,
342 switches::kPpapiFlashArgs,
343 switches::kPpapiFlashInProcess,
344 switches::kPpapiFlashPath,
345 switches::kPpapiFlashVersion,
346 switches::kProfilingAtStart,
347 switches::kProfilingFile,
348 switches::kProfilingFlush,
349 switches::kRemoteShellPort,
350 switches::kSilentDumpOnDCHECK,
351 };
352
353 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
354 arraysize(kSwitchNames));
[email protected]3cb054e62011-06-13 05:21:17355 } else if (process_type == switches::kUtilityProcess) {
356 if (browser_command_line.HasSwitch(
357 switches::kEnableExperimentalExtensionApis)) {
358 command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
359 }
[email protected]4287a3d2011-06-13 23:56:51360 } else if (process_type == switches::kPluginProcess) {
361 static const char* const kSwitchNames[] = {
362 #if defined(OS_CHROMEOS)
363 switches::kLoginProfile,
364 #endif
365 switches::kMemoryProfiling,
366 switches::kSilentDumpOnDCHECK,
367 switches::kUserDataDir,
368 };
369
370 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
371 arraysize(kSwitchNames));
372 } else if (process_type == switches::kZygoteProcess) {
373 static const char* const kSwitchNames[] = {
374 switches::kEnableRemoting,
375 switches::kUserDataDir, // Make logs go to the right file.
376 // Load (in-process) Pepper plugins in-process in the zygote pre-sandbox.
377 switches::kPpapiFlashInProcess,
378 switches::kPpapiFlashPath,
379 switches::kPpapiFlashVersion,
380 };
381
382 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
383 arraysize(kSwitchNames));
[email protected]b80f68432011-05-02 17:22:30384 }
385}
386
387std::string ChromeContentBrowserClient::GetApplicationLocale() {
388 return g_browser_process->GetApplicationLocale();
389}
390
[email protected]b5cca982011-05-26 04:42:08391std::string ChromeContentBrowserClient::GetAcceptLangs(const TabContents* tab) {
392 return tab->profile()->GetPrefs()->GetString(prefs::kAcceptLanguages);
393}
394
[email protected]ac55e292011-06-24 05:16:08395SkBitmap* ChromeContentBrowserClient::GetDefaultFavicon() {
396 ResourceBundle &rb = ResourceBundle::GetSharedInstance();
397 return rb.GetBitmapNamed(IDR_DEFAULT_FAVICON);
398}
399
[email protected]a2176792011-05-08 19:30:49400bool ChromeContentBrowserClient::AllowAppCache(
[email protected]5b52ad42011-05-26 14:26:09401 const GURL& manifest_url,
402 const content::ResourceContext& context) {
[email protected]8093a542011-05-13 07:29:32403 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
404 ProfileIOData* io_data =
405 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09406 // FIXME(jochen): get the correct top-level origin.
[email protected]efa55212011-05-13 16:19:38407 ContentSetting setting = io_data->GetHostContentSettingsMap()->
[email protected]5b52ad42011-05-26 14:26:09408 GetCookieContentSetting(manifest_url, manifest_url, true);
[email protected]a2176792011-05-08 19:30:49409 DCHECK(setting != CONTENT_SETTING_DEFAULT);
410 return setting != CONTENT_SETTING_BLOCK;
411}
412
[email protected]ed24fad2011-05-10 22:44:01413bool ChromeContentBrowserClient::AllowGetCookie(
414 const GURL& url,
415 const GURL& first_party,
416 const net::CookieList& cookie_list,
417 const content::ResourceContext& context,
418 int render_process_id,
419 int render_view_id) {
420 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]8093a542011-05-13 07:29:32421 ProfileIOData* io_data =
422 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09423 ContentSetting setting = io_data->GetHostContentSettingsMap()->
424 GetCookieContentSetting(url, first_party, false);
425 bool allow = setting == CONTENT_SETTING_ALLOW ||
426 setting == CONTENT_SETTING_SESSION_ONLY;
[email protected]ed24fad2011-05-10 22:44:01427
[email protected]8093a542011-05-13 07:29:32428 BrowserThread::PostTask(
429 BrowserThread::UI, FROM_HERE,
430 NewRunnableFunction(
431 &TabSpecificContentSettings::CookiesRead,
432 render_process_id, render_view_id, url, cookie_list, !allow));
[email protected]ed24fad2011-05-10 22:44:01433 return allow;
434}
435
436bool ChromeContentBrowserClient::AllowSetCookie(
437 const GURL& url,
438 const GURL& first_party,
439 const std::string& cookie_line,
440 const content::ResourceContext& context,
441 int render_process_id,
442 int render_view_id,
443 net::CookieOptions* options) {
444 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]8093a542011-05-13 07:29:32445 ProfileIOData* io_data =
446 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09447 ContentSetting setting = io_data->GetHostContentSettingsMap()->
448 GetCookieContentSetting(url, first_party, true);
[email protected]ed24fad2011-05-10 22:44:01449
[email protected]5b52ad42011-05-26 14:26:09450 if (setting == CONTENT_SETTING_SESSION_ONLY)
451 options->set_force_session();
[email protected]ed24fad2011-05-10 22:44:01452
[email protected]5b52ad42011-05-26 14:26:09453 bool allow = setting == CONTENT_SETTING_ALLOW ||
454 setting == CONTENT_SETTING_SESSION_ONLY;
[email protected]ed24fad2011-05-10 22:44:01455
[email protected]8093a542011-05-13 07:29:32456 BrowserThread::PostTask(
457 BrowserThread::UI, FROM_HERE,
458 NewRunnableFunction(
459 &TabSpecificContentSettings::CookieChanged,
460 render_process_id, render_view_id, url, cookie_line, *options,
461 !allow));
[email protected]ed24fad2011-05-10 22:44:01462 return allow;
463}
464
[email protected]d5a19162011-06-30 18:51:54465bool ChromeContentBrowserClient::AllowSaveLocalState(
466 const content::ResourceContext& context) {
467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
468 ProfileIOData* io_data =
469 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
470 return !io_data->clear_local_state_on_exit()->GetValue();
471}
472
[email protected]6133f922011-07-01 21:34:34473net::URLRequestContext*
474ChromeContentBrowserClient::OverrideRequestContextForURL(
475 const GURL& url, const content::ResourceContext& context) {
476 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
477 if (url.SchemeIs(chrome::kExtensionScheme)) {
478 ProfileIOData* io_data =
479 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
480 return io_data->extensions_request_context();
481 }
482
483 return NULL;
484}
485
[email protected]317f96c92011-05-31 06:53:41486QuotaPermissionContext*
487ChromeContentBrowserClient::CreateQuotaPermissionContext() {
488 return new ChromeQuotaPermissionContext();
489}
490
[email protected]0609b17f2011-05-31 20:13:42491void ChromeContentBrowserClient::RevealFolderInOS(const FilePath& path) {
492 // On Mac, this call needs to be done on the UI thread. On other platforms,
493 // do it on the FILE thread so we don't slow down UI.
494#if defined(OS_MACOSX)
495 platform_util::OpenItem(path);
496#else
497 BrowserThread::PostTask(
498 BrowserThread::FILE, FROM_HERE,
499 NewRunnableFunction(&platform_util::OpenItem, path));
500#endif
501}
502
[email protected]848dd042011-06-04 18:24:03503void ChromeContentBrowserClient::AllowCertificateError(
504 SSLCertErrorHandler* handler,
505 bool overridable,
506 Callback2<SSLCertErrorHandler*, bool>::Type* callback) {
507 SSLBlockingPage* blocking_page = new SSLBlockingPage(
508 handler, overridable, callback);
509 blocking_page->Show();
510}
511
[email protected]8ec26472011-06-06 16:52:45512void ChromeContentBrowserClient::ShowClientCertificateRequestDialog(
513 int render_process_id,
514 int render_view_id,
515 SSLClientAuthHandler* handler) {
516 TabContents* tab = tab_util::GetTabContentsByID(
517 render_process_id, render_view_id);
518 if (!tab) {
519 NOTREACHED();
520 return;
521 }
522
523 TabContentsWrapper* wrapper =
524 TabContentsWrapper::GetCurrentWrapperForContents(tab);
525 wrapper->ssl_helper()->ShowClientCertificateRequestDialog(handler);
526}
527
528void ChromeContentBrowserClient::AddNewCertificate(
529 net::URLRequest* request,
530 net::X509Certificate* cert,
531 int render_process_id,
532 int render_view_id) {
533 // The handler will run the UI and delete itself when it's finished.
534 new SSLAddCertHandler(request, cert, render_process_id, render_view_id);
535}
536
[email protected]941623e2011-06-07 23:06:04537void ChromeContentBrowserClient::RequestDesktopNotificationPermission(
538 const GURL& source_origin,
539 int callback_context,
540 int render_process_id,
541 int render_view_id) {
542 RenderViewHost* rvh = RenderViewHost::FromID(
543 render_process_id, render_view_id);
544 if (!rvh) {
545 NOTREACHED();
546 return;
547 }
548
549 RenderProcessHost* process = rvh->process();
550 DesktopNotificationService* service =
551 DesktopNotificationServiceFactory::GetForProfile(process->profile());
552 service->RequestPermission(
553 source_origin, render_process_id, render_view_id, callback_context,
554 tab_util::GetTabContentsByID(render_process_id, render_view_id));
555}
556
557WebKit::WebNotificationPresenter::Permission
558 ChromeContentBrowserClient::CheckDesktopNotificationPermission(
559 const GURL& source_url,
560 const content::ResourceContext& context) {
561 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
562 ProfileIOData* io_data =
563 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
564
565 const Extension* extension =
566 io_data->GetExtensionInfoMap()->extensions().GetByURL(source_url);
567 if (extension &&
[email protected]0d3e4a22011-06-23 19:02:52568 extension->HasAPIPermission(ExtensionAPIPermission::kNotification)) {
[email protected]941623e2011-06-07 23:06:04569 return WebKit::WebNotificationPresenter::PermissionAllowed;
570 }
571
572 // Fall back to the regular notification preferences, which works on an
573 // origin basis.
574 return io_data->GetNotificationService() ?
575 io_data->GetNotificationService()->HasPermission(source_url.GetOrigin()) :
576 WebKit::WebNotificationPresenter::PermissionNotAllowed;
577}
578
579void ChromeContentBrowserClient::ShowDesktopNotification(
580 const DesktopNotificationHostMsg_Show_Params& params,
581 int render_process_id,
582 int render_view_id,
583 bool worker) {
584 RenderViewHost* rvh = RenderViewHost::FromID(
585 render_process_id, render_view_id);
586 if (!rvh) {
587 NOTREACHED();
588 return;
589 }
590
591 RenderProcessHost* process = rvh->process();
592 DesktopNotificationService* service =
593 DesktopNotificationServiceFactory::GetForProfile(process->profile());
594 service->ShowDesktopNotification(
595 params, render_process_id, render_view_id,
596 worker ? DesktopNotificationService::WorkerNotification :
597 DesktopNotificationService::PageNotification);
598}
599
600void ChromeContentBrowserClient::CancelDesktopNotification(
601 int render_process_id,
602 int render_view_id,
603 int notification_id) {
604 RenderViewHost* rvh = RenderViewHost::FromID(
605 render_process_id, render_view_id);
606 if (!rvh) {
607 NOTREACHED();
608 return;
609 }
610
611 RenderProcessHost* process = rvh->process();
612 DesktopNotificationService* service =
613 DesktopNotificationServiceFactory::GetForProfile(process->profile());
614 service->CancelDesktopNotification(
615 render_process_id, render_view_id, notification_id);
616}
617
[email protected]9f3fba52011-06-08 20:37:19618bool ChromeContentBrowserClient::CanCreateWindow(
619 const GURL& source_url,
620 WindowContainerType container_type,
621 const content::ResourceContext& context) {
622 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
623 // If the opener is trying to create a background window but doesn't have
624 // the appropriate permission, fail the attempt.
625 if (container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) {
626 ProfileIOData* io_data =
627 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
628 const Extension* extension =
629 io_data->GetExtensionInfoMap()->extensions().GetByURL(source_url);
630 return (extension &&
[email protected]0d3e4a22011-06-23 19:02:52631 extension->HasAPIPermission(ExtensionAPIPermission::kBackground));
[email protected]9f3fba52011-06-08 20:37:19632 }
633 return true;
634}
635
636std::string ChromeContentBrowserClient::GetWorkerProcessTitle(
637 const GURL& url, const content::ResourceContext& context) {
638 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
639 // Check if it's an extension-created worker, in which case we want to use
640 // the name of the extension.
641 ProfileIOData* io_data =
642 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
643 const Extension* extension =
644 io_data->GetExtensionInfoMap()->extensions().GetByID(url.host());
645 return extension ? extension->name() : std::string();
646}
647
[email protected]3cb054e62011-06-13 05:21:17648ResourceDispatcherHost*
649 ChromeContentBrowserClient::GetResourceDispatcherHost() {
650 return g_browser_process->resource_dispatcher_host();
651}
652
653ui::Clipboard* ChromeContentBrowserClient::GetClipboard() {
654 return g_browser_process->clipboard();
655}
656
[email protected]dbae6b02011-06-29 23:51:41657bool ChromeContentBrowserClient::IsFastShutdownPossible() {
658 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
659 return !browser_command_line.HasSwitch(switches::kChromeFrame);
660}
661
[email protected]181a95ee2011-07-12 19:26:36662WebPreferences ChromeContentBrowserClient::GetWebkitPrefs(Profile* profile,
663 bool is_web_ui) {
664 return RenderViewHostDelegateHelper::GetWebkitPrefs(profile, is_web_ui);
665}
666
667void ChromeContentBrowserClient::UpdateInspectorSetting(
668 RenderViewHost* rvh, const std::string& key, const std::string& value) {
669 RenderViewHostDelegateHelper::UpdateInspectorSetting(
670 rvh->process()->profile(), key, value);
671}
672
673void ChromeContentBrowserClient::ClearInspectorSettings(RenderViewHost* rvh) {
674 RenderViewHostDelegateHelper::ClearInspectorSettings(
675 rvh->process()->profile());
676}
677
[email protected]b8148ac2011-07-13 22:03:25678void ChromeContentBrowserClient::BrowserURLHandlerCreated(
679 BrowserURLHandler* handler) {
680 // Add the default URL handlers.
681 handler->AddHandlerPair(&ExtensionWebUI::HandleChromeURLOverride,
682 BrowserURLHandler::null_handler());
683 handler->AddHandlerPair(BrowserURLHandler::null_handler(),
684 &ExtensionWebUI::HandleChromeURLOverrideReverse);
685
686 // about:
687 handler->AddHandlerPair(&WillHandleBrowserAboutURL,
688 BrowserURLHandler::null_handler());
689 // chrome: & friends.
690 handler->AddHandlerPair(&HandleWebUI,
691 BrowserURLHandler::null_handler());
692}
693
694void ChromeContentBrowserClient::ClearCache(RenderViewHost* rvh) {
695 Profile* profile = rvh->site_instance()->GetProcess()->profile();
696 BrowsingDataRemover* remover = new BrowsingDataRemover(profile,
697 BrowsingDataRemover::EVERYTHING,
698 base::Time());
699 remover->Remove(BrowsingDataRemover::REMOVE_CACHE);
700 // BrowsingDataRemover takes care of deleting itself when done.
701}
702
703void ChromeContentBrowserClient::ClearCookies(RenderViewHost* rvh) {
704 Profile* profile = rvh->site_instance()->GetProcess()->profile();
705 BrowsingDataRemover* remover = new BrowsingDataRemover(profile,
706 BrowsingDataRemover::EVERYTHING,
707 base::Time());
708 int remove_mask = BrowsingDataRemover::REMOVE_COOKIES;
709 remover->Remove(remove_mask);
710 // BrowsingDataRemover takes care of deleting itself when done.
711}
712
[email protected]b80f68432011-05-02 17:22:30713#if defined(OS_LINUX)
714int ChromeContentBrowserClient::GetCrashSignalFD(
715 const std::string& process_type) {
716 if (process_type == switches::kRendererProcess)
717 return RendererCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
718
[email protected]9dbfff12011-07-01 19:37:07719 if (process_type == switches::kExtensionProcess) {
720 ExtensionCrashHandlerHostLinux* crash_handler =
721 ExtensionCrashHandlerHostLinux::GetInstance();
722 return crash_handler->GetDeathSignalSocket();
723 }
724
[email protected]b80f68432011-05-02 17:22:30725 if (process_type == switches::kPluginProcess)
726 return PluginCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
727
728 if (process_type == switches::kPpapiPluginProcess)
729 return PpapiCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
730
731 if (process_type == switches::kGpuProcess)
732 return GpuCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
733
734 return -1;
735}
[email protected]9dbfff12011-07-01 19:37:07736#endif // defined(OS_LINUX)
[email protected]b80f68432011-05-02 17:22:30737
[email protected]37a72af2011-06-13 05:42:01738#if defined(USE_NSS)
739crypto::CryptoModuleBlockingPasswordDelegate*
740 ChromeContentBrowserClient::GetCryptoPasswordDelegate(
741 const GURL& url) {
742 return browser::NewCryptoModuleBlockingDialogDelegate(
743 browser::kCryptoModulePasswordKeygen, url.host());
744}
745#endif
746
[email protected]d977f9c2011-03-14 16:10:26747} // namespace chrome