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

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

Issue 8302016: Make GTK and Aura parts orthogonal to OS parts (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Moved BrowserMainLoop into its own file, changed PreMainMessageLoopStart to return void 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
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_loop.h"
6 6
7 #include "base/allocator/allocator_shim.h"
8 #include "base/command_line.h" 7 #include "base/command_line.h"
9 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
10 #include "base/logging.h" 9 #include "base/logging.h"
11 #include "base/metrics/field_trial.h" 10 #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"
14 #include "base/threading/thread_restrictions.h" 12 #include "base/threading/thread_restrictions.h"
15 #include "base/tracked_objects.h" 13 #include "base/tracked_objects.h"
16 #include "content/browser/browser_thread.h"
17 #include "content/browser/notification_service_impl.h"
18 #include "content/common/hi_res_timer_manager.h"
19 #include "content/common/main_function_params.h"
20 #include "content/common/result_codes.h" 14 #include "content/common/result_codes.h"
21 #include "content/common/sandbox_policy.h" 15 #include "content/common/sandbox_policy.h"
16 #include "content/public/browser/browser_main_parts.h"
22 #include "content/public/browser/content_browser_client.h" 17 #include "content/public/browser/content_browser_client.h"
18 #include "content/public/common/content_client.h"
jam 2011/10/25 06:11:28 nit: by convention we don't include this when incl
stevenjb 2011/10/25 19:21:18 Done.
23 #include "content/public/common/content_switches.h" 19 #include "content/public/common/content_switches.h"
24 #include "crypto/nss_util.h" 20 #include "crypto/nss_util.h"
25 #include "net/base/network_change_notifier.h"
26 #include "net/base/ssl_config_service.h" 21 #include "net/base/ssl_config_service.h"
27 #include "net/socket/client_socket_factory.h" 22 #include "net/socket/client_socket_factory.h"
28 #include "net/socket/tcp_client_socket.h" 23 #include "net/socket/tcp_client_socket.h"
29 24
30 #if defined(OS_WIN) 25 #if defined(OS_WIN)
31 #include <windows.h> 26 #include <windows.h>
32 #include <commctrl.h> 27 #include <commctrl.h>
33 #include <ole2.h> 28 #include <ole2.h>
34 #include <shellapi.h> 29 #include <shellapi.h>
35 30
36 #include "base/win/scoped_com_initializer.h" 31 #include "ui/base/l10n/l10n_util_win.h"
37 #include "net/base/winsock_init.h" 32 #include "net/base/winsock_init.h"
38 #include "sandbox/src/sandbox.h"
39 #include "ui/base/l10n/l10n_util_win.h"
40 #endif 33 #endif
41 34
42 #if defined(OS_LINUX) 35 #if defined(OS_LINUX)
43 #include <glib-object.h> 36 #include <glib-object.h>
44 #endif 37 #endif
45 38
46 #if defined(OS_CHROMEOS) 39 #if defined(OS_CHROMEOS)
47 #include <dbus/dbus-glib.h> 40 #include <dbus/dbus-glib.h>
48 #endif 41 #endif
49 42
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) 43 #if defined(TOOLKIT_USES_GTK)
58 #include "ui/gfx/gtk_util.h" 44 #include "ui/gfx/gtk_util.h"
59 #endif 45 #endif
60 46
47 #if defined(OS_POSIX) && !defined(OS_MACOSX)
48 #include <sys/stat.h>
49 #include "content/browser/renderer_host/render_sandbox_host_linux.h"
50 #include "content/browser/zygote_host_linux.h"
51 #endif
52
61 namespace { 53 namespace {
62 54
63 #if defined(OS_WIN) 55 #if defined(OS_POSIX) && !defined(OS_MACOSX)
64 // Windows-specific initialization code for the sandbox broker services.
65 void InitializeBrokerServices(const MainFunctionParams& parameters,
66 const CommandLine& parsed_command_line) {
67 sandbox::BrokerServices* broker_services =
68 parameters.sandbox_info_.BrokerServices();
69 if (broker_services) {
70 sandbox::InitBrokerServices(broker_services);
71 if (!parsed_command_line.HasSwitch(switches::kNoSandbox)) {
72 bool use_winsta = !parsed_command_line.HasSwitch(
73 switches::kDisableAltWinstation);
74 // Precreate the desktop and window station used by the renderers.
75 sandbox::TargetPolicy* policy = broker_services->CreatePolicy();
76 sandbox::ResultCode result = policy->CreateAlternateDesktop(use_winsta);
77 CHECK(sandbox::SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION != result);
78 policy->Release();
79 }
80 }
81 }
82 #elif defined(OS_POSIX) && !defined(OS_MACOSX)
83 void SetupSandbox(const CommandLine& parsed_command_line) { 56 void SetupSandbox(const CommandLine& parsed_command_line) {
84 // TODO(evanm): move this into SandboxWrapper; I'm just trying to move this 57 // TODO(evanm): move this into SandboxWrapper; I'm just trying to move this
85 // code en masse out of chrome_main for now. 58 // code en masse out of chrome_main for now.
86 const char* sandbox_binary = NULL; 59 const char* sandbox_binary = NULL;
87 struct stat st; 60 struct stat st;
88 61
89 // In Chromium branded builds, developers can set an environment variable to 62 // In Chromium branded builds, developers can set an environment variable to
90 // use the development sandbox. See 63 // use the development sandbox. See
91 // http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment 64 // http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment
92 if (stat("/proc/self/exe", &st) == 0 && st.st_uid == getuid()) 65 if (stat("/proc/self/exe", &st) == 0 && st.st_uid == getuid())
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 GLibLogHandler, 133 GLibLogHandler,
161 NULL); 134 NULL);
162 } 135 }
163 } 136 }
164 #endif 137 #endif
165 138
166 } // namespace 139 } // namespace
167 140
168 namespace content { 141 namespace content {
169 142
170 BrowserMainParts::BrowserMainParts(const MainFunctionParams& parameters) 143 class BrowserMainLoopImpl : public BrowserMainLoop {
144 public:
145 explicit BrowserMainLoopImpl(const MainFunctionParams& parameters);
146 virtual ~BrowserMainLoopImpl();
147
148 void Init();
149
150 // BrowserMainLoop implementation
151 virtual void EarlyInitialization() OVERRIDE;
152 virtual void InitializeToolkit() OVERRIDE;
153 virtual void MainMessageLoopStart() OVERRIDE;
154 virtual void RunMainMessageLoopParts(
155 bool* completed_main_message_loop) OVERRIDE;
156 virtual void MainMessageLoopRun() OVERRIDE;
157
158 virtual int GetResultCode() const OVERRIDE { return result_code_; }
159
160 private:
161 void InitializeMainThread();
162
163 // Members initialized on construction ---------------------------------------
164
165 const MainFunctionParams& parameters_;
166 const CommandLine& parsed_command_line_;
167 int result_code_;
168
169 // Vector of BrowserMainParts set by CreateBrowserMainParts ------------------
170 // The BrowserParts fucntions for each part are called in the order added.
171 // They are released (destroyed) in the reverse order.
172 std::vector<BrowserMainParts*> parts_;
173
174 // Members initialized in |MainMessageLoopStart()| ---------------------------
175 scoped_ptr<MessageLoop> main_message_loop_;
176 scoped_ptr<base::SystemMonitor> system_monitor_;
177 scoped_ptr<HighResolutionTimerManager> hi_res_timer_manager_;
178 scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_;
179 scoped_ptr<BrowserThread> main_thread_;
180
181 DISALLOW_COPY_AND_ASSIGN(BrowserMainLoopImpl);
182 };
183
184 // BrowserMainLoopImpl construction / destructione =============================
185
186 BrowserMainLoopImpl::BrowserMainLoopImpl(const MainFunctionParams& parameters)
171 : parameters_(parameters), 187 : parameters_(parameters),
172 parsed_command_line_(parameters.command_line_), 188 parsed_command_line_(parameters.command_line_),
173 result_code_(content::RESULT_CODE_NORMAL_EXIT) { 189 result_code_(content::RESULT_CODE_NORMAL_EXIT) {
174 #if defined(OS_WIN) 190 #if defined(OS_WIN)
175 OleInitialize(NULL); 191 OleInitialize(NULL);
176 #endif 192 #endif
177 } 193 }
178 194
179 BrowserMainParts::~BrowserMainParts() { 195 BrowserMainLoopImpl::~BrowserMainLoopImpl() {
196 // Destroy added parts in reverse order.
197 for (size_t i = parts_.size()-1; i >= 0; --i)
198 delete parts_[i];
199 parts_.clear();
200
180 #if defined(OS_WIN) 201 #if defined(OS_WIN)
181 OleUninitialize(); 202 OleUninitialize();
182 #endif 203 #endif
183 } 204 }
184 205
185 void BrowserMainParts::EarlyInitialization() { 206 void BrowserMainLoopImpl::Init() {
186 PreEarlyInitialization(); 207 GetContentClient()->browser()->CreateBrowserMainParts(
208 parameters_, parts_);
209 }
210
211 // BrowserMainLoopImpl stages ==================================================
212
213 void BrowserMainLoopImpl::EarlyInitialization() {
214 for (size_t i = 0; i < parts_.size(); ++i)
215 parts_[i]->PreEarlyInitialization();
216
217 // Start watching for jank during shutdown. It gets disarmed when
187 218
188 #if defined(OS_WIN) 219 #if defined(OS_WIN)
189 net::EnsureWinsockInit(); 220 net::EnsureWinsockInit();
190 #endif 221 #endif
191 222
192 // Use NSS for SSL by default. 223 // Use NSS for SSL by default.
193 // The default client socket factory uses NSS for SSL by default on 224 // The default client socket factory uses NSS for SSL by default on
194 // Windows and Mac. 225 // Windows and Mac.
226 bool init_nspr = false;
195 #if defined(OS_WIN) || defined(OS_MACOSX) 227 #if defined(OS_WIN) || defined(OS_MACOSX)
196 if (parsed_command_line().HasSwitch(switches::kUseSystemSSL)) { 228 if (parsed_command_line_.HasSwitch(switches::kUseSystemSSL)) {
197 net::ClientSocketFactory::UseSystemSSL(); 229 net::ClientSocketFactory::UseSystemSSL();
198 } else { 230 } else {
231 init_nspr = true;
232 }
199 #elif defined(USE_NSS) 233 #elif defined(USE_NSS)
200 if (true) { 234 init_nspr = true;
201 #else
202 if (false) {
203 #endif 235 #endif
236 if (init_nspr) {
204 // We want to be sure to init NSPR on the main thread. 237 // We want to be sure to init NSPR on the main thread.
205 crypto::EnsureNSPRInit(); 238 crypto::EnsureNSPRInit();
206 } 239 }
207 240
208 #if defined(OS_POSIX) && !defined(OS_MACOSX) 241 #if defined(OS_POSIX) && !defined(OS_MACOSX)
209 SetupSandbox(parsed_command_line()); 242 SetupSandbox(parsed_command_line_);
210 #endif 243 #endif
211 244
212 if (parsed_command_line().HasSwitch(switches::kDisableSSLFalseStart)) 245 if (parsed_command_line_.HasSwitch(switches::kDisableSSLFalseStart))
213 net::SSLConfigService::DisableFalseStart(); 246 net::SSLConfigService::DisableFalseStart();
214 if (parsed_command_line().HasSwitch(switches::kEnableSSLCachedInfo)) 247 if (parsed_command_line_.HasSwitch(switches::kEnableSSLCachedInfo))
215 net::SSLConfigService::EnableCachedInfo(); 248 net::SSLConfigService::EnableCachedInfo();
216 if (parsed_command_line().HasSwitch(switches::kEnableOriginBoundCerts)) 249 if (parsed_command_line_.HasSwitch(switches::kEnableOriginBoundCerts))
217 net::SSLConfigService::EnableOriginBoundCerts(); 250 net::SSLConfigService::EnableOriginBoundCerts();
218 if (parsed_command_line().HasSwitch( 251 if (parsed_command_line_.HasSwitch(
219 switches::kEnableDNSCertProvenanceChecking)) { 252 switches::kEnableDNSCertProvenanceChecking)) {
220 net::SSLConfigService::EnableDNSCertProvenanceChecking(); 253 net::SSLConfigService::EnableDNSCertProvenanceChecking();
221 } 254 }
222 255
223 // TODO(abarth): Should this move to InitializeNetworkOptions? This doesn't 256 // TODO(abarth): Should this move to InitializeNetworkOptions? This doesn't
224 // seem dependent on SSL initialization(). 257 // seem dependent on SSL initialization().
225 if (parsed_command_line().HasSwitch(switches::kEnableTcpFastOpen)) 258 if (parsed_command_line_.HasSwitch(switches::kEnableTcpFastOpen))
226 net::set_tcp_fastopen_enabled(true); 259 net::set_tcp_fastopen_enabled(true);
227 260
228 PostEarlyInitialization(); 261 for (size_t i = 0; i < parts_.size(); ++i)
262 parts_[i]->PostEarlyInitialization();
229 } 263 }
230 264
231 void BrowserMainParts::MainMessageLoopStart() { 265 void BrowserMainLoopImpl::MainMessageLoopStart() {
232 PreMainMessageLoopStart(); 266 for (size_t i = 0; i < parts_.size(); ++i)
267 parts_[i]->PreMainMessageLoopStart();
233 268
234 #if defined(OS_WIN) 269 #if defined(OS_WIN)
235 // If we're running tests (ui_task is non-null), then the ResourceBundle 270 // If we're running tests (ui_task is non-null), then the ResourceBundle
236 // has already been initialized. 271 // has already been initialized.
237 if (!parameters().ui_task) { 272 if (!parameters_.ui_task) {
238 // Override the configured locale with the user's preferred UI language. 273 // Override the configured locale with the user's preferred UI language.
239 l10n_util::OverrideLocaleWithUILanguageList(); 274 l10n_util::OverrideLocaleWithUILanguageList();
240 } 275 }
241 #endif 276 #endif
242 277
243 main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI)); 278 main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI));
244 279
245 InitializeMainThread(); 280 InitializeMainThread();
246 281
247 system_monitor_.reset(new base::SystemMonitor); 282 system_monitor_.reset(new base::SystemMonitor);
248 hi_res_timer_manager_.reset(new HighResolutionTimerManager); 283 hi_res_timer_manager_.reset(new HighResolutionTimerManager);
249 284
250 network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); 285 network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
251 286
252 PostMainMessageLoopStart(); 287 for (size_t i = 0; i < parts_.size(); ++i)
288 parts_[i]->PostMainMessageLoopStart();
253 } 289 }
254 290
255 static bool g_exited_main_message_loop = false; 291 void BrowserMainLoopImpl::RunMainMessageLoopParts(
256 292 bool* completed_main_message_loop) {
257 void BrowserMainParts::RunMainMessageLoopParts() { 293 for (size_t i = 0; i < parts_.size(); ++i)
258 PreMainMessageLoopRun(); 294 parts_[i]->PreMainMessageLoopRun();
259 295
260 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); 296 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
261 // If the UI thread blocks, the whole UI is unresponsive. 297 // If the UI thread blocks, the whole UI is unresponsive.
262 // Do not allow disk IO from the UI thread. 298 // Do not allow disk IO from the UI thread.
263 base::ThreadRestrictions::SetIOAllowed(false); 299 base::ThreadRestrictions::SetIOAllowed(false);
264 MainMessageLoopRun(); 300
301 // Iterate through each of the parts. If any of them ran the main
302 // message loop then they should return |true|. Otherwise
303 // BrowserMainLoopImpl::MainMessageLoopRun loop will be run.
304 bool ran_main_loop = false;
305 for (size_t i = 0; i < parts_.size(); ++i) {
306 int result_code = result_code_;
307 if (parts_[i]->MainMessageLoopRun(&result_code)) {
308 ran_main_loop = true;
309 result_code_ = result_code;
310 }
311 }
312 if (!ran_main_loop)
313 MainMessageLoopRun();
314
265 TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); 315 TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
266 316
267 g_exited_main_message_loop = true; 317 if (completed_main_message_loop)
318 *completed_main_message_loop = true;
268 319
269 PostMainMessageLoopRun(); 320 for (size_t i = 0; i < parts_.size(); ++i)
321 parts_[i]->PostMainMessageLoopRun();
270 } 322 }
271 323
272 void BrowserMainParts::InitializeMainThread() { 324 void BrowserMainLoopImpl::InitializeMainThread() {
273 const char* kThreadName = "CrBrowserMain"; 325 const char* kThreadName = "CrBrowserMain";
274 base::PlatformThread::SetName(kThreadName); 326 base::PlatformThread::SetName(kThreadName);
275 main_message_loop().set_thread_name(kThreadName); 327 main_message_loop_->set_thread_name(kThreadName);
276 328
277 #if defined(TRACK_ALL_TASK_OBJECTS) 329 #if defined(TRACK_ALL_TASK_OBJECTS)
278 tracked_objects::ThreadData::InitializeThreadContext(kThreadName); 330 tracked_objects::ThreadData::InitializeThreadContext(kThreadName);
279 #endif // TRACK_ALL_TASK_OBJECTS 331 #endif // TRACK_ALL_TASK_OBJECTS
280 332
281 // Register the main thread by instantiating it, but don't call any methods. 333 // Register the main thread by instantiating it, but don't call any methods.
282 main_thread_.reset(new BrowserThread(BrowserThread::UI, 334 main_thread_.reset(new BrowserThread(BrowserThread::UI,
283 MessageLoop::current())); 335 MessageLoop::current()));
284 } 336 }
285 337
286 void BrowserMainParts::InitializeToolkit() { 338 void BrowserMainLoopImpl::InitializeToolkit() {
287 // TODO(evan): this function is rather subtle, due to the variety 339 // TODO(evan): this function is rather subtle, due to the variety
288 // of intersecting ifdefs we have. To keep it easy to follow, there 340 // of intersecting ifdefs we have. To keep it easy to follow, there
289 // are no #else branches on any #ifs. 341 // are no #else branches on any #ifs.
290 342 // TODO(stevenjb): Move platform specific code into platform specific Parts
343 // (Need to add InitializeToolkit stage to BrowserParts).
291 #if defined(OS_LINUX) 344 #if defined(OS_LINUX)
292 // We want to call g_thread_init(), but in some codepaths (tests) it 345 // 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 346 // is possible it has already been called. In older versions of
294 // GTK, it is an error to call g_thread_init twice; unfortunately, 347 // 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 348 // 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 349 // added in a newer version of GTK! Thankfully, this non-intuitive
297 // check is actually equivalent and sufficient to work around the 350 // check is actually equivalent and sufficient to work around the
298 // error. 351 // error.
299 if (!g_thread_supported()) 352 if (!g_thread_supported())
300 g_thread_init(NULL); 353 g_thread_init(NULL);
301 // Glib type system initialization. Needed at least for gconf, 354 // Glib type system initialization. Needed at least for gconf,
302 // used in net/proxy/proxy_config_service_linux.cc. Most likely 355 // used in net/proxy/proxy_config_service_linux.cc. Most likely
303 // this is superfluous as gtk_init() ought to do this. It's 356 // this is superfluous as gtk_init() ought to do this. It's
304 // definitely harmless, so retained as a reminder of this 357 // definitely harmless, so retained as a reminder of this
305 // requirement for gconf. 358 // requirement for gconf.
306 g_type_init(); 359 g_type_init();
360
307 #if defined(OS_CHROMEOS) 361 #if defined(OS_CHROMEOS)
308 // ChromeOS still uses dbus-glib, so initialize its threading here. 362 // ChromeOS still uses dbus-glib, so initialize its threading here.
309 // TODO(satorux, stevenjb): remove this once it is no longer needed. 363 // TODO(satorux, stevenjb): remove this once it is no longer needed.
310 dbus_g_thread_init(); 364 dbus_g_thread_init();
311 #endif 365 #endif
366
312 #if !defined(USE_AURA) 367 #if !defined(USE_AURA)
313 gfx::GtkInitFromCommandLine(parameters().command_line_); 368 gfx::GtkInitFromCommandLine(parameters_.command_line_);
314 #endif 369 #endif
370
315 SetUpGLibLogHandler(); 371 SetUpGLibLogHandler();
316 #endif 372 #endif
317 373
318 #if defined(TOOLKIT_GTK) 374 #if defined(TOOLKIT_GTK)
319 // It is important for this to happen before the first run dialog, as it 375 // It is important for this to happen before the first run dialog, as it
320 // styles the dialog as well. 376 // styles the dialog as well.
321 gfx::InitRCStyles(); 377 gfx::InitRCStyles();
322 #endif 378 #endif
323 379
324 #if defined(OS_WIN) 380 #if defined(OS_WIN)
325 // Init common control sex. 381 // Init common control sex.
326 INITCOMMONCONTROLSEX config; 382 INITCOMMONCONTROLSEX config;
327 config.dwSize = sizeof(config); 383 config.dwSize = sizeof(config);
328 config.dwICC = ICC_WIN95_CLASSES; 384 config.dwICC = ICC_WIN95_CLASSES;
329 if (!InitCommonControlsEx(&config)) 385 if (!InitCommonControlsEx(&config))
330 LOG_GETLASTERROR(FATAL); 386 LOG_GETLASTERROR(FATAL);
331 #endif 387 #endif
332 388
333 ToolkitInitialized(); 389 for (size_t i = 0; i < parts_.size(); ++i)
390 parts_[i]->ToolkitInitialized();
334 } 391 }
335 392
336 void BrowserMainParts::PreEarlyInitialization() { 393 void BrowserMainLoopImpl::MainMessageLoopRun() {
337 } 394 if (parameters_.ui_task)
338 395 MessageLoopForUI::current()->PostTask(FROM_HERE, parameters_.ui_task);
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 396
355 #if defined(OS_MACOSX) 397 #if defined(OS_MACOSX)
356 MessageLoopForUI::current()->Run(); 398 MessageLoopForUI::current()->Run();
357 #else 399 #else
358 MessageLoopForUI::current()->RunWithDispatcher(NULL); 400 MessageLoopForUI::current()->RunWithDispatcher(NULL);
359 #endif 401 #endif
360 } 402 }
361 403
362 void BrowserMainParts::PostMainMessageLoopRun() { 404 // BrowserMainLoop
363 }
364 405
365 void BrowserMainParts::ToolkitInitialized() { 406 // static
366 } 407 BrowserMainLoop* BrowserMainLoop::CreateInstance(
367 408 const MainFunctionParams& parameters) {
368 bool ExitedMainMessageLoop() { 409 BrowserMainLoopImpl* instance = new BrowserMainLoopImpl(parameters);
369 return g_exited_main_message_loop; 410 instance->Init();
411 return instance;
370 } 412 }
371 413
372 } // namespace content 414 } // namespace content
373
374 // Main routine for running as the Browser process.
375 int BrowserMain(const MainFunctionParams& parameters) {
376 TRACE_EVENT_BEGIN_ETW("BrowserMain", 0, "");
377
378 NotificationServiceImpl main_notification_service;
379
380 scoped_ptr<content::BrowserMainParts> parts(
381 content::GetContentClient()->browser()->CreateBrowserMainParts(
382 parameters));
383 if (!parts.get())
384 parts.reset(new content::BrowserMainParts(parameters));
385
386 parts->EarlyInitialization();
387
388 // Must happen before we try to use a message loop or display any UI.
389 parts->InitializeToolkit();
390
391 parts->MainMessageLoopStart();
392
393 // 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
395 // to browser_shutdown::Shutdown or BrowserProcess::EndSession.
396
397 // !!!!!!!!!! READ ME !!!!!!!!!!
398 // I (viettrungluu) am in the process of refactoring |BrowserMain()|. If you
399 // 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
401 // following:
402 // - Figure out where you should add your code. Do NOT just pick a random
403 // location "which works".
404 // - Document the dependencies apart from compile-time-checkable ones. What
405 // must happen before your new code is executed? Does your new code need to
406 // run before something else? Are there performance reasons for executing
407 // your code at that point?
408 // - If you need to create a (persistent) object, heap allocate it and keep a
409 // |scoped_ptr| to it rather than allocating it on the stack. Otherwise
410 // I'll have to convert your code when I refactor.
411 // - Unless your new code is just a couple of lines, factor it out into a
412 // function with a well-defined purpose. Do NOT just add it inline in
413 // |BrowserMain()|.
414 // Thanks!
415
416 // TODO(viettrungluu): put the remainder into BrowserMainParts
417
418 #if defined(OS_WIN)
419 #if !defined(NO_TCMALLOC)
420 // When linking shared libraries, NO_TCMALLOC is defined, and dynamic
421 // allocator selection is not supported.
422
423 // Make this call before going multithreaded, or spawning any subprocesses.
424 base::allocator::SetupSubprocessAllocator();
425 #endif
426 // The broker service initialization needs to run early because it will
427 // 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
429 // run before threads and windows are created.
430 InitializeBrokerServices(parameters, parameters.command_line_);
431
432 base::win::ScopedCOMInitializer com_initializer;
433 #endif // OS_WIN
434
435 base::StatisticsRecorder statistics;
436
437 parts->RunMainMessageLoopParts();
438
439 TRACE_EVENT_END_ETW("BrowserMain", 0, 0);
440 return parts->result_code();
441 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698