Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / shell / app / shell_main_delegate.cc
1 // Copyright (c) 2012 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 "content/shell/app/shell_main_delegate.h"
6
7 #include "base/base_switches.h"
8 #include "base/command_line.h"
9 #include "base/cpu.h"
10 #include "base/files/file.h"
11 #include "base/files/file_path.h"
12 #include "base/lazy_instance.h"
13 #include "base/logging.h"
14 #include "base/path_service.h"
15 #include "cc/base/switches.h"
16 #include "content/public/browser/browser_main_runner.h"
17 #include "content/public/common/content_switches.h"
18 #include "content/public/common/url_constants.h"
19 #include "content/public/test/layouttest_support.h"
20 #include "content/shell/app/shell_crash_reporter_client.h"
21 #include "content/shell/app/webkit_test_platform_support.h"
22 #include "content/shell/browser/shell_browser_main.h"
23 #include "content/shell/browser/shell_content_browser_client.h"
24 #include "content/shell/common/shell_switches.h"
25 #include "content/shell/renderer/shell_content_renderer_client.h"
26 #include "media/base/media_switches.h"
27 #include "net/cookies/cookie_monster.h"
28 #include "ui/base/resource/resource_bundle.h"
29 #include "ui/base/ui_base_paths.h"
30 #include "ui/base/ui_base_switches.h"
31 #include "ui/events/event_switches.h"
32 #include "ui/gfx/switches.h"
33 #include "ui/gl/gl_switches.h"
34
35 #include "ipc/ipc_message.h"  // For IPC_MESSAGE_LOG_ENABLED.
36
37 #if defined(IPC_MESSAGE_LOG_ENABLED)
38 #define IPC_MESSAGE_MACROS_LOG_ENABLED
39 #include "content/public/common/content_ipc_logging.h"
40 #define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \
41     content::RegisterIPCLogger(msg_id, logger)
42 #include "content/shell/common/shell_messages.h"
43 #endif
44
45 #if defined(OS_ANDROID)
46 #include "base/posix/global_descriptors.h"
47 #include "content/shell/android/shell_descriptors.h"
48 #endif
49
50 #if defined(OS_MACOSX)
51 #include "base/mac/os_crash_dumps.h"
52 #include "components/crash/app/breakpad_mac.h"
53 #include "content/shell/app/paths_mac.h"
54 #include "content/shell/app/shell_main_delegate_mac.h"
55 #endif  // OS_MACOSX
56
57 #if defined(OS_WIN)
58 #include <initguid.h>
59 #include <windows.h>
60 #include "base/logging_win.h"
61 #include "components/crash/app/breakpad_win.h"
62 #endif
63
64 #if defined(OS_POSIX) && !defined(OS_MACOSX)
65 #include "components/crash/app/breakpad_linux.h"
66 #endif
67
68 namespace {
69
70 base::LazyInstance<content::ShellCrashReporterClient>::Leaky
71     g_shell_crash_client = LAZY_INSTANCE_INITIALIZER;
72
73 #if defined(OS_WIN)
74 // If "Content Shell" doesn't show up in your list of trace providers in
75 // Sawbuck, add these registry entries to your machine (NOTE the optional
76 // Wow6432Node key for x64 machines):
77 // 1. Find:  HKLM\SOFTWARE\[Wow6432Node\]Google\Sawbuck\Providers
78 // 2. Add a subkey with the name "{6A3E50A4-7E15-4099-8413-EC94D8C2A4B6}"
79 // 3. Add these values:
80 //    "default_flags"=dword:00000001
81 //    "default_level"=dword:00000004
82 //    @="Content Shell"
83
84 // {6A3E50A4-7E15-4099-8413-EC94D8C2A4B6}
85 const GUID kContentShellProviderName = {
86     0x6a3e50a4, 0x7e15, 0x4099,
87         { 0x84, 0x13, 0xec, 0x94, 0xd8, 0xc2, 0xa4, 0xb6 } };
88 #endif
89
90 void InitLogging() {
91   base::FilePath log_filename;
92   PathService::Get(base::DIR_EXE, &log_filename);
93   log_filename = log_filename.AppendASCII("content_shell.log");
94   logging::LoggingSettings settings;
95   settings.logging_dest = logging::LOG_TO_ALL;
96   settings.log_file = log_filename.value().c_str();
97   settings.delete_old = logging::DELETE_OLD_LOG_FILE;
98   logging::InitLogging(settings);
99   logging::SetLogItems(true, true, true, true);
100 }
101
102 }  // namespace
103
104 namespace content {
105
106 ShellMainDelegate::ShellMainDelegate() {
107 }
108
109 ShellMainDelegate::~ShellMainDelegate() {
110 }
111
112 bool ShellMainDelegate::BasicStartupComplete(int* exit_code) {
113 #if defined(OS_WIN)
114   // Enable trace control and transport through event tracing for Windows.
115   logging::LogEventProvider::Initialize(kContentShellProviderName);
116 #endif
117 #if defined(OS_MACOSX)
118   // Needs to happen before InitializeResourceBundle() and before
119   // WebKitTestPlatformInitialize() are called.
120   OverrideFrameworkBundlePath();
121   OverrideChildProcessPath();
122   EnsureCorrectResolutionSettings();
123 #endif  // OS_MACOSX
124
125   InitLogging();
126   CommandLine& command_line = *CommandLine::ForCurrentProcess();
127   if (command_line.HasSwitch(switches::kCheckLayoutTestSysDeps)) {
128     // If CheckLayoutSystemDeps succeeds, we don't exit early. Instead we
129     // continue and try to load the fonts in WebKitTestPlatformInitialize
130     // below, and then try to bring up the rest of the content module.
131     if (!CheckLayoutSystemDeps()) {
132       if (exit_code)
133         *exit_code = 1;
134       return true;
135     }
136   }
137
138   if (command_line.HasSwitch(switches::kDumpRenderTree)) {
139     EnableBrowserLayoutTestMode();
140
141     command_line.AppendSwitch(switches::kProcessPerTab);
142     command_line.AppendSwitch(switches::kEnableLogging);
143     command_line.AppendSwitch(switches::kAllowFileAccessFromFiles);
144     command_line.AppendSwitchASCII(switches::kUseGL,
145                                    gfx::kGLImplementationOSMesaName);
146     command_line.AppendSwitch(switches::kSkipGpuDataLoading);
147     command_line.AppendSwitchASCII(switches::kTouchEvents,
148                                    switches::kTouchEventsEnabled);
149     command_line.AppendSwitchASCII(switches::kForceDeviceScaleFactor, "1.0");
150 #if defined(OS_ANDROID)
151     command_line.AppendSwitch(
152         switches::kDisableGestureRequirementForMediaPlayback);
153 #endif
154
155     if (!command_line.HasSwitch(switches::kStableReleaseMode)) {
156       command_line.AppendSwitch(
157         switches::kEnableExperimentalWebPlatformFeatures);
158     }
159
160     if (!command_line.HasSwitch(switches::kEnableThreadedCompositing)) {
161       command_line.AppendSwitch(switches::kDisableThreadedCompositing);
162       command_line.AppendSwitch(cc::switches::kDisableThreadedAnimation);
163       command_line.AppendSwitch(switches::kDisableImplSidePainting);
164     }
165
166     command_line.AppendSwitch(switches::kEnableInbandTextTracks);
167     command_line.AppendSwitch(switches::kMuteAudio);
168
169 #if defined(USE_AURA) || defined(OS_ANDROID) || defined(OS_MACOSX)
170     // TODO: crbug.com/311404 Make layout tests work w/ delegated renderer.
171     command_line.AppendSwitch(switches::kDisableDelegatedRenderer);
172     command_line.AppendSwitch(cc::switches::kCompositeToMailbox);
173 #endif
174
175     command_line.AppendSwitch(switches::kEnableFileCookies);
176
177     command_line.AppendSwitch(switches::kEnablePreciseMemoryInfo);
178
179     command_line.AppendSwitchASCII(switches::kHostResolverRules,
180                                    "MAP *.test 127.0.0.1");
181
182     // Unless/until WebM files are added to the media layout tests, we need to
183     // avoid removing MP4/H264/AAC so that layout tests can run on Android.
184 #if !defined(OS_ANDROID)
185     net::RemoveProprietaryMediaTypesAndCodecsForTests();
186 #endif
187
188     if (!WebKitTestPlatformInitialize()) {
189       if (exit_code)
190         *exit_code = 1;
191       return true;
192     }
193   }
194   SetContentClient(&content_client_);
195   return false;
196 }
197
198 void ShellMainDelegate::PreSandboxStartup() {
199 #if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX))
200   // Create an instance of the CPU class to parse /proc/cpuinfo and cache
201   // cpu_brand info.
202   base::CPU cpu_info;
203 #endif
204   if (CommandLine::ForCurrentProcess()->HasSwitch(
205           switches::kEnableCrashReporter)) {
206     std::string process_type =
207         CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
208             switches::kProcessType);
209     crash_reporter::SetCrashReporterClient(g_shell_crash_client.Pointer());
210 #if defined(OS_MACOSX)
211     base::mac::DisableOSCrashDumps();
212     breakpad::InitCrashReporter(process_type);
213     breakpad::InitCrashProcessInfo(process_type);
214 #elif defined(OS_POSIX) && !defined(OS_MACOSX)
215     if (process_type != switches::kZygoteProcess) {
216 #if defined(OS_ANDROID)
217       if (process_type.empty())
218         breakpad::InitCrashReporter(process_type);
219       else
220         breakpad::InitNonBrowserCrashReporterForAndroid(process_type);
221 #else
222       breakpad::InitCrashReporter(process_type);
223 #endif
224     }
225 #elif defined(OS_WIN)
226     UINT new_flags =
227         SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX;
228     UINT existing_flags = SetErrorMode(new_flags);
229     SetErrorMode(existing_flags | new_flags);
230     breakpad::InitCrashReporter(process_type);
231 #endif
232   }
233
234   InitializeResourceBundle();
235 }
236
237 int ShellMainDelegate::RunProcess(
238     const std::string& process_type,
239     const MainFunctionParams& main_function_params) {
240   if (!process_type.empty())
241     return -1;
242
243 #if !defined(OS_ANDROID)
244   // Android stores the BrowserMainRunner instance as a scoped member pointer
245   // on the ShellMainDelegate class because of different object lifetime.
246   scoped_ptr<BrowserMainRunner> browser_runner_;
247 #endif
248
249   browser_runner_.reset(BrowserMainRunner::Create());
250   return ShellBrowserMain(main_function_params, browser_runner_);
251 }
252
253 #if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
254 void ShellMainDelegate::ZygoteForked() {
255   if (CommandLine::ForCurrentProcess()->HasSwitch(
256           switches::kEnableCrashReporter)) {
257     std::string process_type =
258         CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
259             switches::kProcessType);
260     breakpad::InitCrashReporter(process_type);
261   }
262 }
263 #endif
264
265 void ShellMainDelegate::InitializeResourceBundle() {
266 #if defined(OS_ANDROID)
267   // In the Android case, the renderer runs with a different UID and can never
268   // access the file system.  So we are passed a file descriptor to the
269   // ResourceBundle pak at launch time.
270   int pak_fd =
271       base::GlobalDescriptors::GetInstance()->MaybeGet(kShellPakDescriptor);
272   if (pak_fd >= 0) {
273     // This is clearly wrong. See crbug.com/330930
274     ui::ResourceBundle::InitSharedInstanceWithPakFileRegion(
275         base::File(pak_fd), base::MemoryMappedFile::Region::kWholeFile);
276     ResourceBundle::GetSharedInstance().AddDataPackFromFile(
277         base::File(pak_fd), ui::SCALE_FACTOR_100P);
278     return;
279   }
280 #endif
281
282   base::FilePath pak_file;
283 #if defined(OS_MACOSX)
284   pak_file = GetResourcesPakFilePath();
285 #else
286   base::FilePath pak_dir;
287
288 #if defined(OS_ANDROID)
289   bool got_path = PathService::Get(base::DIR_ANDROID_APP_DATA, &pak_dir);
290   DCHECK(got_path);
291   pak_dir = pak_dir.Append(FILE_PATH_LITERAL("paks"));
292 #else
293   PathService::Get(base::DIR_MODULE, &pak_dir);
294 #endif
295
296   pak_file = pak_dir.Append(FILE_PATH_LITERAL("content_shell.pak"));
297 #endif
298   ui::ResourceBundle::InitSharedInstanceWithPakPath(pak_file);
299 }
300
301 ContentBrowserClient* ShellMainDelegate::CreateContentBrowserClient() {
302   browser_client_.reset(new ShellContentBrowserClient);
303   return browser_client_.get();
304 }
305
306 ContentRendererClient* ShellMainDelegate::CreateContentRendererClient() {
307   renderer_client_.reset(new ShellContentRendererClient);
308   return renderer_client_.get();
309 }
310
311 }  // namespace content