blob: 402b298074ddf28f340098fc966652dd4a5e075d [file] [log] [blame]
[email protected]de7d61ff2013-08-20 11:30:411// Copyright 2013 The Chromium Authors. All rights reserved.
[email protected]5629e0c2011-09-12 22:07:362// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]de7d61ff2013-08-20 11:30:415#include "content/shell/browser/shell_content_browser_client.h"
[email protected]5629e0c2011-09-12 22:07:366
avi66a07722015-12-25 23:38:127#include <stddef.h>
dchengf63a1252015-12-26 20:43:138#include <utility>
avi66a07722015-12-25 23:38:129
[email protected]d6d06a352013-10-23 07:04:0010#include "base/base_switches.h"
[email protected]74830f02012-01-30 22:27:0411#include "base/command_line.h"
[email protected]0daaebfe2014-03-15 00:09:0512#include "base/files/file.h"
thestigb7aad54f2014-09-05 18:25:3913#include "base/files/file_util.h"
ben6c7a8a72016-09-30 18:35:2114#include "base/json/json_reader.h"
avi66a07722015-12-25 23:38:1215#include "base/macros.h"
[email protected]53d96fb2012-11-27 15:36:2716#include "base/path_service.h"
nickd4106442015-12-08 21:53:1117#include "base/strings/pattern.h"
[email protected]a553b672014-04-16 05:40:4118#include "base/strings/utf_string_conversions.h"
avi66a07722015-12-25 23:38:1219#include "build/build_config.h"
davidben3b8455ae72015-03-11 19:42:1920#include "content/public/browser/client_certificate_delegate.h"
mlamourieb40d552015-02-05 00:57:0821#include "content/public/browser/page_navigator.h"
[email protected]53d96fb2012-11-27 15:36:2722#include "content/public/browser/render_process_host.h"
[email protected]e3503ac2012-04-05 15:01:3623#include "content/public/browser/resource_dispatcher_host.h"
[email protected]833b700d2013-02-18 19:43:0024#include "content/public/browser/storage_partition.h"
[email protected]7b38b192013-03-23 18:39:3125#include "content/public/common/content_switches.h"
ben51bb6c62016-11-17 20:15:5726#include "content/public/common/service_names.mojom.h"
[email protected]e0f35c92013-05-08 16:04:3427#include "content/public/common/url_constants.h"
[email protected]b3a97b52014-07-09 06:25:0528#include "content/public/common/web_preferences.h"
benff461632016-10-06 14:27:3329#include "content/public/test/test_service.h"
[email protected]de7d61ff2013-08-20 11:30:4130#include "content/shell/browser/shell.h"
31#include "content/shell/browser/shell_browser_context.h"
32#include "content/shell/browser/shell_browser_main_parts.h"
vkuzkokovcbabd582014-11-06 13:53:5433#include "content/shell/browser/shell_devtools_manager_delegate.h"
[email protected]de7d61ff2013-08-20 11:30:4134#include "content/shell/browser/shell_net_log.h"
35#include "content/shell/browser/shell_quota_permission_context.h"
36#include "content/shell/browser/shell_resource_dispatcher_host_delegate.h"
37#include "content/shell/browser/shell_web_contents_view_delegate_creator.h"
[email protected]b7c504c2013-05-07 14:42:1238#include "content/shell/common/shell_messages.h"
39#include "content/shell/common/shell_switches.h"
ben6c7a8a72016-09-30 18:35:2140#include "grit/shell_resources.h"
[email protected]e3c4d5272013-07-17 11:14:0141#include "net/url_request/url_request_context_getter.h"
ben6c7a8a72016-09-30 18:35:2142#include "ui/base/resource/resource_bundle.h"
[email protected]707e1c42013-07-09 21:18:5843#include "url/gurl.h"
nickd4106442015-12-08 21:53:1144#include "url/origin.h"
[email protected]5629e0c2011-09-12 22:07:3645
[email protected]f83a47392012-07-12 22:15:0446#if defined(OS_ANDROID)
agrieve05398f52015-06-24 18:59:0047#include "base/android/apk_assets.h"
[email protected]f83a47392012-07-12 22:15:0448#include "base/android/path_utils.h"
sdefresne8ba0b88c2015-09-18 10:33:1349#include "components/crash/content/browser/crash_dump_manager_android.h"
[email protected]f83a47392012-07-12 22:15:0450#include "content/shell/android/shell_descriptors.h"
51#endif
52
[email protected]a7aa8ab2013-10-24 07:21:4853#if defined(OS_POSIX) && !defined(OS_MACOSX)
54#include "base/debug/leak_annotations.h"
sdefresne8ba0b88c2015-09-18 10:33:1355#include "components/crash/content/app/breakpad_linux.h"
56#include "components/crash/content/browser/crash_handler_host_linux.h"
[email protected]a7aa8ab2013-10-24 07:21:4857#include "content/public/common/content_descriptors.h"
58#endif
59
[email protected]a553b672014-04-16 05:40:4160#if defined(OS_WIN)
61#include "content/common/sandbox_win.h"
62#include "sandbox/win/src/sandbox.h"
63#endif
64
alokpaa2fdfb72016-02-03 22:55:5465#if defined(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS)
xhwangb1d65fd2016-10-19 20:55:5266#include "media/mojo/services/media_service_factory.h" // nogncheck
alokpaa2fdfb72016-02-03 22:55:5467#endif
68
bend9063072016-11-12 01:32:5169#if defined(USE_AURA)
70#include "services/navigation/navigation.h"
71#endif
72
[email protected]5629e0c2011-09-12 22:07:3673namespace content {
74
[email protected]53d96fb2012-11-27 15:36:2775namespace {
76
[email protected]eabbfb12013-04-05 23:28:3577ShellContentBrowserClient* g_browser_client;
[email protected]fbaccee2013-08-12 23:24:0278bool g_swap_processes_for_redirect = false;
[email protected]eabbfb12013-04-05 23:28:3579
[email protected]1d51882f2013-11-12 01:59:0280#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
[email protected]a7aa8ab2013-10-24 07:21:4881breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost(
82 const std::string& process_type) {
83 base::FilePath dumps_path =
avi83883c82014-12-23 00:08:4984 base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
[email protected]a7aa8ab2013-10-24 07:21:4885 switches::kCrashDumpsDir);
86 {
87 ANNOTATE_SCOPED_MEMORY_LEAK;
88 breakpad::CrashHandlerHostLinux* crash_handler =
89 new breakpad::CrashHandlerHostLinux(
90 process_type, dumps_path, false);
91 crash_handler->StartUploaderThread();
92 return crash_handler;
93 }
94}
95
avi83883c82014-12-23 00:08:4996int GetCrashSignalFD(const base::CommandLine& command_line) {
[email protected]a7aa8ab2013-10-24 07:21:4897 if (!breakpad::IsCrashReporterEnabled())
98 return -1;
99
100 std::string process_type =
101 command_line.GetSwitchValueASCII(switches::kProcessType);
102
103 if (process_type == switches::kRendererProcess) {
104 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
105 if (!crash_handler)
106 crash_handler = CreateCrashHandlerHost(process_type);
107 return crash_handler->GetDeathSignalSocket();
108 }
109
[email protected]a7aa8ab2013-10-24 07:21:48110 if (process_type == switches::kPpapiPluginProcess) {
111 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
112 if (!crash_handler)
113 crash_handler = CreateCrashHandlerHost(process_type);
114 return crash_handler->GetDeathSignalSocket();
115 }
116
117 if (process_type == switches::kGpuProcess) {
118 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
119 if (!crash_handler)
120 crash_handler = CreateCrashHandlerHost(process_type);
121 return crash_handler->GetDeathSignalSocket();
122 }
123
124 return -1;
125}
[email protected]1d51882f2013-11-12 01:59:02126#endif // defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
[email protected]a7aa8ab2013-10-24 07:21:48127
[email protected]53d96fb2012-11-27 15:36:27128} // namespace
129
[email protected]eabbfb12013-04-05 23:28:35130ShellContentBrowserClient* ShellContentBrowserClient::Get() {
131 return g_browser_client;
132}
133
[email protected]fbaccee2013-08-12 23:24:02134void ShellContentBrowserClient::SetSwapProcessesForRedirect(bool swap) {
135 g_swap_processes_for_redirect = swap;
136}
137
[email protected]b0f146f2011-09-15 22:14:25138ShellContentBrowserClient::ShellContentBrowserClient()
agrievefd2d44ab2015-06-19 04:33:03139 : shell_browser_main_parts_(NULL) {
[email protected]eabbfb12013-04-05 23:28:35140 DCHECK(!g_browser_client);
141 g_browser_client = this;
[email protected]b0f146f2011-09-15 22:14:25142}
143
[email protected]5629e0c2011-09-12 22:07:36144ShellContentBrowserClient::~ShellContentBrowserClient() {
[email protected]eabbfb12013-04-05 23:28:35145 g_browser_client = NULL;
[email protected]5629e0c2011-09-12 22:07:36146}
147
[email protected]50462bf02011-11-21 19:13:31148BrowserMainParts* ShellContentBrowserClient::CreateBrowserMainParts(
[email protected]bdcf9152012-07-19 17:43:21149 const MainFunctionParams& parameters) {
jochen5ce1af92016-02-17 20:39:45150 shell_browser_main_parts_ = new ShellBrowserMainParts(parameters);
[email protected]078822c1b2012-04-07 23:16:12151 return shell_browser_main_parts_;
[email protected]5629e0c2011-09-12 22:07:36152}
153
nickd4106442015-12-08 21:53:11154bool ShellContentBrowserClient::DoesSiteRequireDedicatedProcess(
155 BrowserContext* browser_context,
nickdb193a12016-09-09 23:09:23156 const GURL& effective_site_url) {
nickd4106442015-12-08 21:53:11157 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
158 DCHECK(command_line->HasSwitch(switches::kIsolateSitesForTesting));
159 std::string pattern =
160 command_line->GetSwitchValueASCII(switches::kIsolateSitesForTesting);
nickfd25e832016-11-08 22:18:27161
nickdb193a12016-09-09 23:09:23162 url::Origin origin(effective_site_url);
163
nickfd25e832016-11-08 22:18:27164 if (!origin.unique()) {
165 // Schemes like blob or filesystem, which have an embedded origin, should
166 // already have been canonicalized to the origin site.
167 CHECK_EQ(origin.scheme(), effective_site_url.scheme())
168 << "a site url should have the same scheme as its origin.";
169 }
nickdb193a12016-09-09 23:09:23170
171 // Practically |origin.Serialize()| is the same as
172 // |effective_site_url.spec()|, except Origin serialization strips the
173 // trailing "/", which makes for cleaner wildcard patterns.
174 return base::MatchPattern(origin.Serialize(), pattern);
nickd4106442015-12-08 21:53:11175}
176
[email protected]e0f35c92013-05-08 16:04:34177bool ShellContentBrowserClient::IsHandledURL(const GURL& url) {
178 if (!url.is_valid())
179 return false;
[email protected]e0f35c92013-05-08 16:04:34180 // Keep in sync with ProtocolHandlers added by
181 // ShellURLRequestContextGetter::GetURLRequestContext().
182 static const char* const kProtocolList[] = {
[email protected]cca6f392014-05-28 21:32:26183 url::kBlobScheme,
184 url::kFileSystemScheme,
[email protected]2d9748b22014-02-11 00:17:29185 kChromeUIScheme,
[email protected]b3690f72014-02-17 00:32:48186 kChromeDevToolsScheme,
[email protected]cca6f392014-05-28 21:32:26187 url::kDataScheme,
188 url::kFileScheme,
[email protected]e0f35c92013-05-08 16:04:34189 };
190 for (size_t i = 0; i < arraysize(kProtocolList); ++i) {
191 if (url.scheme() == kProtocolList[i])
192 return true;
193 }
194 return false;
195}
196
bend32292b2016-10-07 00:21:58197void ShellContentBrowserClient::RegisterInProcessServices(
198 StaticServiceMap* services) {
alokp6ecb2382016-01-27 00:40:00199#if (ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS)
bend9063072016-11-12 01:32:51200 {
201 content::ServiceInfo info;
202 info.factory = base::Bind(&media::CreateMediaServiceForTesting);
ben72b077632016-11-16 00:23:53203 services->insert(std::make_pair("media", info));
bend9063072016-11-12 01:32:51204 }
205#endif
206#if defined(USE_AURA)
207 {
208 content::ServiceInfo info;
209 info.factory = base::Bind(&navigation::CreateNavigationService);
ben72b077632016-11-16 00:23:53210 services->insert(std::make_pair("navigation", info));
bend9063072016-11-12 01:32:51211 }
alokp6ecb2382016-01-27 00:40:00212#endif
213}
214
bend32292b2016-10-07 00:21:58215void ShellContentBrowserClient::RegisterOutOfProcessServices(
216 OutOfProcessServiceMap* services) {
217 services->insert(std::make_pair(kTestServiceUrl,
218 base::UTF8ToUTF16("Test Service")));
rockot4252ddfd2015-09-01 19:44:55219}
220
ben6c7a8a72016-09-30 18:35:21221std::unique_ptr<base::Value>
sammc2b0375b2016-12-22 01:26:17222ShellContentBrowserClient::GetServiceManifestOverlay(base::StringPiece name) {
ben6c7a8a72016-09-30 18:35:21223 int id = -1;
ben51bb6c62016-11-17 20:15:57224 if (name == content::mojom::kBrowserServiceName)
ben6c7a8a72016-09-30 18:35:21225 id = IDR_CONTENT_SHELL_BROWSER_MANIFEST_OVERLAY;
ben51bb6c62016-11-17 20:15:57226 else if (name == content::mojom::kRendererServiceName)
ben6c7a8a72016-09-30 18:35:21227 id = IDR_CONTENT_SHELL_RENDERER_MANIFEST_OVERLAY;
ben51bb6c62016-11-17 20:15:57228 else if (name == content::mojom::kUtilityServiceName)
ben6c7a8a72016-09-30 18:35:21229 id = IDR_CONTENT_SHELL_UTILITY_MANIFEST_OVERLAY;
230 if (id == -1)
231 return nullptr;
232
233 base::StringPiece manifest_contents =
234 ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale(
235 id, ui::ScaleFactor::SCALE_FACTOR_NONE);
236 return base::JSONReader::Read(manifest_contents);
237}
238
erikcorryc94eff12015-06-08 11:29:16239void ShellContentBrowserClient::AppendExtraCommandLineSwitches(
240 base::CommandLine* command_line,
241 int child_process_id) {
avi83883c82014-12-23 00:08:49242 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
lukasza756abda2016-03-15 21:58:50243 switches::kExposeInternalsForTesting)) {
244 command_line->AppendSwitch(switches::kExposeInternalsForTesting);
245 }
246 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]d6d06a352013-10-23 07:04:00247 switches::kEnableCrashReporter)) {
248 command_line->AppendSwitch(switches::kEnableCrashReporter);
249 }
avi83883c82014-12-23 00:08:49250 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
251 switches::kCrashDumpsDir)) {
[email protected]a7aa8ab2013-10-24 07:21:48252 command_line->AppendSwitchPath(
253 switches::kCrashDumpsDir,
avi83883c82014-12-23 00:08:49254 base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
[email protected]a7aa8ab2013-10-24 07:21:48255 switches::kCrashDumpsDir));
256 }
avi83883c82014-12-23 00:08:49257 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
nickd4106442015-12-08 21:53:11258 switches::kIsolateSitesForTesting)) {
259 command_line->AppendSwitchASCII(
260 switches::kIsolateSitesForTesting,
261 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
262 switches::kIsolateSitesForTesting));
263 }
264 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
avi83883c82014-12-23 00:08:49265 switches::kRegisterFontFiles)) {
[email protected]a553b672014-04-16 05:40:41266 command_line->AppendSwitchASCII(
267 switches::kRegisterFontFiles,
avi83883c82014-12-23 00:08:49268 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
[email protected]a553b672014-04-16 05:40:41269 switches::kRegisterFontFiles));
270 }
[email protected]5629e0c2011-09-12 22:07:36271}
272
[email protected]99907362012-01-11 05:41:40273void ShellContentBrowserClient::ResourceDispatcherHostCreated() {
[email protected]e3503ac2012-04-05 15:01:36274 resource_dispatcher_host_delegate_.reset(
jochen5ce1af92016-02-17 20:39:45275 new ShellResourceDispatcherHostDelegate);
[email protected]e3503ac2012-04-05 15:01:36276 ResourceDispatcherHost::Get()->SetDelegate(
277 resource_dispatcher_host_delegate_.get());
[email protected]5629e0c2011-09-12 22:07:36278}
279
[email protected]c9b6eb62011-10-18 20:49:39280std::string ShellContentBrowserClient::GetDefaultDownloadName() {
281 return "download";
282}
283
[email protected]4c2aa392012-09-03 01:29:42284WebContentsViewDelegate* ShellContentBrowserClient::GetWebContentsViewDelegate(
285 WebContents* web_contents) {
[email protected]4c2aa392012-09-03 01:29:42286 return CreateShellWebContentsViewDelegate(web_contents);
[email protected]4c2aa392012-09-03 01:29:42287}
288
[email protected]fc41b212013-03-25 16:04:23289QuotaPermissionContext*
290ShellContentBrowserClient::CreateQuotaPermissionContext() {
291 return new ShellQuotaPermissionContext();
292}
293
davidben3b8455ae72015-03-11 19:42:19294void ShellContentBrowserClient::SelectClientCertificate(
295 WebContents* web_contents,
296 net::SSLCertRequestInfo* cert_request_info,
dcheng6003e0b2016-04-09 18:42:34297 std::unique_ptr<ClientCertificateDelegate> delegate) {
davidben3b8455ae72015-03-11 19:42:19298 if (!select_client_certificate_callback_.is_null())
299 select_client_certificate_callback_.Run();
300}
301
[email protected]9896c552013-08-29 19:03:20302SpeechRecognitionManagerDelegate*
zorkb548de082014-11-14 21:40:47303 ShellContentBrowserClient::CreateSpeechRecognitionManagerDelegate() {
[email protected]9896c552013-08-29 19:03:20304 return new ShellSpeechRecognitionManagerDelegate();
305}
306
[email protected]d5869bf2013-07-03 16:21:47307net::NetLog* ShellContentBrowserClient::GetNetLog() {
308 return shell_browser_main_parts_->net_log();
309}
310
[email protected]fbaccee2013-08-12 23:24:02311bool ShellContentBrowserClient::ShouldSwapProcessesForRedirect(
clamyd69748c2016-10-07 22:09:44312 BrowserContext* browser_context,
[email protected]fbaccee2013-08-12 23:24:02313 const GURL& current_url,
314 const GURL& new_url) {
315 return g_swap_processes_for_redirect;
316}
317
dgozman252e18d2014-09-22 12:40:06318DevToolsManagerDelegate*
319ShellContentBrowserClient::GetDevToolsManagerDelegate() {
Pavel Feldman43f56b7c2016-08-30 00:04:35320 return new ShellDevToolsManagerDelegate(browser_context());
dgozman252e18d2014-09-22 12:40:06321}
322
peterbbcccc12015-02-11 22:23:33323void ShellContentBrowserClient::OpenURL(
324 BrowserContext* browser_context,
325 const OpenURLParams& params,
326 const base::Callback<void(WebContents*)>& callback) {
327 callback.Run(Shell::CreateNewWindow(browser_context,
328 params.url,
329 nullptr,
330 gfx::Size())->web_contents());
mlamourieb40d552015-02-05 00:57:08331}
332
agrieve05398f52015-06-24 18:59:00333#if defined(OS_ANDROID)
[email protected]f83a47392012-07-12 22:15:04334void ShellContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
avi83883c82014-12-23 00:08:49335 const base::CommandLine& command_line,
[email protected]12c779c2012-10-25 09:39:57336 int child_process_id,
agrieve05398f52015-06-24 18:59:00337 content::FileDescriptorInfo* mappings,
338 std::map<int, base::MemoryMappedFile::Region>* regions) {
339 mappings->Share(
340 kShellPakDescriptor,
341 base::GlobalDescriptors::GetInstance()->Get(kShellPakDescriptor));
342 regions->insert(std::make_pair(
343 kShellPakDescriptor,
344 base::GlobalDescriptors::GetInstance()->GetRegion(kShellPakDescriptor)));
boliuf4d9dc02016-09-02 03:24:04345
346 if (breakpad::IsCrashReporterEnabled()) {
347 base::File f(breakpad::CrashDumpManager::GetInstance()->CreateMinidumpFile(
348 child_process_id));
349 if (!f.IsValid()) {
350 LOG(ERROR) << "Failed to create file for minidump, crash reporting will "
351 << "be disabled for this process.";
352 } else {
353 mappings->Transfer(kAndroidMinidumpDescriptor,
354 base::ScopedFD(f.TakePlatformFile()));
355 }
356 }
agrieve05398f52015-06-24 18:59:00357}
358#elif defined(OS_POSIX) && !defined(OS_MACOSX)
359void ShellContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
360 const base::CommandLine& command_line,
361 int child_process_id,
362 content::FileDescriptorInfo* mappings) {
[email protected]a7aa8ab2013-10-24 07:21:48363 int crash_signal_fd = GetCrashSignalFD(command_line);
364 if (crash_signal_fd >= 0) {
morritad95714f2014-10-01 02:37:24365 mappings->Share(kCrashDumpSignal, crash_signal_fd);
[email protected]a7aa8ab2013-10-24 07:21:48366 }
[email protected]f83a47392012-07-12 22:15:04367}
agrieve05398f52015-06-24 18:59:00368#endif // defined(OS_ANDROID)
[email protected]f83a47392012-07-12 22:15:04369
[email protected]a553b672014-04-16 05:40:41370#if defined(OS_WIN)
rickyz50109312015-11-11 00:37:08371bool ShellContentBrowserClient::PreSpawnRenderer(
372 sandbox::TargetPolicy* policy) {
[email protected]a553b672014-04-16 05:40:41373 // Add sideloaded font files for testing. See also DIR_WINDOWS_FONTS
374 // addition in |StartSandboxedProcess|.
jamdaca82e2015-09-02 06:51:25375 std::vector<std::string> font_files = switches::GetSideloadFontFiles();
[email protected]a553b672014-04-16 05:40:41376 for (std::vector<std::string>::const_iterator i(font_files.begin());
377 i != font_files.end();
378 ++i) {
379 policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
380 sandbox::TargetPolicy::FILES_ALLOW_READONLY,
381 base::UTF8ToWide(*i).c_str());
382 }
rickyz50109312015-11-11 00:37:08383 return true;
[email protected]a553b672014-04-16 05:40:41384}
385#endif // OS_WIN
386
[email protected]147f8092012-03-21 11:47:45387ShellBrowserContext* ShellContentBrowserClient::browser_context() {
[email protected]3560b572012-04-04 20:47:32388 return shell_browser_main_parts_->browser_context();
[email protected]147f8092012-03-21 11:47:45389}
390
[email protected]71d504f2012-07-25 17:15:28391ShellBrowserContext*
392 ShellContentBrowserClient::off_the_record_browser_context() {
393 return shell_browser_main_parts_->off_the_record_browser_context();
394}
395
[email protected]5629e0c2011-09-12 22:07:36396} // namespace content