blob: 51177de2836101e4988cd1dfe1ab79e1bad5cfb0 [file] [log] [blame]
[email protected]d977f9c2011-03-14 16:10:261// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/chrome_content_browser_client.h"
6
[email protected]b80f68432011-05-02 17:22:307#include "base/command_line.h"
8#include "chrome/app/breakpad_mac.h"
9#include "chrome/browser/browser_process.h"
[email protected]763ec4ca2011-04-29 15:48:1210#include "chrome/browser/character_encoding.h"
[email protected]97e6c4c2011-05-18 16:08:5111#include "chrome/browser/chrome_plugin_message_filter.h"
[email protected]317f96c92011-05-31 06:53:4112#include "chrome/browser/chrome_quota_permission_context.h"
[email protected]5327dfb2011-05-03 17:50:3613#include "chrome/browser/chrome_worker_message_filter.h"
[email protected]a2176792011-05-08 19:30:4914#include "chrome/browser/content_settings/host_content_settings_map.h"
[email protected]8093a542011-05-13 07:29:3215#include "chrome/browser/content_settings/tab_specific_content_settings.h"
[email protected]941623e2011-06-07 23:06:0416#include "chrome/browser/extensions/extension_info_map.h"
[email protected]f364d1392011-04-08 21:03:1017#include "chrome/browser/extensions/extension_message_handler.h"
[email protected]d977f9c2011-03-14 16:10:2618#include "chrome/browser/extensions/extension_service.h"
[email protected]763ec4ca2011-04-29 15:48:1219#include "chrome/browser/google/google_util.h"
[email protected]941623e2011-06-07 23:06:0420#include "chrome/browser/notifications/desktop_notification_service.h"
21#include "chrome/browser/notifications/desktop_notification_service_factory.h"
[email protected]0609b17f2011-05-31 20:13:4222#include "chrome/browser/platform_util.h"
[email protected]763ec4ca2011-04-29 15:48:1223#include "chrome/browser/prefs/pref_service.h"
[email protected]05fcf982011-04-19 00:44:1424#include "chrome/browser/printing/printing_message_filter.h"
25#include "chrome/browser/profiles/profile.h"
[email protected]8093a542011-05-13 07:29:3226#include "chrome/browser/profiles/profile_io_data.h"
[email protected]05fcf982011-04-19 00:44:1427#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
[email protected]53a0afa2011-04-28 02:09:3328#include "chrome/browser/renderer_host/chrome_render_view_host_observer.h"
[email protected]d4cff272011-05-02 15:46:0129#include "chrome/browser/renderer_host/text_input_client_message_filter.h"
[email protected]05fcf982011-04-19 00:44:1430#include "chrome/browser/search_engines/search_provider_install_state_message_filter.h"
31#include "chrome/browser/spellcheck_message_filter.h"
[email protected]8ec26472011-06-06 16:52:4532#include "chrome/browser/ssl/ssl_add_cert_handler.h"
[email protected]848dd042011-06-04 18:24:0333#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]8ec26472011-06-06 16:52:4534#include "chrome/browser/tab_contents/tab_contents_ssl_helper.h"
35#include "chrome/browser/tab_contents/tab_util.h"
36#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]1fd1a502011-03-30 16:55:5637#include "chrome/browser/ui/webui/chrome_web_ui_factory.h"
[email protected]b80f68432011-05-02 17:22:3038#include "chrome/common/child_process_logging.h"
39#include "chrome/common/chrome_switches.h"
[email protected]941623e2011-06-07 23:06:0440#include "chrome/common/extensions/extension.h"
[email protected]c5dbef02011-05-13 05:06:0941#include "chrome/common/extensions/extension_messages.h"
[email protected]f1933792011-06-14 00:49:3442#include "chrome/common/logging_chrome.h"
[email protected]763ec4ca2011-04-29 15:48:1243#include "chrome/common/pref_names.h"
[email protected]3e69bc82011-05-26 23:22:3844#include "chrome/common/render_messages.h"
[email protected]c5dbef02011-05-13 05:06:0945#include "chrome/common/url_constants.h"
46#include "content/browser/browsing_instance.h"
47#include "content/browser/child_process_security_policy.h"
[email protected]b46442d7e2011-06-29 02:16:0648#include "content/browser/debugger/devtools_handler.h"
[email protected]97e6c4c2011-05-18 16:08:5149#include "content/browser/plugin_process_host.h"
[email protected]05fcf982011-04-19 00:44:1450#include "content/browser/renderer_host/browser_render_process_host.h"
[email protected]d977f9c2011-03-14 16:10:2651#include "content/browser/renderer_host/render_view_host.h"
[email protected]a2176792011-05-08 19:30:4952#include "content/browser/resource_context.h"
[email protected]c5dbef02011-05-13 05:06:0953#include "content/browser/site_instance.h"
[email protected]8ec26472011-06-06 16:52:4554#include "content/browser/ssl/ssl_client_auth_handler.h"
[email protected]763ec4ca2011-04-29 15:48:1255#include "content/browser/tab_contents/tab_contents.h"
[email protected]5327dfb2011-05-03 17:50:3656#include "content/browser/worker_host/worker_process_host.h"
[email protected]c5dbef02011-05-13 05:06:0957#include "content/common/bindings_policy.h"
[email protected]941623e2011-06-07 23:06:0458#include "content/common/desktop_notification_messages.h"
[email protected]29b25d092011-06-29 20:57:3459#include "grit/ui_resources.h"
[email protected]ed24fad2011-05-10 22:44:0160#include "net/base/cookie_monster.h"
61#include "net/base/cookie_options.h"
[email protected]ac55e292011-06-24 05:16:0862#include "ui/base/resource/resource_bundle.h"
[email protected]d977f9c2011-03-14 16:10:2663
[email protected]b80f68432011-05-02 17:22:3064#if defined(OS_LINUX)
65#include "base/linux_util.h"
66#include "chrome/browser/crash_handler_host_linux.h"
[email protected]1fd5302c2011-05-28 04:06:4367#endif
[email protected]b80f68432011-05-02 17:22:3068
[email protected]37a72af2011-06-13 05:42:0169#if defined(USE_NSS)
70#include "chrome/browser/ui/crypto_module_password_dialog.h"
71#endif
72
[email protected]c5dbef02011-05-13 05:06:0973namespace {
74
75void InitRenderViewHostForExtensions(RenderViewHost* render_view_host) {
76 // Note that due to GetEffectiveURL(), even hosted apps will have a
77 // chrome-extension:// URL for their site, so we can ignore that wrinkle here.
78 SiteInstance* site_instance = render_view_host->site_instance();
79 const GURL& site = site_instance->site();
80 RenderProcessHost* process = render_view_host->process();
81
82 if (!site.SchemeIs(chrome::kExtensionScheme))
83 return;
84
85 Profile* profile = site_instance->browsing_instance()->profile();
86 ExtensionService* service = profile->GetExtensionService();
87 if (!service)
88 return;
89
90 ExtensionProcessManager* process_manager =
91 profile->GetExtensionProcessManager();
92 CHECK(process_manager);
93
94 // This can happen if somebody typos a chrome-extension:// URL.
95 const Extension* extension = service->GetExtensionByURL(site);
96 if (!extension)
97 return;
98
99 site_instance->GetProcess()->mark_is_extension_process();
100
[email protected]056ad2a2011-07-12 02:13:55101 // Register the association between extension and SiteInstance with
[email protected]c5dbef02011-05-13 05:06:09102 // ExtensionProcessManager.
[email protected]056ad2a2011-07-12 02:13:55103 // TODO(creis): Use this to replace SetInstalledAppForRenderer below.
104 process_manager->RegisterExtensionSiteInstance(site_instance->id(),
105 extension->id());
[email protected]c5dbef02011-05-13 05:06:09106
[email protected]80675fc2011-06-21 02:05:49107 if (extension->is_app()) {
108 render_view_host->Send(
109 new ExtensionMsg_ActivateApplication(extension->id()));
110 // Record which, if any, installed app is associated with this process.
111 // TODO(aa): Totally lame to store this state in a global map in extension
112 // service. Can we get it from EPM instead?
[email protected]c5dbef02011-05-13 05:06:09113 service->SetInstalledAppForRenderer(process->id(), extension);
[email protected]80675fc2011-06-21 02:05:49114 }
[email protected]c5dbef02011-05-13 05:06:09115
116 // Some extensions use chrome:// URLs.
117 Extension::Type type = extension->GetType();
118 if (type == Extension::TYPE_EXTENSION ||
119 type == Extension::TYPE_PACKAGED_APP) {
120 ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
121 process->id(), chrome::kChromeUIScheme);
122 }
123
124 // Enable extension bindings for the renderer. Currently only extensions,
125 // packaged apps, and hosted component apps use extension bindings.
126 if (type == Extension::TYPE_EXTENSION ||
[email protected]2333bf22011-05-19 02:16:51127 type == Extension::TYPE_USER_SCRIPT ||
[email protected]c5dbef02011-05-13 05:06:09128 type == Extension::TYPE_PACKAGED_APP ||
129 (type == Extension::TYPE_HOSTED_APP &&
130 extension->location() == Extension::COMPONENT)) {
131 render_view_host->Send(new ExtensionMsg_ActivateExtension(extension->id()));
132 render_view_host->AllowBindings(BindingsPolicy::EXTENSION);
133 }
134}
135
[email protected]9dbfff12011-07-01 19:37:07136} // namespace
[email protected]c5dbef02011-05-13 05:06:09137
[email protected]d977f9c2011-03-14 16:10:26138namespace chrome {
139
[email protected]f364d1392011-04-08 21:03:10140void ChromeContentBrowserClient::RenderViewHostCreated(
141 RenderViewHost* render_view_host) {
[email protected]53a0afa2011-04-28 02:09:33142 new ChromeRenderViewHostObserver(render_view_host);
[email protected]f364d1392011-04-08 21:03:10143 new DevToolsHandler(render_view_host);
144 new ExtensionMessageHandler(render_view_host);
[email protected]f364d1392011-04-08 21:03:10145
[email protected]c5dbef02011-05-13 05:06:09146 InitRenderViewHostForExtensions(render_view_host);
[email protected]d977f9c2011-03-14 16:10:26147}
148
[email protected]05fcf982011-04-19 00:44:14149void ChromeContentBrowserClient::BrowserRenderProcessHostCreated(
150 BrowserRenderProcessHost* host) {
[email protected]c47cfd62011-04-29 21:27:02151 int id = host->id();
152 Profile* profile = host->profile();
[email protected]05fcf982011-04-19 00:44:14153 host->channel()->AddFilter(new ChromeRenderMessageFilter(
[email protected]c47cfd62011-04-29 21:27:02154 id, profile, profile->GetRequestContextForRenderProcess(id)));
[email protected]05fcf982011-04-19 00:44:14155 host->channel()->AddFilter(new PrintingMessageFilter());
156 host->channel()->AddFilter(
[email protected]c47cfd62011-04-29 21:27:02157 new SearchProviderInstallStateMessageFilter(id, profile));
158 host->channel()->AddFilter(new SpellCheckMessageFilter(id));
[email protected]d4cff272011-05-02 15:46:01159#if defined(OS_MACOSX)
160 host->channel()->AddFilter(new TextInputClientMessageFilter(host->id()));
161#endif
[email protected]3e69bc82011-05-26 23:22:38162
163 host->Send(new ViewMsg_SetIsIncognitoProcess(profile->IsOffTheRecord()));
[email protected]05fcf982011-04-19 00:44:14164}
165
[email protected]97e6c4c2011-05-18 16:08:51166void ChromeContentBrowserClient::PluginProcessHostCreated(
167 PluginProcessHost* host) {
168 host->AddFilter(new ChromePluginMessageFilter(host));
169}
170
[email protected]5327dfb2011-05-03 17:50:36171void ChromeContentBrowserClient::WorkerProcessHostCreated(
172 WorkerProcessHost* host) {
173 host->AddFilter(new ChromeWorkerMessageFilter(host));
174}
175
[email protected]1fd1a502011-03-30 16:55:56176content::WebUIFactory* ChromeContentBrowserClient::GetWebUIFactory() {
177 return ChromeWebUIFactory::GetInstance();
178}
179
[email protected]36fb2c7c2011-04-04 15:49:08180GURL ChromeContentBrowserClient::GetEffectiveURL(Profile* profile,
181 const GURL& url) {
182 // Get the effective URL for the given actual URL. If the URL is part of an
183 // installed app, the effective URL is an extension URL with the ID of that
184 // extension as the host. This has the effect of grouping apps together in
185 // a common SiteInstance.
186 if (!profile || !profile->GetExtensionService())
187 return url;
188
189 const Extension* extension =
190 profile->GetExtensionService()->GetExtensionByWebExtent(url);
191 if (!extension)
192 return url;
193
194 // If the URL is part of an extension's web extent, convert it to an
195 // extension URL.
196 return extension->GetResourceURL(url.path());
197}
198
[email protected]056ad2a2011-07-12 02:13:55199bool ChromeContentBrowserClient::ShouldUseProcessPerSite(
200 Profile* profile,
201 const GURL& effective_url) {
202 // Non-extension URLs should generally use process-per-site-instance.
203 // Because we expect to use the effective URL, hosted apps URLs should have
204 // an extension scheme by now.
205 if (!effective_url.SchemeIs(chrome::kExtensionScheme))
206 return false;
207
208 if (!profile || !profile->GetExtensionService())
209 return false;
210
211 const Extension* extension =
212 profile->GetExtensionService()->GetExtensionByURL(effective_url);
213 if (!extension)
214 return false;
215
216 // If the URL is part of a hosted app that does not have the background
217 // permission, we want to give each instance its own process to improve
218 // responsiveness.
219 if (extension->GetType() == Extension::TYPE_HOSTED_APP &&
220 !extension->HasAPIPermission(ExtensionAPIPermission::kBackground))
221 return false;
222
223 // Hosted apps that have the background permission must use process per site,
224 // since all instances can make synchronous calls to the background window.
225 // Other extensions should use process per site as well.
226 return true;
227}
228
[email protected]0f012df82011-05-19 14:15:29229bool ChromeContentBrowserClient::IsURLSameAsAnySiteInstance(const GURL& url) {
[email protected]89f550b2011-06-08 18:34:03230 return url == GURL(chrome::kChromeUICrashURL) ||
231 url == GURL(chrome::kChromeUIKillURL) ||
232 url == GURL(chrome::kChromeUIHangURL) ||
233 url == GURL(chrome::kChromeUIShorthangURL);
[email protected]0f012df82011-05-19 14:15:29234}
235
[email protected]763ec4ca2011-04-29 15:48:12236std::string ChromeContentBrowserClient::GetCanonicalEncodingNameByAliasName(
237 const std::string& alias_name) {
238 return CharacterEncoding::GetCanonicalEncodingNameByAliasName(alias_name);
239}
240
[email protected]b80f68432011-05-02 17:22:30241void ChromeContentBrowserClient::AppendExtraCommandLineSwitches(
242 CommandLine* command_line, int child_process_id) {
243#if defined(USE_LINUX_BREAKPAD)
244 if (IsCrashReporterEnabled()) {
245 command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
246 child_process_logging::GetClientId() + "," + base::GetLinuxDistro());
247 }
248#elif defined(OS_MACOSX)
249 if (IsCrashReporterEnabled()) {
250 command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
251 child_process_logging::GetClientId());
252 }
253#endif // OS_MACOSX
254
[email protected]f1933792011-06-14 00:49:34255 if (logging::DialogsAreSuppressed())
256 command_line->AppendSwitch(switches::kNoErrorDialogs);
257
[email protected]b80f68432011-05-02 17:22:30258 std::string process_type =
259 command_line->GetSwitchValueASCII(switches::kProcessType);
[email protected]3cb054e62011-06-13 05:21:17260 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
[email protected]b80f68432011-05-02 17:22:30261 if (process_type == switches::kExtensionProcess ||
262 process_type == switches::kRendererProcess) {
[email protected]b80f68432011-05-02 17:22:30263 FilePath user_data_dir =
264 browser_command_line.GetSwitchValuePath(switches::kUserDataDir);
265 if (!user_data_dir.empty())
266 command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir);
267#if defined(OS_CHROMEOS)
268 const std::string& login_profile =
269 browser_command_line.GetSwitchValueASCII(switches::kLoginProfile);
270 if (!login_profile.empty())
271 command_line->AppendSwitchASCII(switches::kLoginProfile, login_profile);
272#endif
273
274 RenderProcessHost* process = RenderProcessHost::FromID(child_process_id);
275
276 PrefService* prefs = process->profile()->GetPrefs();
277 // Currently this pref is only registered if applied via a policy.
278 if (prefs->HasPrefPath(prefs::kDisable3DAPIs) &&
279 prefs->GetBoolean(prefs::kDisable3DAPIs)) {
280 // Turn this policy into a command line switch.
281 command_line->AppendSwitch(switches::kDisable3DAPIs);
282 }
283
284 // Disable client-side phishing detection in the renderer if it is disabled
285 // in the browser process.
286 if (!g_browser_process->safe_browsing_detection_service())
287 command_line->AppendSwitch(switches::kDisableClientSidePhishingDetection);
[email protected]4287a3d2011-06-13 23:56:51288
289 static const char* const kSwitchNames[] = {
290 switches::kAllowHTTPBackgroundPage,
291 switches::kAllowScriptingGallery,
292 switches::kAppsCheckoutURL,
293 switches::kAppsGalleryURL,
294 switches::kDebugPrint,
295#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
296 // Enabled by default in Google Chrome builds, except on CrOS.
297 switches::kDisablePrintPreview,
298#else
299 // Disabled by default in Chromium builds and on CrOS.
300 switches::kEnablePrintPreview,
301#endif
302 switches::kDomAutomationController,
303 switches::kDumpHistogramsOnExit,
304 switches::kEnableClickToPlay,
305 switches::kEnableCrxlessWebApps,
306 switches::kEnableExperimentalExtensionApis,
307 switches::kEnableInBrowserThumbnailing,
308 switches::kEnableIPCFuzzing,
309 switches::kEnableNaCl,
310 switches::kEnableRemoting,
311 switches::kEnableResourceContentSettings,
312 switches::kEnableSearchProviderApiV2,
313 switches::kEnableWatchdog,
314 switches::kExperimentalSpellcheckerFeatures,
315 switches::kMemoryProfiling,
316 switches::kMessageLoopHistogrammer,
317 switches::kPpapiFlashArgs,
318 switches::kPpapiFlashInProcess,
319 switches::kPpapiFlashPath,
320 switches::kPpapiFlashVersion,
321 switches::kProfilingAtStart,
322 switches::kProfilingFile,
323 switches::kProfilingFlush,
324 switches::kRemoteShellPort,
325 switches::kSilentDumpOnDCHECK,
326 };
327
328 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
329 arraysize(kSwitchNames));
[email protected]3cb054e62011-06-13 05:21:17330 } else if (process_type == switches::kUtilityProcess) {
331 if (browser_command_line.HasSwitch(
332 switches::kEnableExperimentalExtensionApis)) {
333 command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
334 }
[email protected]4287a3d2011-06-13 23:56:51335 } else if (process_type == switches::kPluginProcess) {
336 static const char* const kSwitchNames[] = {
337 #if defined(OS_CHROMEOS)
338 switches::kLoginProfile,
339 #endif
340 switches::kMemoryProfiling,
341 switches::kSilentDumpOnDCHECK,
342 switches::kUserDataDir,
343 };
344
345 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
346 arraysize(kSwitchNames));
347 } else if (process_type == switches::kZygoteProcess) {
348 static const char* const kSwitchNames[] = {
349 switches::kEnableRemoting,
350 switches::kUserDataDir, // Make logs go to the right file.
351 // Load (in-process) Pepper plugins in-process in the zygote pre-sandbox.
352 switches::kPpapiFlashInProcess,
353 switches::kPpapiFlashPath,
354 switches::kPpapiFlashVersion,
355 };
356
357 command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
358 arraysize(kSwitchNames));
[email protected]b80f68432011-05-02 17:22:30359 }
360}
361
362std::string ChromeContentBrowserClient::GetApplicationLocale() {
363 return g_browser_process->GetApplicationLocale();
364}
365
[email protected]b5cca982011-05-26 04:42:08366std::string ChromeContentBrowserClient::GetAcceptLangs(const TabContents* tab) {
367 return tab->profile()->GetPrefs()->GetString(prefs::kAcceptLanguages);
368}
369
[email protected]ac55e292011-06-24 05:16:08370SkBitmap* ChromeContentBrowserClient::GetDefaultFavicon() {
371 ResourceBundle &rb = ResourceBundle::GetSharedInstance();
372 return rb.GetBitmapNamed(IDR_DEFAULT_FAVICON);
373}
374
[email protected]a2176792011-05-08 19:30:49375bool ChromeContentBrowserClient::AllowAppCache(
[email protected]5b52ad42011-05-26 14:26:09376 const GURL& manifest_url,
377 const content::ResourceContext& context) {
[email protected]8093a542011-05-13 07:29:32378 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
379 ProfileIOData* io_data =
380 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09381 // FIXME(jochen): get the correct top-level origin.
[email protected]efa55212011-05-13 16:19:38382 ContentSetting setting = io_data->GetHostContentSettingsMap()->
[email protected]5b52ad42011-05-26 14:26:09383 GetCookieContentSetting(manifest_url, manifest_url, true);
[email protected]a2176792011-05-08 19:30:49384 DCHECK(setting != CONTENT_SETTING_DEFAULT);
385 return setting != CONTENT_SETTING_BLOCK;
386}
387
[email protected]ed24fad2011-05-10 22:44:01388bool ChromeContentBrowserClient::AllowGetCookie(
389 const GURL& url,
390 const GURL& first_party,
391 const net::CookieList& cookie_list,
392 const content::ResourceContext& context,
393 int render_process_id,
394 int render_view_id) {
395 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]8093a542011-05-13 07:29:32396 ProfileIOData* io_data =
397 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09398 ContentSetting setting = io_data->GetHostContentSettingsMap()->
399 GetCookieContentSetting(url, first_party, false);
400 bool allow = setting == CONTENT_SETTING_ALLOW ||
401 setting == CONTENT_SETTING_SESSION_ONLY;
[email protected]ed24fad2011-05-10 22:44:01402
[email protected]8093a542011-05-13 07:29:32403 BrowserThread::PostTask(
404 BrowserThread::UI, FROM_HERE,
405 NewRunnableFunction(
406 &TabSpecificContentSettings::CookiesRead,
407 render_process_id, render_view_id, url, cookie_list, !allow));
[email protected]ed24fad2011-05-10 22:44:01408 return allow;
409}
410
411bool ChromeContentBrowserClient::AllowSetCookie(
412 const GURL& url,
413 const GURL& first_party,
414 const std::string& cookie_line,
415 const content::ResourceContext& context,
416 int render_process_id,
417 int render_view_id,
418 net::CookieOptions* options) {
419 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]8093a542011-05-13 07:29:32420 ProfileIOData* io_data =
421 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
[email protected]5b52ad42011-05-26 14:26:09422 ContentSetting setting = io_data->GetHostContentSettingsMap()->
423 GetCookieContentSetting(url, first_party, true);
[email protected]ed24fad2011-05-10 22:44:01424
[email protected]5b52ad42011-05-26 14:26:09425 if (setting == CONTENT_SETTING_SESSION_ONLY)
426 options->set_force_session();
[email protected]ed24fad2011-05-10 22:44:01427
[email protected]5b52ad42011-05-26 14:26:09428 bool allow = setting == CONTENT_SETTING_ALLOW ||
429 setting == CONTENT_SETTING_SESSION_ONLY;
[email protected]ed24fad2011-05-10 22:44:01430
[email protected]8093a542011-05-13 07:29:32431 BrowserThread::PostTask(
432 BrowserThread::UI, FROM_HERE,
433 NewRunnableFunction(
434 &TabSpecificContentSettings::CookieChanged,
435 render_process_id, render_view_id, url, cookie_line, *options,
436 !allow));
[email protected]ed24fad2011-05-10 22:44:01437 return allow;
438}
439
[email protected]d5a19162011-06-30 18:51:54440bool ChromeContentBrowserClient::AllowSaveLocalState(
441 const content::ResourceContext& context) {
442 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
443 ProfileIOData* io_data =
444 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
445 return !io_data->clear_local_state_on_exit()->GetValue();
446}
447
[email protected]6133f922011-07-01 21:34:34448net::URLRequestContext*
449ChromeContentBrowserClient::OverrideRequestContextForURL(
450 const GURL& url, const content::ResourceContext& context) {
451 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
452 if (url.SchemeIs(chrome::kExtensionScheme)) {
453 ProfileIOData* io_data =
454 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
455 return io_data->extensions_request_context();
456 }
457
458 return NULL;
459}
460
[email protected]317f96c92011-05-31 06:53:41461QuotaPermissionContext*
462ChromeContentBrowserClient::CreateQuotaPermissionContext() {
463 return new ChromeQuotaPermissionContext();
464}
465
[email protected]0609b17f2011-05-31 20:13:42466void ChromeContentBrowserClient::RevealFolderInOS(const FilePath& path) {
467 // On Mac, this call needs to be done on the UI thread. On other platforms,
468 // do it on the FILE thread so we don't slow down UI.
469#if defined(OS_MACOSX)
470 platform_util::OpenItem(path);
471#else
472 BrowserThread::PostTask(
473 BrowserThread::FILE, FROM_HERE,
474 NewRunnableFunction(&platform_util::OpenItem, path));
475#endif
476}
477
[email protected]848dd042011-06-04 18:24:03478void ChromeContentBrowserClient::AllowCertificateError(
479 SSLCertErrorHandler* handler,
480 bool overridable,
481 Callback2<SSLCertErrorHandler*, bool>::Type* callback) {
482 SSLBlockingPage* blocking_page = new SSLBlockingPage(
483 handler, overridable, callback);
484 blocking_page->Show();
485}
486
[email protected]8ec26472011-06-06 16:52:45487void ChromeContentBrowserClient::ShowClientCertificateRequestDialog(
488 int render_process_id,
489 int render_view_id,
490 SSLClientAuthHandler* handler) {
491 TabContents* tab = tab_util::GetTabContentsByID(
492 render_process_id, render_view_id);
493 if (!tab) {
494 NOTREACHED();
495 return;
496 }
497
498 TabContentsWrapper* wrapper =
499 TabContentsWrapper::GetCurrentWrapperForContents(tab);
500 wrapper->ssl_helper()->ShowClientCertificateRequestDialog(handler);
501}
502
503void ChromeContentBrowserClient::AddNewCertificate(
504 net::URLRequest* request,
505 net::X509Certificate* cert,
506 int render_process_id,
507 int render_view_id) {
508 // The handler will run the UI and delete itself when it's finished.
509 new SSLAddCertHandler(request, cert, render_process_id, render_view_id);
510}
511
[email protected]941623e2011-06-07 23:06:04512void ChromeContentBrowserClient::RequestDesktopNotificationPermission(
513 const GURL& source_origin,
514 int callback_context,
515 int render_process_id,
516 int render_view_id) {
517 RenderViewHost* rvh = RenderViewHost::FromID(
518 render_process_id, render_view_id);
519 if (!rvh) {
520 NOTREACHED();
521 return;
522 }
523
524 RenderProcessHost* process = rvh->process();
525 DesktopNotificationService* service =
526 DesktopNotificationServiceFactory::GetForProfile(process->profile());
527 service->RequestPermission(
528 source_origin, render_process_id, render_view_id, callback_context,
529 tab_util::GetTabContentsByID(render_process_id, render_view_id));
530}
531
532WebKit::WebNotificationPresenter::Permission
533 ChromeContentBrowserClient::CheckDesktopNotificationPermission(
534 const GURL& source_url,
535 const content::ResourceContext& context) {
536 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
537 ProfileIOData* io_data =
538 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
539
540 const Extension* extension =
541 io_data->GetExtensionInfoMap()->extensions().GetByURL(source_url);
542 if (extension &&
[email protected]0d3e4a22011-06-23 19:02:52543 extension->HasAPIPermission(ExtensionAPIPermission::kNotification)) {
[email protected]941623e2011-06-07 23:06:04544 return WebKit::WebNotificationPresenter::PermissionAllowed;
545 }
546
547 // Fall back to the regular notification preferences, which works on an
548 // origin basis.
549 return io_data->GetNotificationService() ?
550 io_data->GetNotificationService()->HasPermission(source_url.GetOrigin()) :
551 WebKit::WebNotificationPresenter::PermissionNotAllowed;
552}
553
554void ChromeContentBrowserClient::ShowDesktopNotification(
555 const DesktopNotificationHostMsg_Show_Params& params,
556 int render_process_id,
557 int render_view_id,
558 bool worker) {
559 RenderViewHost* rvh = RenderViewHost::FromID(
560 render_process_id, render_view_id);
561 if (!rvh) {
562 NOTREACHED();
563 return;
564 }
565
566 RenderProcessHost* process = rvh->process();
567 DesktopNotificationService* service =
568 DesktopNotificationServiceFactory::GetForProfile(process->profile());
569 service->ShowDesktopNotification(
570 params, render_process_id, render_view_id,
571 worker ? DesktopNotificationService::WorkerNotification :
572 DesktopNotificationService::PageNotification);
573}
574
575void ChromeContentBrowserClient::CancelDesktopNotification(
576 int render_process_id,
577 int render_view_id,
578 int notification_id) {
579 RenderViewHost* rvh = RenderViewHost::FromID(
580 render_process_id, render_view_id);
581 if (!rvh) {
582 NOTREACHED();
583 return;
584 }
585
586 RenderProcessHost* process = rvh->process();
587 DesktopNotificationService* service =
588 DesktopNotificationServiceFactory::GetForProfile(process->profile());
589 service->CancelDesktopNotification(
590 render_process_id, render_view_id, notification_id);
591}
592
[email protected]9f3fba52011-06-08 20:37:19593bool ChromeContentBrowserClient::CanCreateWindow(
594 const GURL& source_url,
595 WindowContainerType container_type,
596 const content::ResourceContext& context) {
597 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
598 // If the opener is trying to create a background window but doesn't have
599 // the appropriate permission, fail the attempt.
600 if (container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) {
601 ProfileIOData* io_data =
602 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
603 const Extension* extension =
604 io_data->GetExtensionInfoMap()->extensions().GetByURL(source_url);
605 return (extension &&
[email protected]0d3e4a22011-06-23 19:02:52606 extension->HasAPIPermission(ExtensionAPIPermission::kBackground));
[email protected]9f3fba52011-06-08 20:37:19607 }
608 return true;
609}
610
611std::string ChromeContentBrowserClient::GetWorkerProcessTitle(
612 const GURL& url, const content::ResourceContext& context) {
613 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
614 // Check if it's an extension-created worker, in which case we want to use
615 // the name of the extension.
616 ProfileIOData* io_data =
617 reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL));
618 const Extension* extension =
619 io_data->GetExtensionInfoMap()->extensions().GetByID(url.host());
620 return extension ? extension->name() : std::string();
621}
622
[email protected]3cb054e62011-06-13 05:21:17623ResourceDispatcherHost*
624 ChromeContentBrowserClient::GetResourceDispatcherHost() {
625 return g_browser_process->resource_dispatcher_host();
626}
627
628ui::Clipboard* ChromeContentBrowserClient::GetClipboard() {
629 return g_browser_process->clipboard();
630}
631
[email protected]dbae6b02011-06-29 23:51:41632bool ChromeContentBrowserClient::IsFastShutdownPossible() {
633 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
634 return !browser_command_line.HasSwitch(switches::kChromeFrame);
635}
636
[email protected]b80f68432011-05-02 17:22:30637#if defined(OS_LINUX)
638int ChromeContentBrowserClient::GetCrashSignalFD(
639 const std::string& process_type) {
640 if (process_type == switches::kRendererProcess)
641 return RendererCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
642
[email protected]9dbfff12011-07-01 19:37:07643 if (process_type == switches::kExtensionProcess) {
644 ExtensionCrashHandlerHostLinux* crash_handler =
645 ExtensionCrashHandlerHostLinux::GetInstance();
646 return crash_handler->GetDeathSignalSocket();
647 }
648
[email protected]b80f68432011-05-02 17:22:30649 if (process_type == switches::kPluginProcess)
650 return PluginCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
651
652 if (process_type == switches::kPpapiPluginProcess)
653 return PpapiCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
654
655 if (process_type == switches::kGpuProcess)
656 return GpuCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
657
658 return -1;
659}
[email protected]9dbfff12011-07-01 19:37:07660#endif // defined(OS_LINUX)
[email protected]b80f68432011-05-02 17:22:30661
[email protected]37a72af2011-06-13 05:42:01662#if defined(USE_NSS)
663crypto::CryptoModuleBlockingPasswordDelegate*
664 ChromeContentBrowserClient::GetCryptoPasswordDelegate(
665 const GURL& url) {
666 return browser::NewCryptoModuleBlockingDialogDelegate(
667 browser::kCryptoModulePasswordKeygen, url.host());
668}
669#endif
670
[email protected]d977f9c2011-03-14 16:10:26671} // namespace chrome