[DevTools] Fixed double delete of ShellDevToolsDelegate
[chromium-blink-merge.git] / content / shell / browser / shell_content_browser_client.cc
blobac27b39e541ee4a6773583e4feff4ac706ad2d84
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/render_process_host.h"
14 #include "content/public/browser/resource_dispatcher_host.h"
15 #include "content/public/browser/storage_partition.h"
16 #include "content/public/common/content_switches.h"
17 #include "content/public/common/url_constants.h"
18 #include "content/public/common/web_preferences.h"
19 #include "content/shell/browser/ipc_echo_message_filter.h"
20 #include "content/shell/browser/layout_test/layout_test_browser_main_parts.h"
21 #include "content/shell/browser/layout_test/layout_test_resource_dispatcher_host_delegate.h"
22 #include "content/shell/browser/shell.h"
23 #include "content/shell/browser/shell_access_token_store.h"
24 #include "content/shell/browser/shell_browser_context.h"
25 #include "content/shell/browser/shell_browser_main_parts.h"
26 #include "content/shell/browser/shell_devtools_manager_delegate.h"
27 #include "content/shell/browser/shell_net_log.h"
28 #include "content/shell/browser/shell_quota_permission_context.h"
29 #include "content/shell/browser/shell_resource_dispatcher_host_delegate.h"
30 #include "content/shell/browser/shell_web_contents_view_delegate_creator.h"
31 #include "content/shell/browser/webkit_test_controller.h"
32 #include "content/shell/common/shell_messages.h"
33 #include "content/shell/common/shell_switches.h"
34 #include "content/shell/common/webkit_test_helpers.h"
35 #include "net/url_request/url_request_context_getter.h"
36 #include "url/gurl.h"
38 #if defined(OS_ANDROID)
39 #include "base/android/path_utils.h"
40 #include "components/crash/browser/crash_dump_manager_android.h"
41 #include "content/shell/android/shell_descriptors.h"
42 #endif
44 #if defined(OS_POSIX) && !defined(OS_MACOSX)
45 #include "base/debug/leak_annotations.h"
46 #include "components/crash/app/breakpad_linux.h"
47 #include "components/crash/browser/crash_handler_host_linux.h"
48 #include "content/public/common/content_descriptors.h"
49 #endif
51 #if defined(OS_WIN)
52 #include "content/common/sandbox_win.h"
53 #include "sandbox/win/src/sandbox.h"
54 #endif
56 namespace content {
58 namespace {
60 ShellContentBrowserClient* g_browser_client;
61 bool g_swap_processes_for_redirect = false;
63 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
64 breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost(
65 const std::string& process_type) {
66 base::FilePath dumps_path =
67 CommandLine::ForCurrentProcess()->GetSwitchValuePath(
68 switches::kCrashDumpsDir);
70 ANNOTATE_SCOPED_MEMORY_LEAK;
71 breakpad::CrashHandlerHostLinux* crash_handler =
72 new breakpad::CrashHandlerHostLinux(
73 process_type, dumps_path, false);
74 crash_handler->StartUploaderThread();
75 return crash_handler;
79 int GetCrashSignalFD(const CommandLine& command_line) {
80 if (!breakpad::IsCrashReporterEnabled())
81 return -1;
83 std::string process_type =
84 command_line.GetSwitchValueASCII(switches::kProcessType);
86 if (process_type == switches::kRendererProcess) {
87 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
88 if (!crash_handler)
89 crash_handler = CreateCrashHandlerHost(process_type);
90 return crash_handler->GetDeathSignalSocket();
93 if (process_type == switches::kPluginProcess) {
94 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
95 if (!crash_handler)
96 crash_handler = CreateCrashHandlerHost(process_type);
97 return crash_handler->GetDeathSignalSocket();
100 if (process_type == switches::kPpapiPluginProcess) {
101 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
102 if (!crash_handler)
103 crash_handler = CreateCrashHandlerHost(process_type);
104 return crash_handler->GetDeathSignalSocket();
107 if (process_type == switches::kGpuProcess) {
108 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
109 if (!crash_handler)
110 crash_handler = CreateCrashHandlerHost(process_type);
111 return crash_handler->GetDeathSignalSocket();
114 return -1;
116 #endif // defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
118 } // namespace
120 ShellContentBrowserClient* ShellContentBrowserClient::Get() {
121 return g_browser_client;
124 void ShellContentBrowserClient::SetSwapProcessesForRedirect(bool swap) {
125 g_swap_processes_for_redirect = swap;
128 ShellContentBrowserClient::ShellContentBrowserClient()
129 : shell_browser_main_parts_(NULL) {
130 DCHECK(!g_browser_client);
131 g_browser_client = this;
134 ShellContentBrowserClient::~ShellContentBrowserClient() {
135 g_browser_client = NULL;
138 BrowserMainParts* ShellContentBrowserClient::CreateBrowserMainParts(
139 const MainFunctionParams& parameters) {
140 shell_browser_main_parts_ =
141 CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)
142 ? new LayoutTestBrowserMainParts(parameters)
143 : new ShellBrowserMainParts(parameters);
144 return shell_browser_main_parts_;
147 void ShellContentBrowserClient::RenderProcessWillLaunch(
148 RenderProcessHost* host) {
149 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kExposeIpcEcho))
150 host->AddFilter(new IPCEchoMessageFilter());
153 net::URLRequestContextGetter* ShellContentBrowserClient::CreateRequestContext(
154 BrowserContext* content_browser_context,
155 ProtocolHandlerMap* protocol_handlers,
156 URLRequestInterceptorScopedVector request_interceptors) {
157 ShellBrowserContext* shell_browser_context =
158 ShellBrowserContextForBrowserContext(content_browser_context);
159 return shell_browser_context->CreateRequestContext(
160 protocol_handlers, request_interceptors.Pass());
163 net::URLRequestContextGetter*
164 ShellContentBrowserClient::CreateRequestContextForStoragePartition(
165 BrowserContext* content_browser_context,
166 const base::FilePath& partition_path,
167 bool in_memory,
168 ProtocolHandlerMap* protocol_handlers,
169 URLRequestInterceptorScopedVector request_interceptors) {
170 ShellBrowserContext* shell_browser_context =
171 ShellBrowserContextForBrowserContext(content_browser_context);
172 return shell_browser_context->CreateRequestContextForStoragePartition(
173 partition_path,
174 in_memory,
175 protocol_handlers,
176 request_interceptors.Pass());
179 bool ShellContentBrowserClient::IsHandledURL(const GURL& url) {
180 if (!url.is_valid())
181 return false;
182 DCHECK_EQ(url.scheme(), base::StringToLowerASCII(url.scheme()));
183 // Keep in sync with ProtocolHandlers added by
184 // ShellURLRequestContextGetter::GetURLRequestContext().
185 static const char* const kProtocolList[] = {
186 url::kBlobScheme,
187 url::kFileSystemScheme,
188 kChromeUIScheme,
189 kChromeDevToolsScheme,
190 url::kDataScheme,
191 url::kFileScheme,
193 for (size_t i = 0; i < arraysize(kProtocolList); ++i) {
194 if (url.scheme() == kProtocolList[i])
195 return true;
197 return false;
200 void ShellContentBrowserClient::AppendExtraCommandLineSwitches(
201 CommandLine* command_line, int child_process_id) {
202 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
203 command_line->AppendSwitch(switches::kDumpRenderTree);
204 if (CommandLine::ForCurrentProcess()->HasSwitch(
205 switches::kEnableFontAntialiasing))
206 command_line->AppendSwitch(switches::kEnableFontAntialiasing);
207 if (CommandLine::ForCurrentProcess()->HasSwitch(
208 switches::kExposeInternalsForTesting))
209 command_line->AppendSwitch(switches::kExposeInternalsForTesting);
210 if (CommandLine::ForCurrentProcess()->HasSwitch(
211 switches::kExposeIpcEcho))
212 command_line->AppendSwitch(switches::kExposeIpcEcho);
213 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kStableReleaseMode))
214 command_line->AppendSwitch(switches::kStableReleaseMode);
215 if (CommandLine::ForCurrentProcess()->HasSwitch(
216 switches::kEnableCrashReporter)) {
217 command_line->AppendSwitch(switches::kEnableCrashReporter);
219 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kCrashDumpsDir)) {
220 command_line->AppendSwitchPath(
221 switches::kCrashDumpsDir,
222 CommandLine::ForCurrentProcess()->GetSwitchValuePath(
223 switches::kCrashDumpsDir));
225 if (CommandLine::ForCurrentProcess()->HasSwitch(
226 switches::kEnableLeakDetection)) {
227 command_line->AppendSwitchASCII(
228 switches::kEnableLeakDetection,
229 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
230 switches::kEnableLeakDetection));
232 if (CommandLine::ForCurrentProcess()->HasSwitch(
233 switches::kRegisterFontFiles)) {
234 command_line->AppendSwitchASCII(
235 switches::kRegisterFontFiles,
236 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
237 switches::kRegisterFontFiles));
241 void ShellContentBrowserClient::OverrideWebkitPrefs(
242 RenderViewHost* render_view_host,
243 const GURL& url,
244 WebPreferences* prefs) {
245 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
246 return;
247 WebKitTestController::Get()->OverrideWebkitPrefs(prefs);
250 void ShellContentBrowserClient::ResourceDispatcherHostCreated() {
251 resource_dispatcher_host_delegate_.reset(
252 CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)
253 ? new LayoutTestResourceDispatcherHostDelegate
254 : new ShellResourceDispatcherHostDelegate);
255 ResourceDispatcherHost::Get()->SetDelegate(
256 resource_dispatcher_host_delegate_.get());
259 std::string ShellContentBrowserClient::GetDefaultDownloadName() {
260 return "download";
263 WebContentsViewDelegate* ShellContentBrowserClient::GetWebContentsViewDelegate(
264 WebContents* web_contents) {
265 #if !defined(USE_AURA)
266 return CreateShellWebContentsViewDelegate(web_contents);
267 #else
268 return NULL;
269 #endif
272 QuotaPermissionContext*
273 ShellContentBrowserClient::CreateQuotaPermissionContext() {
274 return new ShellQuotaPermissionContext();
277 SpeechRecognitionManagerDelegate*
278 ShellContentBrowserClient::GetSpeechRecognitionManagerDelegate() {
279 return new ShellSpeechRecognitionManagerDelegate();
282 net::NetLog* ShellContentBrowserClient::GetNetLog() {
283 return shell_browser_main_parts_->net_log();
286 bool ShellContentBrowserClient::ShouldSwapProcessesForRedirect(
287 ResourceContext* resource_context,
288 const GURL& current_url,
289 const GURL& new_url) {
290 return g_swap_processes_for_redirect;
293 DevToolsManagerDelegate*
294 ShellContentBrowserClient::GetDevToolsManagerDelegate() {
295 return new ShellDevToolsManagerDelegate(browser_context());
298 #if defined(OS_POSIX) && !defined(OS_MACOSX)
299 void ShellContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
300 const CommandLine& command_line,
301 int child_process_id,
302 FileDescriptorInfo* mappings) {
303 #if defined(OS_ANDROID)
304 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
305 base::FilePath pak_file;
306 bool r = PathService::Get(base::DIR_ANDROID_APP_DATA, &pak_file);
307 CHECK(r);
308 pak_file = pak_file.Append(FILE_PATH_LITERAL("paks"));
309 pak_file = pak_file.Append(FILE_PATH_LITERAL("content_shell.pak"));
311 base::File f(pak_file, flags);
312 if (!f.IsValid()) {
313 NOTREACHED() << "Failed to open file when creating renderer process: "
314 << "content_shell.pak";
317 mappings->Transfer(kShellPakDescriptor, base::ScopedFD(f.TakePlatformFile()));
319 if (breakpad::IsCrashReporterEnabled()) {
320 f = breakpad::CrashDumpManager::GetInstance()->CreateMinidumpFile(
321 child_process_id);
322 if (!f.IsValid()) {
323 LOG(ERROR) << "Failed to create file for minidump, crash reporting will "
324 << "be disabled for this process.";
325 } else {
326 mappings->Transfer(kAndroidMinidumpDescriptor,
327 base::ScopedFD(f.TakePlatformFile()));
330 #else // !defined(OS_ANDROID)
331 int crash_signal_fd = GetCrashSignalFD(command_line);
332 if (crash_signal_fd >= 0) {
333 mappings->Share(kCrashDumpSignal, crash_signal_fd);
335 #endif // defined(OS_ANDROID)
337 #endif // defined(OS_POSIX) && !defined(OS_MACOSX)
339 #if defined(OS_WIN)
340 void ShellContentBrowserClient::PreSpawnRenderer(sandbox::TargetPolicy* policy,
341 bool* success) {
342 // Add sideloaded font files for testing. See also DIR_WINDOWS_FONTS
343 // addition in |StartSandboxedProcess|.
344 std::vector<std::string> font_files = GetSideloadFontFiles();
345 for (std::vector<std::string>::const_iterator i(font_files.begin());
346 i != font_files.end();
347 ++i) {
348 policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
349 sandbox::TargetPolicy::FILES_ALLOW_READONLY,
350 base::UTF8ToWide(*i).c_str());
353 #endif // OS_WIN
355 ShellBrowserContext* ShellContentBrowserClient::browser_context() {
356 return shell_browser_main_parts_->browser_context();
359 ShellBrowserContext*
360 ShellContentBrowserClient::off_the_record_browser_context() {
361 return shell_browser_main_parts_->off_the_record_browser_context();
364 AccessTokenStore* ShellContentBrowserClient::CreateAccessTokenStore() {
365 return new ShellAccessTokenStore(browser_context());
368 ShellBrowserContext*
369 ShellContentBrowserClient::ShellBrowserContextForBrowserContext(
370 BrowserContext* content_browser_context) {
371 if (content_browser_context == browser_context())
372 return browser_context();
373 DCHECK_EQ(content_browser_context, off_the_record_browser_context());
374 return off_the_record_browser_context();
377 } // namespace content