Convert browser_tests to Swarming.
[chromium-blink-merge.git] / content / shell / browser / shell_content_browser_client.cc
bloba48c00860c012a8160aa7b6bf96f4b328775b684
1 // Copyright 2013 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.
5 #include "content/shell/browser/shell_content_browser_client.h"
7 #include "base/base_switches.h"
8 #include "base/command_line.h"
9 #include "base/files/file.h"
10 #include "base/files/file_util.h"
11 #include "base/path_service.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "content/public/browser/client_certificate_delegate.h"
14 #include "content/public/browser/page_navigator.h"
15 #include "content/public/browser/render_process_host.h"
16 #include "content/public/browser/resource_dispatcher_host.h"
17 #include "content/public/browser/storage_partition.h"
18 #include "content/public/common/content_switches.h"
19 #include "content/public/common/url_constants.h"
20 #include "content/public/common/web_preferences.h"
21 #include "content/shell/browser/blink_test_controller.h"
22 #include "content/shell/browser/ipc_echo_message_filter.h"
23 #include "content/shell/browser/layout_test/layout_test_browser_main_parts.h"
24 #include "content/shell/browser/layout_test/layout_test_resource_dispatcher_host_delegate.h"
25 #include "content/shell/browser/shell.h"
26 #include "content/shell/browser/shell_access_token_store.h"
27 #include "content/shell/browser/shell_browser_context.h"
28 #include "content/shell/browser/shell_browser_main_parts.h"
29 #include "content/shell/browser/shell_devtools_manager_delegate.h"
30 #include "content/shell/browser/shell_net_log.h"
31 #include "content/shell/browser/shell_quota_permission_context.h"
32 #include "content/shell/browser/shell_resource_dispatcher_host_delegate.h"
33 #include "content/shell/browser/shell_web_contents_view_delegate_creator.h"
34 #include "content/shell/common/shell_messages.h"
35 #include "content/shell/common/shell_switches.h"
36 #include "content/shell/renderer/layout_test/blink_test_helpers.h"
37 #include "net/url_request/url_request_context_getter.h"
38 #include "url/gurl.h"
40 #if defined(OS_ANDROID)
41 #include "base/android/path_utils.h"
42 #include "components/crash/browser/crash_dump_manager_android.h"
43 #include "content/shell/android/shell_descriptors.h"
44 #endif
46 #if defined(OS_POSIX) && !defined(OS_MACOSX)
47 #include "base/debug/leak_annotations.h"
48 #include "components/crash/app/breakpad_linux.h"
49 #include "components/crash/browser/crash_handler_host_linux.h"
50 #include "content/public/common/content_descriptors.h"
51 #endif
53 #if defined(OS_WIN)
54 #include "content/common/sandbox_win.h"
55 #include "sandbox/win/src/sandbox.h"
56 #endif
58 namespace content {
60 namespace {
62 ShellContentBrowserClient* g_browser_client;
63 bool g_swap_processes_for_redirect = false;
65 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
66 breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost(
67 const std::string& process_type) {
68 base::FilePath dumps_path =
69 base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
70 switches::kCrashDumpsDir);
72 ANNOTATE_SCOPED_MEMORY_LEAK;
73 breakpad::CrashHandlerHostLinux* crash_handler =
74 new breakpad::CrashHandlerHostLinux(
75 process_type, dumps_path, false);
76 crash_handler->StartUploaderThread();
77 return crash_handler;
81 int GetCrashSignalFD(const base::CommandLine& command_line) {
82 if (!breakpad::IsCrashReporterEnabled())
83 return -1;
85 std::string process_type =
86 command_line.GetSwitchValueASCII(switches::kProcessType);
88 if (process_type == switches::kRendererProcess) {
89 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
90 if (!crash_handler)
91 crash_handler = CreateCrashHandlerHost(process_type);
92 return crash_handler->GetDeathSignalSocket();
95 if (process_type == switches::kPluginProcess) {
96 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
97 if (!crash_handler)
98 crash_handler = CreateCrashHandlerHost(process_type);
99 return crash_handler->GetDeathSignalSocket();
102 if (process_type == switches::kPpapiPluginProcess) {
103 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
104 if (!crash_handler)
105 crash_handler = CreateCrashHandlerHost(process_type);
106 return crash_handler->GetDeathSignalSocket();
109 if (process_type == switches::kGpuProcess) {
110 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
111 if (!crash_handler)
112 crash_handler = CreateCrashHandlerHost(process_type);
113 return crash_handler->GetDeathSignalSocket();
116 return -1;
118 #endif // defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
120 } // namespace
122 ShellContentBrowserClient* ShellContentBrowserClient::Get() {
123 return g_browser_client;
126 void ShellContentBrowserClient::SetSwapProcessesForRedirect(bool swap) {
127 g_swap_processes_for_redirect = swap;
130 ShellContentBrowserClient::ShellContentBrowserClient()
131 : shell_browser_main_parts_(NULL) {
132 DCHECK(!g_browser_client);
133 g_browser_client = this;
136 ShellContentBrowserClient::~ShellContentBrowserClient() {
137 g_browser_client = NULL;
140 BrowserMainParts* ShellContentBrowserClient::CreateBrowserMainParts(
141 const MainFunctionParams& parameters) {
142 shell_browser_main_parts_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
143 switches::kRunLayoutTest)
144 ? new LayoutTestBrowserMainParts(parameters)
145 : new ShellBrowserMainParts(parameters);
146 return shell_browser_main_parts_;
149 void ShellContentBrowserClient::RenderProcessWillLaunch(
150 RenderProcessHost* host) {
151 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
152 switches::kExposeIpcEcho))
153 host->AddFilter(new IPCEchoMessageFilter());
156 net::URLRequestContextGetter* ShellContentBrowserClient::CreateRequestContext(
157 BrowserContext* content_browser_context,
158 ProtocolHandlerMap* protocol_handlers,
159 URLRequestInterceptorScopedVector request_interceptors) {
160 ShellBrowserContext* shell_browser_context =
161 ShellBrowserContextForBrowserContext(content_browser_context);
162 return shell_browser_context->CreateRequestContext(
163 protocol_handlers, request_interceptors.Pass());
166 net::URLRequestContextGetter*
167 ShellContentBrowserClient::CreateRequestContextForStoragePartition(
168 BrowserContext* content_browser_context,
169 const base::FilePath& partition_path,
170 bool in_memory,
171 ProtocolHandlerMap* protocol_handlers,
172 URLRequestInterceptorScopedVector request_interceptors) {
173 ShellBrowserContext* shell_browser_context =
174 ShellBrowserContextForBrowserContext(content_browser_context);
175 return shell_browser_context->CreateRequestContextForStoragePartition(
176 partition_path,
177 in_memory,
178 protocol_handlers,
179 request_interceptors.Pass());
182 bool ShellContentBrowserClient::IsHandledURL(const GURL& url) {
183 if (!url.is_valid())
184 return false;
185 DCHECK_EQ(url.scheme(), base::StringToLowerASCII(url.scheme()));
186 // Keep in sync with ProtocolHandlers added by
187 // ShellURLRequestContextGetter::GetURLRequestContext().
188 static const char* const kProtocolList[] = {
189 url::kBlobScheme,
190 url::kFileSystemScheme,
191 kChromeUIScheme,
192 kChromeDevToolsScheme,
193 url::kDataScheme,
194 url::kFileScheme,
196 for (size_t i = 0; i < arraysize(kProtocolList); ++i) {
197 if (url.scheme() == kProtocolList[i])
198 return true;
200 return false;
203 void ShellContentBrowserClient::AppendExtraCommandLineSwitches(
204 base::CommandLine* command_line,
205 int child_process_id) {
206 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
207 switches::kRunLayoutTest)) {
208 command_line->AppendSwitch(switches::kRunLayoutTest);
210 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
211 switches::kDumpLineBoxTrees)) {
212 command_line->AppendSwitch(switches::kDumpLineBoxTrees);
214 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
215 switches::kEnableFontAntialiasing)) {
216 command_line->AppendSwitch(switches::kEnableFontAntialiasing);
218 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
219 switches::kExposeInternalsForTesting)) {
220 command_line->AppendSwitch(switches::kExposeInternalsForTesting);
222 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
223 switches::kExposeIpcEcho)) {
224 command_line->AppendSwitch(switches::kExposeIpcEcho);
226 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
227 switches::kStableReleaseMode)) {
228 command_line->AppendSwitch(switches::kStableReleaseMode);
230 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
231 switches::kEnableCrashReporter)) {
232 command_line->AppendSwitch(switches::kEnableCrashReporter);
234 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
235 switches::kCrashDumpsDir)) {
236 command_line->AppendSwitchPath(
237 switches::kCrashDumpsDir,
238 base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
239 switches::kCrashDumpsDir));
241 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
242 switches::kEnableLeakDetection)) {
243 command_line->AppendSwitchASCII(
244 switches::kEnableLeakDetection,
245 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
246 switches::kEnableLeakDetection));
248 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
249 switches::kRegisterFontFiles)) {
250 command_line->AppendSwitchASCII(
251 switches::kRegisterFontFiles,
252 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
253 switches::kRegisterFontFiles));
257 void ShellContentBrowserClient::OverrideWebkitPrefs(
258 RenderViewHost* render_view_host,
259 WebPreferences* prefs) {
260 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
261 switches::kRunLayoutTest))
262 return;
263 BlinkTestController::Get()->OverrideWebkitPrefs(prefs);
266 void ShellContentBrowserClient::ResourceDispatcherHostCreated() {
267 resource_dispatcher_host_delegate_.reset(
268 base::CommandLine::ForCurrentProcess()->HasSwitch(
269 switches::kRunLayoutTest)
270 ? new LayoutTestResourceDispatcherHostDelegate
271 : new ShellResourceDispatcherHostDelegate);
272 ResourceDispatcherHost::Get()->SetDelegate(
273 resource_dispatcher_host_delegate_.get());
276 std::string ShellContentBrowserClient::GetDefaultDownloadName() {
277 return "download";
280 WebContentsViewDelegate* ShellContentBrowserClient::GetWebContentsViewDelegate(
281 WebContents* web_contents) {
282 #if !defined(USE_AURA)
283 return CreateShellWebContentsViewDelegate(web_contents);
284 #else
285 return NULL;
286 #endif
289 QuotaPermissionContext*
290 ShellContentBrowserClient::CreateQuotaPermissionContext() {
291 return new ShellQuotaPermissionContext();
294 void ShellContentBrowserClient::SelectClientCertificate(
295 WebContents* web_contents,
296 net::SSLCertRequestInfo* cert_request_info,
297 scoped_ptr<ClientCertificateDelegate> delegate) {
298 if (!select_client_certificate_callback_.is_null())
299 select_client_certificate_callback_.Run();
302 SpeechRecognitionManagerDelegate*
303 ShellContentBrowserClient::CreateSpeechRecognitionManagerDelegate() {
304 return new ShellSpeechRecognitionManagerDelegate();
307 net::NetLog* ShellContentBrowserClient::GetNetLog() {
308 return shell_browser_main_parts_->net_log();
311 bool ShellContentBrowserClient::ShouldSwapProcessesForRedirect(
312 ResourceContext* resource_context,
313 const GURL& current_url,
314 const GURL& new_url) {
315 return g_swap_processes_for_redirect;
318 DevToolsManagerDelegate*
319 ShellContentBrowserClient::GetDevToolsManagerDelegate() {
320 return new ShellDevToolsManagerDelegate(browser_context());
323 void 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());
333 #if defined(OS_POSIX) && !defined(OS_MACOSX)
334 void ShellContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
335 const base::CommandLine& command_line,
336 int child_process_id,
337 FileDescriptorInfo* mappings) {
338 #if defined(OS_ANDROID)
339 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
340 base::FilePath pak_file;
341 bool r = PathService::Get(base::DIR_ANDROID_APP_DATA, &pak_file);
342 CHECK(r);
343 pak_file = pak_file.Append(FILE_PATH_LITERAL("paks"));
344 pak_file = pak_file.Append(FILE_PATH_LITERAL("content_shell.pak"));
346 base::File f(pak_file, flags);
347 if (!f.IsValid()) {
348 NOTREACHED() << "Failed to open file when creating renderer process: "
349 << "content_shell.pak";
352 mappings->Transfer(kShellPakDescriptor, base::ScopedFD(f.TakePlatformFile()));
354 if (breakpad::IsCrashReporterEnabled()) {
355 f = breakpad::CrashDumpManager::GetInstance()->CreateMinidumpFile(
356 child_process_id);
357 if (!f.IsValid()) {
358 LOG(ERROR) << "Failed to create file for minidump, crash reporting will "
359 << "be disabled for this process.";
360 } else {
361 mappings->Transfer(kAndroidMinidumpDescriptor,
362 base::ScopedFD(f.TakePlatformFile()));
365 #else // !defined(OS_ANDROID)
366 int crash_signal_fd = GetCrashSignalFD(command_line);
367 if (crash_signal_fd >= 0) {
368 mappings->Share(kCrashDumpSignal, crash_signal_fd);
370 #endif // defined(OS_ANDROID)
372 #endif // defined(OS_POSIX) && !defined(OS_MACOSX)
374 #if defined(OS_WIN)
375 void ShellContentBrowserClient::PreSpawnRenderer(sandbox::TargetPolicy* policy,
376 bool* success) {
377 // Add sideloaded font files for testing. See also DIR_WINDOWS_FONTS
378 // addition in |StartSandboxedProcess|.
379 std::vector<std::string> font_files = GetSideloadFontFiles();
380 for (std::vector<std::string>::const_iterator i(font_files.begin());
381 i != font_files.end();
382 ++i) {
383 policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
384 sandbox::TargetPolicy::FILES_ALLOW_READONLY,
385 base::UTF8ToWide(*i).c_str());
388 #endif // OS_WIN
390 ShellBrowserContext* ShellContentBrowserClient::browser_context() {
391 return shell_browser_main_parts_->browser_context();
394 ShellBrowserContext*
395 ShellContentBrowserClient::off_the_record_browser_context() {
396 return shell_browser_main_parts_->off_the_record_browser_context();
399 AccessTokenStore* ShellContentBrowserClient::CreateAccessTokenStore() {
400 return new ShellAccessTokenStore(browser_context());
403 ShellBrowserContext*
404 ShellContentBrowserClient::ShellBrowserContextForBrowserContext(
405 BrowserContext* content_browser_context) {
406 if (content_browser_context == browser_context())
407 return browser_context();
408 DCHECK_EQ(content_browser_context, off_the_record_browser_context());
409 return off_the_record_browser_context();
412 } // namespace content