Extension window.create API accepts state.
[chromium-blink-merge.git] / content / shell / browser / shell_content_browser_client.cc
blobfc03843c0830ae4aa60860821fa40fd451bf1523
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/ipc_echo_message_filter.h"
22 #include "content/shell/browser/layout_test/layout_test_browser_main_parts.h"
23 #include "content/shell/browser/layout_test/layout_test_resource_dispatcher_host_delegate.h"
24 #include "content/shell/browser/shell.h"
25 #include "content/shell/browser/shell_access_token_store.h"
26 #include "content/shell/browser/shell_browser_context.h"
27 #include "content/shell/browser/shell_browser_main_parts.h"
28 #include "content/shell/browser/shell_devtools_manager_delegate.h"
29 #include "content/shell/browser/shell_net_log.h"
30 #include "content/shell/browser/shell_quota_permission_context.h"
31 #include "content/shell/browser/shell_resource_dispatcher_host_delegate.h"
32 #include "content/shell/browser/shell_web_contents_view_delegate_creator.h"
33 #include "content/shell/browser/webkit_test_controller.h"
34 #include "content/shell/common/shell_messages.h"
35 #include "content/shell/common/shell_switches.h"
36 #include "content/shell/common/webkit_test_helpers.h"
37 #include "gin/v8_initializer.h"
38 #include "net/url_request/url_request_context_getter.h"
39 #include "url/gurl.h"
41 #if defined(OS_ANDROID)
42 #include "base/android/path_utils.h"
43 #include "components/crash/browser/crash_dump_manager_android.h"
44 #include "content/shell/android/shell_descriptors.h"
45 #endif
47 #if defined(OS_POSIX) && !defined(OS_MACOSX)
48 #include "base/debug/leak_annotations.h"
49 #include "components/crash/app/breakpad_linux.h"
50 #include "components/crash/browser/crash_handler_host_linux.h"
51 #include "content/public/common/content_descriptors.h"
52 #endif
54 #if defined(OS_WIN)
55 #include "content/common/sandbox_win.h"
56 #include "sandbox/win/src/sandbox.h"
57 #endif
59 namespace content {
61 namespace {
63 ShellContentBrowserClient* g_browser_client;
64 bool g_swap_processes_for_redirect = false;
66 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
67 breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost(
68 const std::string& process_type) {
69 base::FilePath dumps_path =
70 base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
71 switches::kCrashDumpsDir);
73 ANNOTATE_SCOPED_MEMORY_LEAK;
74 breakpad::CrashHandlerHostLinux* crash_handler =
75 new breakpad::CrashHandlerHostLinux(
76 process_type, dumps_path, false);
77 crash_handler->StartUploaderThread();
78 return crash_handler;
82 int GetCrashSignalFD(const base::CommandLine& command_line) {
83 if (!breakpad::IsCrashReporterEnabled())
84 return -1;
86 std::string process_type =
87 command_line.GetSwitchValueASCII(switches::kProcessType);
89 if (process_type == switches::kRendererProcess) {
90 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
91 if (!crash_handler)
92 crash_handler = CreateCrashHandlerHost(process_type);
93 return crash_handler->GetDeathSignalSocket();
96 if (process_type == switches::kPluginProcess) {
97 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
98 if (!crash_handler)
99 crash_handler = CreateCrashHandlerHost(process_type);
100 return crash_handler->GetDeathSignalSocket();
103 if (process_type == switches::kPpapiPluginProcess) {
104 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
105 if (!crash_handler)
106 crash_handler = CreateCrashHandlerHost(process_type);
107 return crash_handler->GetDeathSignalSocket();
110 if (process_type == switches::kGpuProcess) {
111 static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
112 if (!crash_handler)
113 crash_handler = CreateCrashHandlerHost(process_type);
114 return crash_handler->GetDeathSignalSocket();
117 return -1;
119 #endif // defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
121 } // namespace
123 ShellContentBrowserClient* ShellContentBrowserClient::Get() {
124 return g_browser_client;
127 void ShellContentBrowserClient::SetSwapProcessesForRedirect(bool swap) {
128 g_swap_processes_for_redirect = swap;
131 ShellContentBrowserClient::ShellContentBrowserClient()
133 #if defined(OS_POSIX) && !defined(OS_MACOSX)
134 v8_natives_fd_(-1),
135 v8_snapshot_fd_(-1),
136 #endif // OS_POSIX && !OS_MACOSX
137 shell_browser_main_parts_(NULL) {
138 DCHECK(!g_browser_client);
139 g_browser_client = this;
142 ShellContentBrowserClient::~ShellContentBrowserClient() {
143 g_browser_client = NULL;
146 BrowserMainParts* ShellContentBrowserClient::CreateBrowserMainParts(
147 const MainFunctionParams& parameters) {
148 shell_browser_main_parts_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
149 switches::kRunLayoutTest)
150 ? new LayoutTestBrowserMainParts(parameters)
151 : new ShellBrowserMainParts(parameters);
152 return shell_browser_main_parts_;
155 void ShellContentBrowserClient::RenderProcessWillLaunch(
156 RenderProcessHost* host) {
157 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
158 switches::kExposeIpcEcho))
159 host->AddFilter(new IPCEchoMessageFilter());
162 net::URLRequestContextGetter* ShellContentBrowserClient::CreateRequestContext(
163 BrowserContext* content_browser_context,
164 ProtocolHandlerMap* protocol_handlers,
165 URLRequestInterceptorScopedVector request_interceptors) {
166 ShellBrowserContext* shell_browser_context =
167 ShellBrowserContextForBrowserContext(content_browser_context);
168 return shell_browser_context->CreateRequestContext(
169 protocol_handlers, request_interceptors.Pass());
172 net::URLRequestContextGetter*
173 ShellContentBrowserClient::CreateRequestContextForStoragePartition(
174 BrowserContext* content_browser_context,
175 const base::FilePath& partition_path,
176 bool in_memory,
177 ProtocolHandlerMap* protocol_handlers,
178 URLRequestInterceptorScopedVector request_interceptors) {
179 ShellBrowserContext* shell_browser_context =
180 ShellBrowserContextForBrowserContext(content_browser_context);
181 return shell_browser_context->CreateRequestContextForStoragePartition(
182 partition_path,
183 in_memory,
184 protocol_handlers,
185 request_interceptors.Pass());
188 bool ShellContentBrowserClient::IsHandledURL(const GURL& url) {
189 if (!url.is_valid())
190 return false;
191 DCHECK_EQ(url.scheme(), base::StringToLowerASCII(url.scheme()));
192 // Keep in sync with ProtocolHandlers added by
193 // ShellURLRequestContextGetter::GetURLRequestContext().
194 static const char* const kProtocolList[] = {
195 url::kBlobScheme,
196 url::kFileSystemScheme,
197 kChromeUIScheme,
198 kChromeDevToolsScheme,
199 url::kDataScheme,
200 url::kFileScheme,
202 for (size_t i = 0; i < arraysize(kProtocolList); ++i) {
203 if (url.scheme() == kProtocolList[i])
204 return true;
206 return false;
209 void ShellContentBrowserClient::AppendExtraCommandLineSwitches(
210 base::CommandLine* command_line,
211 int child_process_id) {
212 #if defined(OS_POSIX) && !defined(OS_MACOSX)
213 #if defined(V8_USE_EXTERNAL_STARTUP_DATA)
214 std::string process_type =
215 command_line->GetSwitchValueASCII(switches::kProcessType);
216 if (process_type != switches::kZygoteProcess) {
217 command_line->AppendSwitch(::switches::kV8NativesPassedByFD);
218 command_line->AppendSwitch(::switches::kV8SnapshotPassedByFD);
220 #endif // V8_USE_EXTERNAL_STARTUP_DATA
221 #endif // OS_POSIX && !OS_MACOSX
222 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
223 switches::kRunLayoutTest))
224 command_line->AppendSwitch(switches::kRunLayoutTest);
225 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
226 switches::kEnableFontAntialiasing))
227 command_line->AppendSwitch(switches::kEnableFontAntialiasing);
228 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
229 switches::kExposeInternalsForTesting))
230 command_line->AppendSwitch(switches::kExposeInternalsForTesting);
231 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
232 switches::kExposeIpcEcho))
233 command_line->AppendSwitch(switches::kExposeIpcEcho);
234 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
235 switches::kStableReleaseMode))
236 command_line->AppendSwitch(switches::kStableReleaseMode);
237 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
238 switches::kEnableCrashReporter)) {
239 command_line->AppendSwitch(switches::kEnableCrashReporter);
241 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
242 switches::kCrashDumpsDir)) {
243 command_line->AppendSwitchPath(
244 switches::kCrashDumpsDir,
245 base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
246 switches::kCrashDumpsDir));
248 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
249 switches::kEnableLeakDetection)) {
250 command_line->AppendSwitchASCII(
251 switches::kEnableLeakDetection,
252 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
253 switches::kEnableLeakDetection));
255 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
256 switches::kRegisterFontFiles)) {
257 command_line->AppendSwitchASCII(
258 switches::kRegisterFontFiles,
259 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
260 switches::kRegisterFontFiles));
264 void ShellContentBrowserClient::OverrideWebkitPrefs(
265 RenderViewHost* render_view_host,
266 WebPreferences* prefs) {
267 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
268 switches::kRunLayoutTest))
269 return;
270 WebKitTestController::Get()->OverrideWebkitPrefs(prefs);
273 void ShellContentBrowserClient::ResourceDispatcherHostCreated() {
274 resource_dispatcher_host_delegate_.reset(
275 base::CommandLine::ForCurrentProcess()->HasSwitch(
276 switches::kRunLayoutTest)
277 ? new LayoutTestResourceDispatcherHostDelegate
278 : new ShellResourceDispatcherHostDelegate);
279 ResourceDispatcherHost::Get()->SetDelegate(
280 resource_dispatcher_host_delegate_.get());
283 std::string ShellContentBrowserClient::GetDefaultDownloadName() {
284 return "download";
287 WebContentsViewDelegate* ShellContentBrowserClient::GetWebContentsViewDelegate(
288 WebContents* web_contents) {
289 #if !defined(USE_AURA)
290 return CreateShellWebContentsViewDelegate(web_contents);
291 #else
292 return NULL;
293 #endif
296 QuotaPermissionContext*
297 ShellContentBrowserClient::CreateQuotaPermissionContext() {
298 return new ShellQuotaPermissionContext();
301 void ShellContentBrowserClient::SelectClientCertificate(
302 WebContents* web_contents,
303 net::SSLCertRequestInfo* cert_request_info,
304 scoped_ptr<ClientCertificateDelegate> delegate) {
305 if (!select_client_certificate_callback_.is_null())
306 select_client_certificate_callback_.Run();
309 SpeechRecognitionManagerDelegate*
310 ShellContentBrowserClient::CreateSpeechRecognitionManagerDelegate() {
311 return new ShellSpeechRecognitionManagerDelegate();
314 net::NetLog* ShellContentBrowserClient::GetNetLog() {
315 return shell_browser_main_parts_->net_log();
318 bool ShellContentBrowserClient::ShouldSwapProcessesForRedirect(
319 ResourceContext* resource_context,
320 const GURL& current_url,
321 const GURL& new_url) {
322 return g_swap_processes_for_redirect;
325 DevToolsManagerDelegate*
326 ShellContentBrowserClient::GetDevToolsManagerDelegate() {
327 return new ShellDevToolsManagerDelegate(browser_context());
330 void ShellContentBrowserClient::OpenURL(
331 BrowserContext* browser_context,
332 const OpenURLParams& params,
333 const base::Callback<void(WebContents*)>& callback) {
334 callback.Run(Shell::CreateNewWindow(browser_context,
335 params.url,
336 nullptr,
337 gfx::Size())->web_contents());
340 #if defined(OS_POSIX) && !defined(OS_MACOSX)
341 void ShellContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
342 const base::CommandLine& command_line,
343 int child_process_id,
344 FileDescriptorInfo* mappings) {
345 #if defined(V8_USE_EXTERNAL_STARTUP_DATA)
346 if (v8_natives_fd_.get() == -1 || v8_snapshot_fd_.get() == -1) {
347 int v8_natives_fd = -1;
348 int v8_snapshot_fd = -1;
349 if (gin::V8Initializer::OpenV8FilesForChildProcesses(&v8_natives_fd,
350 &v8_snapshot_fd)) {
351 v8_natives_fd_.reset(v8_natives_fd);
352 v8_snapshot_fd_.reset(v8_snapshot_fd);
355 DCHECK(v8_natives_fd_.get() != -1 && v8_snapshot_fd_.get() != -1);
356 mappings->Share(kV8NativesDataDescriptor, v8_natives_fd_.get());
357 mappings->Share(kV8SnapshotDataDescriptor, v8_snapshot_fd_.get());
358 #endif // V8_USE_EXTERNAL_STARTUP_DATA
360 #if defined(OS_ANDROID)
361 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
362 base::FilePath pak_file;
363 bool r = PathService::Get(base::DIR_ANDROID_APP_DATA, &pak_file);
364 CHECK(r);
365 pak_file = pak_file.Append(FILE_PATH_LITERAL("paks"));
366 pak_file = pak_file.Append(FILE_PATH_LITERAL("content_shell.pak"));
368 base::File f(pak_file, flags);
369 if (!f.IsValid()) {
370 NOTREACHED() << "Failed to open file when creating renderer process: "
371 << "content_shell.pak";
374 mappings->Transfer(kShellPakDescriptor, base::ScopedFD(f.TakePlatformFile()));
376 if (breakpad::IsCrashReporterEnabled()) {
377 f = breakpad::CrashDumpManager::GetInstance()->CreateMinidumpFile(
378 child_process_id);
379 if (!f.IsValid()) {
380 LOG(ERROR) << "Failed to create file for minidump, crash reporting will "
381 << "be disabled for this process.";
382 } else {
383 mappings->Transfer(kAndroidMinidumpDescriptor,
384 base::ScopedFD(f.TakePlatformFile()));
387 #else // !defined(OS_ANDROID)
388 int crash_signal_fd = GetCrashSignalFD(command_line);
389 if (crash_signal_fd >= 0) {
390 mappings->Share(kCrashDumpSignal, crash_signal_fd);
392 #endif // defined(OS_ANDROID)
394 #endif // defined(OS_POSIX) && !defined(OS_MACOSX)
396 #if defined(OS_WIN)
397 void ShellContentBrowserClient::PreSpawnRenderer(sandbox::TargetPolicy* policy,
398 bool* success) {
399 // Add sideloaded font files for testing. See also DIR_WINDOWS_FONTS
400 // addition in |StartSandboxedProcess|.
401 std::vector<std::string> font_files = GetSideloadFontFiles();
402 for (std::vector<std::string>::const_iterator i(font_files.begin());
403 i != font_files.end();
404 ++i) {
405 policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
406 sandbox::TargetPolicy::FILES_ALLOW_READONLY,
407 base::UTF8ToWide(*i).c_str());
410 #endif // OS_WIN
412 ShellBrowserContext* ShellContentBrowserClient::browser_context() {
413 return shell_browser_main_parts_->browser_context();
416 ShellBrowserContext*
417 ShellContentBrowserClient::off_the_record_browser_context() {
418 return shell_browser_main_parts_->off_the_record_browser_context();
421 AccessTokenStore* ShellContentBrowserClient::CreateAccessTokenStore() {
422 return new ShellAccessTokenStore(browser_context());
425 ShellBrowserContext*
426 ShellContentBrowserClient::ShellBrowserContextForBrowserContext(
427 BrowserContext* content_browser_context) {
428 if (content_browser_context == browser_context())
429 return browser_context();
430 DCHECK_EQ(content_browser_context, off_the_record_browser_context());
431 return off_the_record_browser_context();
434 } // namespace content