OLD | NEW |
---|---|
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 Loading... | |
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 } | |
OLD | NEW |