Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: content/browser/browser_main.cc

Issue 8302016: Make GTK and Aura parts orthogonal to OS parts (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/browser/browser_main.h ('k') | content/browser/browser_main_loop.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/browser_main.h" 5 #include "content/browser/browser_main.h"
6 6
7 #include "base/allocator/allocator_shim.h" 7 #include "base/allocator/allocator_shim.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/metrics/field_trial.h"
12 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
13 #include "base/system_monitor/system_monitor.h" 12 #include "content/browser/browser_main_loop.h"
14 #include "base/threading/thread_restrictions.h"
15 #include "base/tracked_objects.h"
16 #include "content/browser/browser_thread.h" 13 #include "content/browser/browser_thread.h"
17 #include "content/browser/notification_service_impl.h" 14 #include "content/browser/notification_service_impl.h"
18 #include "content/common/hi_res_timer_manager.h"
19 #include "content/common/main_function_params.h" 15 #include "content/common/main_function_params.h"
20 #include "content/common/sandbox_policy.h"
21 #include "content/public/browser/content_browser_client.h"
22 #include "content/public/common/content_switches.h" 16 #include "content/public/common/content_switches.h"
23 #include "content/public/common/result_codes.h"
24 #include "crypto/nss_util.h"
25 #include "net/base/network_change_notifier.h"
26 #include "net/base/ssl_config_service.h"
27 #include "net/socket/client_socket_factory.h"
28 #include "net/socket/tcp_client_socket.h"
29 17
30 #if defined(OS_WIN) 18 #if defined(OS_WIN)
31 #include <windows.h>
32 #include <commctrl.h>
33 #include <ole2.h>
34 #include <shellapi.h>
35
36 #include "base/win/scoped_com_initializer.h" 19 #include "base/win/scoped_com_initializer.h"
37 #include "net/base/winsock_init.h" 20 #include "content/common/sandbox_policy.h"
38 #include "sandbox/src/sandbox.h" 21 #include "sandbox/src/sandbox.h"
39 #include "ui/base/l10n/l10n_util_win.h"
40 #endif
41
42 #if defined(OS_LINUX)
43 #include <glib-object.h>
44 #endif
45
46 #if defined(OS_CHROMEOS)
47 #include <dbus/dbus-glib.h>
48 #endif
49
50 #if defined(OS_POSIX) && !defined(OS_MACOSX)
51 #include <sys/stat.h>
52
53 #include "content/browser/renderer_host/render_sandbox_host_linux.h"
54 #include "content/browser/zygote_host_linux.h"
55 #endif
56
57 #if defined(TOOLKIT_USES_GTK)
58 #include "ui/gfx/gtk_util.h"
59 #endif 22 #endif
60 23
61 namespace { 24 namespace {
62 25
63 #if defined(OS_WIN) 26 #if defined(OS_WIN)
64 // Windows-specific initialization code for the sandbox broker services. 27 // Windows-specific initialization code for the sandbox broker services.
65 void InitializeBrokerServices(const MainFunctionParams& parameters, 28 void InitializeBrokerServices(const MainFunctionParams& parameters,
66 const CommandLine& parsed_command_line) { 29 const CommandLine& parsed_command_line) {
67 sandbox::BrokerServices* broker_services = 30 sandbox::BrokerServices* broker_services =
68 parameters.sandbox_info_.BrokerServices(); 31 parameters.sandbox_info_.BrokerServices();
69 if (broker_services) { 32 if (broker_services) {
70 sandbox::InitBrokerServices(broker_services); 33 sandbox::InitBrokerServices(broker_services);
71 if (!parsed_command_line.HasSwitch(switches::kNoSandbox)) { 34 if (!parsed_command_line.HasSwitch(switches::kNoSandbox)) {
72 bool use_winsta = !parsed_command_line.HasSwitch( 35 bool use_winsta = !parsed_command_line.HasSwitch(
73 switches::kDisableAltWinstation); 36 switches::kDisableAltWinstation);
74 // Precreate the desktop and window station used by the renderers. 37 // Precreate the desktop and window station used by the renderers.
75 sandbox::TargetPolicy* policy = broker_services->CreatePolicy(); 38 sandbox::TargetPolicy* policy = broker_services->CreatePolicy();
76 sandbox::ResultCode result = policy->CreateAlternateDesktop(use_winsta); 39 sandbox::ResultCode result = policy->CreateAlternateDesktop(use_winsta);
77 CHECK(sandbox::SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION != result); 40 CHECK(sandbox::SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION != result);
78 policy->Release(); 41 policy->Release();
79 } 42 }
80 } 43 }
81 } 44 }
82 #elif defined(OS_POSIX) && !defined(OS_MACOSX)
83 void SetupSandbox(const CommandLine& parsed_command_line) {
84 // TODO(evanm): move this into SandboxWrapper; I'm just trying to move this
85 // code en masse out of chrome_main for now.
86 const char* sandbox_binary = NULL;
87 struct stat st;
88
89 // In Chromium branded builds, developers can set an environment variable to
90 // use the development sandbox. See
91 // http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment
92 if (stat("/proc/self/exe", &st) == 0 && st.st_uid == getuid())
93 sandbox_binary = getenv("CHROME_DEVEL_SANDBOX");
94
95 #if defined(LINUX_SANDBOX_PATH)
96 if (!sandbox_binary)
97 sandbox_binary = LINUX_SANDBOX_PATH;
98 #endif 45 #endif
99 46
100 std::string sandbox_cmd; 47 bool g_exited_main_message_loop = false;
101 if (sandbox_binary && !parsed_command_line.HasSwitch(switches::kNoSandbox))
102 sandbox_cmd = sandbox_binary;
103
104 // Tickle the sandbox host and zygote host so they fork now.
105 RenderSandboxHostLinux* shost = RenderSandboxHostLinux::GetInstance();
106 shost->Init(sandbox_cmd);
107 ZygoteHost* zhost = ZygoteHost::GetInstance();
108 zhost->Init(sandbox_cmd);
109 }
110 #endif
111
112 #if defined(OS_LINUX)
113 static void GLibLogHandler(const gchar* log_domain,
114 GLogLevelFlags log_level,
115 const gchar* message,
116 gpointer userdata) {
117 if (!log_domain)
118 log_domain = "<unknown>";
119 if (!message)
120 message = "<no message>";
121
122 if (strstr(message, "Loading IM context type") ||
123 strstr(message, "wrong ELF class: ELFCLASS64")) {
124 // http://crbug.com/9643
125 // Until we have a real 64-bit build or all of these 32-bit package issues
126 // are sorted out, don't fatal on ELF 32/64-bit mismatch warnings and don't
127 // spam the user with more than one of them.
128 static bool alerted = false;
129 if (!alerted) {
130 LOG(ERROR) << "Bug 9643: " << log_domain << ": " << message;
131 alerted = true;
132 }
133 } else if (strstr(message, "Theme file for default has no") ||
134 strstr(message, "Theme directory") ||
135 strstr(message, "theme pixmap")) {
136 LOG(ERROR) << "GTK theme error: " << message;
137 } else if (strstr(message, "gtk_drag_dest_leave: assertion")) {
138 LOG(ERROR) << "Drag destination deleted: http://crbug.com/18557";
139 } else if (strstr(message, "Out of memory") &&
140 strstr(log_domain, "<unknown>")) {
141 LOG(ERROR) << "DBus call timeout or out of memory: "
142 << "http://crosbug.com/15496";
143 } else if (strstr(message, "XDG_RUNTIME_DIR variable not set")) {
144 LOG(ERROR) << message << " (http://bugs.chromium.org/97293)";
145 } else {
146 LOG(DFATAL) << log_domain << ": " << message;
147 }
148 }
149
150 static void SetUpGLibLogHandler() {
151 // Register GLib-handled assertions to go through our logging system.
152 const char* kLogDomains[] = { NULL, "Gtk", "Gdk", "GLib", "GLib-GObject" };
153 for (size_t i = 0; i < arraysize(kLogDomains); i++) {
154 g_log_set_handler(kLogDomains[i],
155 static_cast<GLogLevelFlags>(G_LOG_FLAG_RECURSION |
156 G_LOG_FLAG_FATAL |
157 G_LOG_LEVEL_ERROR |
158 G_LOG_LEVEL_CRITICAL |
159 G_LOG_LEVEL_WARNING),
160 GLibLogHandler,
161 NULL);
162 }
163 }
164 #endif
165 48
166 } // namespace 49 } // namespace
167 50
168 namespace content { 51 namespace content {
169 52
170 BrowserMainParts::BrowserMainParts(const MainFunctionParams& parameters)
171 : parameters_(parameters),
172 parsed_command_line_(parameters.command_line_),
173 result_code_(content::RESULT_CODE_NORMAL_EXIT) {
174 #if defined(OS_WIN)
175 OleInitialize(NULL);
176 #endif
177 }
178
179 BrowserMainParts::~BrowserMainParts() {
180 #if defined(OS_WIN)
181 OleUninitialize();
182 #endif
183 }
184
185 void BrowserMainParts::EarlyInitialization() {
186 PreEarlyInitialization();
187
188 #if defined(OS_WIN)
189 net::EnsureWinsockInit();
190 #endif
191
192 // Use NSS for SSL by default.
193 // The default client socket factory uses NSS for SSL by default on
194 // Windows and Mac.
195 #if defined(OS_WIN) || defined(OS_MACOSX)
196 if (parsed_command_line().HasSwitch(switches::kUseSystemSSL)) {
197 net::ClientSocketFactory::UseSystemSSL();
198 } else {
199 #elif defined(USE_NSS)
200 if (true) {
201 #else
202 if (false) {
203 #endif
204 // We want to be sure to init NSPR on the main thread.
205 crypto::EnsureNSPRInit();
206 }
207
208 #if defined(OS_POSIX) && !defined(OS_MACOSX)
209 SetupSandbox(parsed_command_line());
210 #endif
211
212 if (parsed_command_line().HasSwitch(switches::kDisableSSLFalseStart))
213 net::SSLConfigService::DisableFalseStart();
214 if (parsed_command_line().HasSwitch(switches::kEnableSSLCachedInfo))
215 net::SSLConfigService::EnableCachedInfo();
216 if (parsed_command_line().HasSwitch(switches::kEnableOriginBoundCerts))
217 net::SSLConfigService::EnableOriginBoundCerts();
218 if (parsed_command_line().HasSwitch(
219 switches::kEnableDNSCertProvenanceChecking)) {
220 net::SSLConfigService::EnableDNSCertProvenanceChecking();
221 }
222
223 // TODO(abarth): Should this move to InitializeNetworkOptions? This doesn't
224 // seem dependent on SSL initialization().
225 if (parsed_command_line().HasSwitch(switches::kEnableTcpFastOpen))
226 net::set_tcp_fastopen_enabled(true);
227
228 PostEarlyInitialization();
229 }
230
231 void BrowserMainParts::MainMessageLoopStart() {
232 PreMainMessageLoopStart();
233
234 #if defined(OS_WIN)
235 // If we're running tests (ui_task is non-null), then the ResourceBundle
236 // has already been initialized.
237 if (!parameters().ui_task) {
238 // Override the configured locale with the user's preferred UI language.
239 l10n_util::OverrideLocaleWithUILanguageList();
240 }
241 #endif
242
243 main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI));
244
245 InitializeMainThread();
246
247 system_monitor_.reset(new base::SystemMonitor);
248 hi_res_timer_manager_.reset(new HighResolutionTimerManager);
249
250 network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
251
252 PostMainMessageLoopStart();
253 }
254
255 static bool g_exited_main_message_loop = false;
256
257 void BrowserMainParts::RunMainMessageLoopParts() {
258 PreMainMessageLoopRun();
259
260 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
261 // If the UI thread blocks, the whole UI is unresponsive.
262 // Do not allow disk IO from the UI thread.
263 base::ThreadRestrictions::SetIOAllowed(false);
264 MainMessageLoopRun();
265 TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
266
267 g_exited_main_message_loop = true;
268
269 PostMainMessageLoopRun();
270 }
271
272 void BrowserMainParts::InitializeMainThread() {
273 const char* kThreadName = "CrBrowserMain";
274 base::PlatformThread::SetName(kThreadName);
275 main_message_loop().set_thread_name(kThreadName);
276
277 #if defined(TRACK_ALL_TASK_OBJECTS)
278 tracked_objects::ThreadData::InitializeThreadContext(kThreadName);
279 #endif // TRACK_ALL_TASK_OBJECTS
280
281 // Register the main thread by instantiating it, but don't call any methods.
282 main_thread_.reset(new BrowserThread(BrowserThread::UI,
283 MessageLoop::current()));
284 }
285
286 void BrowserMainParts::InitializeToolkit() {
287 // TODO(evan): this function is rather subtle, due to the variety
288 // of intersecting ifdefs we have. To keep it easy to follow, there
289 // are no #else branches on any #ifs.
290
291 #if defined(OS_LINUX)
292 // We want to call g_thread_init(), but in some codepaths (tests) it
293 // is possible it has already been called. In older versions of
294 // GTK, it is an error to call g_thread_init twice; unfortunately,
295 // the API to tell whether it has been called already was also only
296 // added in a newer version of GTK! Thankfully, this non-intuitive
297 // check is actually equivalent and sufficient to work around the
298 // error.
299 if (!g_thread_supported())
300 g_thread_init(NULL);
301 // Glib type system initialization. Needed at least for gconf,
302 // used in net/proxy/proxy_config_service_linux.cc. Most likely
303 // this is superfluous as gtk_init() ought to do this. It's
304 // definitely harmless, so retained as a reminder of this
305 // requirement for gconf.
306 g_type_init();
307 #if defined(OS_CHROMEOS)
308 // ChromeOS still uses dbus-glib, so initialize its threading here.
309 // TODO(satorux, stevenjb): remove this once it is no longer needed.
310 dbus_g_thread_init();
311 #endif
312 #if !defined(USE_AURA)
313 gfx::GtkInitFromCommandLine(parameters().command_line_);
314 #endif
315 SetUpGLibLogHandler();
316 #endif
317
318 #if defined(TOOLKIT_GTK)
319 // It is important for this to happen before the first run dialog, as it
320 // styles the dialog as well.
321 gfx::InitRCStyles();
322 #endif
323
324 #if defined(OS_WIN)
325 // Init common control sex.
326 INITCOMMONCONTROLSEX config;
327 config.dwSize = sizeof(config);
328 config.dwICC = ICC_WIN95_CLASSES;
329 if (!InitCommonControlsEx(&config))
330 LOG_GETLASTERROR(FATAL);
331 #endif
332
333 ToolkitInitialized();
334 }
335
336 void BrowserMainParts::PreEarlyInitialization() {
337 }
338
339 void BrowserMainParts::PostEarlyInitialization() {
340 }
341
342 void BrowserMainParts::PreMainMessageLoopStart() {
343 }
344
345 void BrowserMainParts::PostMainMessageLoopStart() {
346 }
347
348 void BrowserMainParts::PreMainMessageLoopRun() {
349 }
350
351 void BrowserMainParts::MainMessageLoopRun() {
352 if (parameters().ui_task)
353 MessageLoopForUI::current()->PostTask(FROM_HERE, parameters().ui_task);
354
355 #if defined(OS_MACOSX)
356 MessageLoopForUI::current()->Run();
357 #else
358 MessageLoopForUI::current()->RunWithDispatcher(NULL);
359 #endif
360 }
361
362 void BrowserMainParts::PostMainMessageLoopRun() {
363 }
364
365 void BrowserMainParts::ToolkitInitialized() {
366 }
367
368 bool ExitedMainMessageLoop() { 53 bool ExitedMainMessageLoop() {
369 return g_exited_main_message_loop; 54 return g_exited_main_message_loop;
370 } 55 }
371 56
372 } // namespace content 57 } // namespace content
373 58
374 // Main routine for running as the Browser process. 59 // Main routine for running as the Browser process.
375 int BrowserMain(const MainFunctionParams& parameters) { 60 int BrowserMain(const MainFunctionParams& parameters) {
376 TRACE_EVENT_BEGIN_ETW("BrowserMain", 0, ""); 61 TRACE_EVENT_BEGIN_ETW("BrowserMain", 0, "");
377 62
378 NotificationServiceImpl main_notification_service; 63 NotificationServiceImpl main_notification_service;
379 64
380 scoped_ptr<content::BrowserMainParts> parts( 65 scoped_ptr<content::BrowserMainLoop> main_loop(
381 content::GetContentClient()->browser()->CreateBrowserMainParts( 66 new content::BrowserMainLoop(parameters));
382 parameters));
383 if (!parts.get())
384 parts.reset(new content::BrowserMainParts(parameters));
385 67
386 parts->EarlyInitialization(); 68 main_loop->Init();
69
70 main_loop->EarlyInitialization();
387 71
388 // Must happen before we try to use a message loop or display any UI. 72 // Must happen before we try to use a message loop or display any UI.
389 parts->InitializeToolkit(); 73 main_loop->InitializeToolkit();
390 74
391 parts->MainMessageLoopStart(); 75 main_loop->MainMessageLoopStart();
392 76
393 // WARNING: If we get a WM_ENDSESSION, objects created on the stack here 77 // WARNING: If we get a WM_ENDSESSION, objects created on the stack here
394 // are NOT deleted. If you need something to run during WM_ENDSESSION add it 78 // are NOT deleted. If you need something to run during WM_ENDSESSION add it
395 // to browser_shutdown::Shutdown or BrowserProcess::EndSession. 79 // to browser_shutdown::Shutdown or BrowserProcess::EndSession.
396 80
397 // !!!!!!!!!! READ ME !!!!!!!!!! 81 // !!!!!!!!!! READ ME !!!!!!!!!!
398 // I (viettrungluu) am in the process of refactoring |BrowserMain()|. If you 82 // I (viettrungluu) am in the process of refactoring |BrowserMain()|. If you
399 // need to add something above this comment, read the documentation in 83 // need to add something above this comment, read the documentation in
400 // browser_main.h. If you need to add something below, please do the 84 // browser_main.h. If you need to add something below, please do the
401 // following: 85 // following:
(...skipping 25 matching lines...) Expand all
427 // initialize the sandbox broker, which requires the process to swap its 111 // initialize the sandbox broker, which requires the process to swap its
428 // window station. During this time all the UI will be broken. This has to 112 // window station. During this time all the UI will be broken. This has to
429 // run before threads and windows are created. 113 // run before threads and windows are created.
430 InitializeBrokerServices(parameters, parameters.command_line_); 114 InitializeBrokerServices(parameters, parameters.command_line_);
431 115
432 base::win::ScopedCOMInitializer com_initializer; 116 base::win::ScopedCOMInitializer com_initializer;
433 #endif // OS_WIN 117 #endif // OS_WIN
434 118
435 base::StatisticsRecorder statistics; 119 base::StatisticsRecorder statistics;
436 120
437 parts->RunMainMessageLoopParts(); 121 main_loop->RunMainMessageLoopParts(&g_exited_main_message_loop);
438 122
439 TRACE_EVENT_END_ETW("BrowserMain", 0, 0); 123 TRACE_EVENT_END_ETW("BrowserMain", 0, 0);
440 return parts->result_code(); 124
125 return main_loop->GetResultCode();
441 } 126 }
OLDNEW
« no previous file with comments | « content/browser/browser_main.h ('k') | content/browser/browser_main_loop.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698