| 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" |
| 10 #include "base/message_loop.h" |
| 11 #include "base/metrics/field_trial.h" | 11 #include "base/metrics/field_trial.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/system_monitor/system_monitor.h" | |
| 14 #include "base/threading/thread_restrictions.h" | 13 #include "base/threading/thread_restrictions.h" |
| 15 #include "base/tracked_objects.h" | 14 #include "base/tracked_objects.h" |
| 16 #include "content/browser/browser_thread.h" | 15 #include "content/browser/browser_thread.h" |
| 17 #include "content/browser/notification_service_impl.h" | |
| 18 #include "content/common/hi_res_timer_manager.h" | 16 #include "content/common/hi_res_timer_manager.h" |
| 19 #include "content/common/main_function_params.h" | 17 #include "content/common/main_function_params.h" |
| 20 #include "content/common/sandbox_policy.h" | 18 #include "content/common/sandbox_policy.h" |
| 19 #include "content/public/browser/browser_main_parts.h" |
| 21 #include "content/public/browser/content_browser_client.h" | 20 #include "content/public/browser/content_browser_client.h" |
| 22 #include "content/public/common/content_switches.h" | 21 #include "content/public/common/content_switches.h" |
| 23 #include "content/public/common/result_codes.h" | 22 #include "content/public/common/result_codes.h" |
| 24 #include "crypto/nss_util.h" | 23 #include "crypto/nss_util.h" |
| 25 #include "net/base/network_change_notifier.h" | 24 #include "net/base/network_change_notifier.h" |
| 26 #include "net/base/ssl_config_service.h" | 25 #include "net/base/ssl_config_service.h" |
| 27 #include "net/socket/client_socket_factory.h" | 26 #include "net/socket/client_socket_factory.h" |
| 28 #include "net/socket/tcp_client_socket.h" | 27 #include "net/socket/tcp_client_socket.h" |
| 29 | 28 |
| 30 #if defined(OS_WIN) | 29 #if defined(OS_WIN) |
| 31 #include <windows.h> | 30 #include <windows.h> |
| 32 #include <commctrl.h> | 31 #include <commctrl.h> |
| 33 #include <ole2.h> | 32 #include <ole2.h> |
| 34 #include <shellapi.h> | 33 #include <shellapi.h> |
| 35 | 34 |
| 36 #include "base/win/scoped_com_initializer.h" | 35 #include "ui/base/l10n/l10n_util_win.h" |
| 37 #include "net/base/winsock_init.h" | 36 #include "net/base/winsock_init.h" |
| 38 #include "sandbox/src/sandbox.h" | |
| 39 #include "ui/base/l10n/l10n_util_win.h" | |
| 40 #endif | 37 #endif |
| 41 | 38 |
| 42 #if defined(OS_LINUX) | 39 #if defined(OS_LINUX) |
| 43 #include <glib-object.h> | 40 #include <glib-object.h> |
| 44 #endif | 41 #endif |
| 45 | 42 |
| 46 #if defined(OS_CHROMEOS) | 43 #if defined(OS_CHROMEOS) |
| 47 #include <dbus/dbus-glib.h> | 44 #include <dbus/dbus-glib.h> |
| 48 #endif | 45 #endif |
| 49 | 46 |
| 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) | 47 #if defined(TOOLKIT_USES_GTK) |
| 58 #include "ui/gfx/gtk_util.h" | 48 #include "ui/gfx/gtk_util.h" |
| 59 #endif | 49 #endif |
| 60 | 50 |
| 51 #if defined(OS_POSIX) && !defined(OS_MACOSX) |
| 52 #include <sys/stat.h> |
| 53 #include "content/browser/renderer_host/render_sandbox_host_linux.h" |
| 54 #include "content/browser/zygote_host_linux.h" |
| 55 #endif |
| 56 |
| 61 namespace { | 57 namespace { |
| 62 | 58 |
| 63 #if defined(OS_WIN) | 59 #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) { | 60 void SetupSandbox(const CommandLine& parsed_command_line) { |
| 84 // TODO(evanm): move this into SandboxWrapper; I'm just trying to move this | 61 // TODO(evanm): move this into SandboxWrapper; I'm just trying to move this |
| 85 // code en masse out of chrome_main for now. | 62 // code en masse out of chrome_main for now. |
| 86 const char* sandbox_binary = NULL; | 63 const char* sandbox_binary = NULL; |
| 87 struct stat st; | 64 struct stat st; |
| 88 | 65 |
| 89 // In Chromium branded builds, developers can set an environment variable to | 66 // In Chromium branded builds, developers can set an environment variable to |
| 90 // use the development sandbox. See | 67 // use the development sandbox. See |
| 91 // http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment | 68 // http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment |
| 92 if (stat("/proc/self/exe", &st) == 0 && st.st_uid == getuid()) | 69 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, | 137 GLibLogHandler, |
| 161 NULL); | 138 NULL); |
| 162 } | 139 } |
| 163 } | 140 } |
| 164 #endif | 141 #endif |
| 165 | 142 |
| 166 } // namespace | 143 } // namespace |
| 167 | 144 |
| 168 namespace content { | 145 namespace content { |
| 169 | 146 |
| 170 BrowserMainParts::BrowserMainParts(const MainFunctionParams& parameters) | 147 |
| 148 // BrowserMainLoop construction / destructione ============================= |
| 149 |
| 150 BrowserMainLoop::BrowserMainLoop(const MainFunctionParams& parameters) |
| 171 : parameters_(parameters), | 151 : parameters_(parameters), |
| 172 parsed_command_line_(parameters.command_line_), | 152 parsed_command_line_(parameters.command_line_), |
| 173 result_code_(content::RESULT_CODE_NORMAL_EXIT) { | 153 result_code_(content::RESULT_CODE_NORMAL_EXIT) { |
| 174 #if defined(OS_WIN) | 154 #if defined(OS_WIN) |
| 175 OleInitialize(NULL); | 155 OleInitialize(NULL); |
| 176 #endif | 156 #endif |
| 177 } | 157 } |
| 178 | 158 |
| 179 BrowserMainParts::~BrowserMainParts() { | 159 BrowserMainLoop::~BrowserMainLoop() { |
| 160 // Destroy added parts in reverse order. |
| 161 for (int i = static_cast<int>(parts_list_.size())-1; i >= 0; --i) |
| 162 delete parts_list_[i]; |
| 163 parts_list_.clear(); |
| 164 |
| 180 #if defined(OS_WIN) | 165 #if defined(OS_WIN) |
| 181 OleUninitialize(); | 166 OleUninitialize(); |
| 182 #endif | 167 #endif |
| 183 } | 168 } |
| 184 | 169 |
| 185 void BrowserMainParts::EarlyInitialization() { | 170 void BrowserMainLoop::Init() { |
| 186 PreEarlyInitialization(); | 171 GetContentClient()->browser()->CreateBrowserMainParts( |
| 172 parameters_, &parts_list_); |
| 173 } |
| 174 |
| 175 // BrowserMainLoop stages ================================================== |
| 176 |
| 177 void BrowserMainLoop::EarlyInitialization() { |
| 178 for (size_t i = 0; i < parts_list_.size(); ++i) |
| 179 parts_list_[i]->PreEarlyInitialization(); |
| 180 |
| 181 // Start watching for jank during shutdown. It gets disarmed when |
| 187 | 182 |
| 188 #if defined(OS_WIN) | 183 #if defined(OS_WIN) |
| 189 net::EnsureWinsockInit(); | 184 net::EnsureWinsockInit(); |
| 190 #endif | 185 #endif |
| 191 | 186 |
| 192 // Use NSS for SSL by default. | 187 // Use NSS for SSL by default. |
| 193 // The default client socket factory uses NSS for SSL by default on | 188 // The default client socket factory uses NSS for SSL by default on |
| 194 // Windows and Mac. | 189 // Windows and Mac. |
| 190 bool init_nspr = false; |
| 195 #if defined(OS_WIN) || defined(OS_MACOSX) | 191 #if defined(OS_WIN) || defined(OS_MACOSX) |
| 196 if (parsed_command_line().HasSwitch(switches::kUseSystemSSL)) { | 192 if (parsed_command_line_.HasSwitch(switches::kUseSystemSSL)) { |
| 197 net::ClientSocketFactory::UseSystemSSL(); | 193 net::ClientSocketFactory::UseSystemSSL(); |
| 198 } else { | 194 } else { |
| 195 init_nspr = true; |
| 196 } |
| 199 #elif defined(USE_NSS) | 197 #elif defined(USE_NSS) |
| 200 if (true) { | 198 init_nspr = true; |
| 201 #else | |
| 202 if (false) { | |
| 203 #endif | 199 #endif |
| 200 if (init_nspr) { |
| 204 // We want to be sure to init NSPR on the main thread. | 201 // We want to be sure to init NSPR on the main thread. |
| 205 crypto::EnsureNSPRInit(); | 202 crypto::EnsureNSPRInit(); |
| 206 } | 203 } |
| 207 | 204 |
| 208 #if defined(OS_POSIX) && !defined(OS_MACOSX) | 205 #if defined(OS_POSIX) && !defined(OS_MACOSX) |
| 209 SetupSandbox(parsed_command_line()); | 206 SetupSandbox(parsed_command_line_); |
| 210 #endif | 207 #endif |
| 211 | 208 |
| 212 if (parsed_command_line().HasSwitch(switches::kDisableSSLFalseStart)) | 209 if (parsed_command_line_.HasSwitch(switches::kDisableSSLFalseStart)) |
| 213 net::SSLConfigService::DisableFalseStart(); | 210 net::SSLConfigService::DisableFalseStart(); |
| 214 if (parsed_command_line().HasSwitch(switches::kEnableSSLCachedInfo)) | 211 if (parsed_command_line_.HasSwitch(switches::kEnableSSLCachedInfo)) |
| 215 net::SSLConfigService::EnableCachedInfo(); | 212 net::SSLConfigService::EnableCachedInfo(); |
| 216 if (parsed_command_line().HasSwitch(switches::kEnableOriginBoundCerts)) | 213 if (parsed_command_line_.HasSwitch(switches::kEnableOriginBoundCerts)) |
| 217 net::SSLConfigService::EnableOriginBoundCerts(); | 214 net::SSLConfigService::EnableOriginBoundCerts(); |
| 218 if (parsed_command_line().HasSwitch( | 215 if (parsed_command_line_.HasSwitch( |
| 219 switches::kEnableDNSCertProvenanceChecking)) { | 216 switches::kEnableDNSCertProvenanceChecking)) { |
| 220 net::SSLConfigService::EnableDNSCertProvenanceChecking(); | 217 net::SSLConfigService::EnableDNSCertProvenanceChecking(); |
| 221 } | 218 } |
| 222 | 219 |
| 223 // TODO(abarth): Should this move to InitializeNetworkOptions? This doesn't | 220 // TODO(abarth): Should this move to InitializeNetworkOptions? This doesn't |
| 224 // seem dependent on SSL initialization(). | 221 // seem dependent on SSL initialization(). |
| 225 if (parsed_command_line().HasSwitch(switches::kEnableTcpFastOpen)) | 222 if (parsed_command_line_.HasSwitch(switches::kEnableTcpFastOpen)) |
| 226 net::set_tcp_fastopen_enabled(true); | 223 net::set_tcp_fastopen_enabled(true); |
| 227 | 224 |
| 228 PostEarlyInitialization(); | 225 for (size_t i = 0; i < parts_list_.size(); ++i) |
| 226 parts_list_[i]->PostEarlyInitialization(); |
| 229 } | 227 } |
| 230 | 228 |
| 231 void BrowserMainParts::MainMessageLoopStart() { | 229 void BrowserMainLoop::MainMessageLoopStart() { |
| 232 PreMainMessageLoopStart(); | 230 for (size_t i = 0; i < parts_list_.size(); ++i) |
| 231 parts_list_[i]->PreMainMessageLoopStart(); |
| 233 | 232 |
| 234 #if defined(OS_WIN) | 233 #if defined(OS_WIN) |
| 235 // If we're running tests (ui_task is non-null), then the ResourceBundle | 234 // If we're running tests (ui_task is non-null), then the ResourceBundle |
| 236 // has already been initialized. | 235 // has already been initialized. |
| 237 if (!parameters().ui_task) { | 236 if (!parameters_.ui_task) { |
| 238 // Override the configured locale with the user's preferred UI language. | 237 // Override the configured locale with the user's preferred UI language. |
| 239 l10n_util::OverrideLocaleWithUILanguageList(); | 238 l10n_util::OverrideLocaleWithUILanguageList(); |
| 240 } | 239 } |
| 241 #endif | 240 #endif |
| 242 | 241 |
| 243 main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI)); | 242 main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI)); |
| 244 | 243 |
| 245 InitializeMainThread(); | 244 InitializeMainThread(); |
| 246 | 245 |
| 247 system_monitor_.reset(new base::SystemMonitor); | 246 system_monitor_.reset(new base::SystemMonitor); |
| 248 hi_res_timer_manager_.reset(new HighResolutionTimerManager); | 247 hi_res_timer_manager_.reset(new HighResolutionTimerManager); |
| 249 | 248 |
| 250 network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); | 249 network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); |
| 251 | 250 |
| 252 PostMainMessageLoopStart(); | 251 for (size_t i = 0; i < parts_list_.size(); ++i) |
| 252 parts_list_[i]->PostMainMessageLoopStart(); |
| 253 } | 253 } |
| 254 | 254 |
| 255 static bool g_exited_main_message_loop = false; | 255 void BrowserMainLoop::RunMainMessageLoopParts( |
| 256 | 256 bool* completed_main_message_loop) { |
| 257 void BrowserMainParts::RunMainMessageLoopParts() { | 257 for (size_t i = 0; i < parts_list_.size(); ++i) |
| 258 PreMainMessageLoopRun(); | 258 parts_list_[i]->PreMainMessageLoopRun(); |
| 259 | 259 |
| 260 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); | 260 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); |
| 261 // If the UI thread blocks, the whole UI is unresponsive. | 261 // If the UI thread blocks, the whole UI is unresponsive. |
| 262 // Do not allow disk IO from the UI thread. | 262 // Do not allow disk IO from the UI thread. |
| 263 base::ThreadRestrictions::SetIOAllowed(false); | 263 base::ThreadRestrictions::SetIOAllowed(false); |
| 264 MainMessageLoopRun(); | 264 |
| 265 // Iterate through each of the parts. If any of them ran the main |
| 266 // message loop then they should return |true|. Otherwise |
| 267 // BrowserMainLoop::MainMessageLoopRun loop will be run. |
| 268 bool ran_main_loop = false; |
| 269 for (size_t i = 0; i < parts_list_.size(); ++i) { |
| 270 int result_code = result_code_; |
| 271 if (parts_list_[i]->MainMessageLoopRun(&result_code)) { |
| 272 ran_main_loop = true; |
| 273 result_code_ = result_code; |
| 274 } |
| 275 } |
| 276 if (!ran_main_loop) |
| 277 MainMessageLoopRun(); |
| 278 |
| 265 TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); | 279 TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); |
| 266 | 280 |
| 267 g_exited_main_message_loop = true; | 281 if (completed_main_message_loop) |
| 282 *completed_main_message_loop = true; |
| 268 | 283 |
| 269 PostMainMessageLoopRun(); | 284 for (size_t i = 0; i < parts_list_.size(); ++i) |
| 285 parts_list_[i]->PostMainMessageLoopRun(); |
| 270 } | 286 } |
| 271 | 287 |
| 272 void BrowserMainParts::InitializeMainThread() { | 288 void BrowserMainLoop::InitializeMainThread() { |
| 273 const char* kThreadName = "CrBrowserMain"; | 289 const char* kThreadName = "CrBrowserMain"; |
| 274 base::PlatformThread::SetName(kThreadName); | 290 base::PlatformThread::SetName(kThreadName); |
| 275 main_message_loop().set_thread_name(kThreadName); | 291 main_message_loop_->set_thread_name(kThreadName); |
| 276 | 292 |
| 277 #if defined(TRACK_ALL_TASK_OBJECTS) | 293 #if defined(TRACK_ALL_TASK_OBJECTS) |
| 278 tracked_objects::ThreadData::InitializeThreadContext(kThreadName); | 294 tracked_objects::ThreadData::InitializeThreadContext(kThreadName); |
| 279 #endif // TRACK_ALL_TASK_OBJECTS | 295 #endif // TRACK_ALL_TASK_OBJECTS |
| 280 | 296 |
| 281 // Register the main thread by instantiating it, but don't call any methods. | 297 // Register the main thread by instantiating it, but don't call any methods. |
| 282 main_thread_.reset(new BrowserThread(BrowserThread::UI, | 298 main_thread_.reset(new BrowserThread(BrowserThread::UI, |
| 283 MessageLoop::current())); | 299 MessageLoop::current())); |
| 284 } | 300 } |
| 285 | 301 |
| 286 void BrowserMainParts::InitializeToolkit() { | 302 void BrowserMainLoop::InitializeToolkit() { |
| 287 // TODO(evan): this function is rather subtle, due to the variety | 303 // TODO(evan): this function is rather subtle, due to the variety |
| 288 // of intersecting ifdefs we have. To keep it easy to follow, there | 304 // of intersecting ifdefs we have. To keep it easy to follow, there |
| 289 // are no #else branches on any #ifs. | 305 // are no #else branches on any #ifs. |
| 290 | 306 // TODO(stevenjb): Move platform specific code into platform specific Parts |
| 307 // (Need to add InitializeToolkit stage to BrowserParts). |
| 291 #if defined(OS_LINUX) | 308 #if defined(OS_LINUX) |
| 292 // We want to call g_thread_init(), but in some codepaths (tests) it | 309 // 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 | 310 // is possible it has already been called. In older versions of |
| 294 // GTK, it is an error to call g_thread_init twice; unfortunately, | 311 // 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 | 312 // 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 | 313 // added in a newer version of GTK! Thankfully, this non-intuitive |
| 297 // check is actually equivalent and sufficient to work around the | 314 // check is actually equivalent and sufficient to work around the |
| 298 // error. | 315 // error. |
| 299 if (!g_thread_supported()) | 316 if (!g_thread_supported()) |
| 300 g_thread_init(NULL); | 317 g_thread_init(NULL); |
| 301 // Glib type system initialization. Needed at least for gconf, | 318 // Glib type system initialization. Needed at least for gconf, |
| 302 // used in net/proxy/proxy_config_service_linux.cc. Most likely | 319 // used in net/proxy/proxy_config_service_linux.cc. Most likely |
| 303 // this is superfluous as gtk_init() ought to do this. It's | 320 // this is superfluous as gtk_init() ought to do this. It's |
| 304 // definitely harmless, so retained as a reminder of this | 321 // definitely harmless, so retained as a reminder of this |
| 305 // requirement for gconf. | 322 // requirement for gconf. |
| 306 g_type_init(); | 323 g_type_init(); |
| 324 |
| 307 #if defined(OS_CHROMEOS) | 325 #if defined(OS_CHROMEOS) |
| 308 // ChromeOS still uses dbus-glib, so initialize its threading here. | 326 // ChromeOS still uses dbus-glib, so initialize its threading here. |
| 309 // TODO(satorux, stevenjb): remove this once it is no longer needed. | 327 // TODO(satorux, stevenjb): remove this once it is no longer needed. |
| 310 dbus_g_thread_init(); | 328 dbus_g_thread_init(); |
| 311 #endif | 329 #endif |
| 330 |
| 312 #if !defined(USE_AURA) | 331 #if !defined(USE_AURA) |
| 313 gfx::GtkInitFromCommandLine(parameters().command_line_); | 332 gfx::GtkInitFromCommandLine(parameters_.command_line_); |
| 314 #endif | 333 #endif |
| 334 |
| 315 SetUpGLibLogHandler(); | 335 SetUpGLibLogHandler(); |
| 316 #endif | 336 #endif |
| 317 | 337 |
| 318 #if defined(TOOLKIT_GTK) | 338 #if defined(TOOLKIT_GTK) |
| 319 // It is important for this to happen before the first run dialog, as it | 339 // It is important for this to happen before the first run dialog, as it |
| 320 // styles the dialog as well. | 340 // styles the dialog as well. |
| 321 gfx::InitRCStyles(); | 341 gfx::InitRCStyles(); |
| 322 #endif | 342 #endif |
| 323 | 343 |
| 324 #if defined(OS_WIN) | 344 #if defined(OS_WIN) |
| 325 // Init common control sex. | 345 // Init common control sex. |
| 326 INITCOMMONCONTROLSEX config; | 346 INITCOMMONCONTROLSEX config; |
| 327 config.dwSize = sizeof(config); | 347 config.dwSize = sizeof(config); |
| 328 config.dwICC = ICC_WIN95_CLASSES; | 348 config.dwICC = ICC_WIN95_CLASSES; |
| 329 if (!InitCommonControlsEx(&config)) | 349 if (!InitCommonControlsEx(&config)) |
| 330 LOG_GETLASTERROR(FATAL); | 350 LOG_GETLASTERROR(FATAL); |
| 331 #endif | 351 #endif |
| 332 | 352 |
| 333 ToolkitInitialized(); | 353 for (size_t i = 0; i < parts_list_.size(); ++i) |
| 354 parts_list_[i]->ToolkitInitialized(); |
| 334 } | 355 } |
| 335 | 356 |
| 336 void BrowserMainParts::PreEarlyInitialization() { | 357 void BrowserMainLoop::MainMessageLoopRun() { |
| 337 } | 358 if (parameters_.ui_task) |
| 338 | 359 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 | 360 |
| 355 #if defined(OS_MACOSX) | 361 #if defined(OS_MACOSX) |
| 356 MessageLoopForUI::current()->Run(); | 362 MessageLoopForUI::current()->Run(); |
| 357 #else | 363 #else |
| 358 MessageLoopForUI::current()->RunWithDispatcher(NULL); | 364 MessageLoopForUI::current()->RunWithDispatcher(NULL); |
| 359 #endif | 365 #endif |
| 360 } | 366 } |
| 361 | 367 |
| 362 void BrowserMainParts::PostMainMessageLoopRun() { | |
| 363 } | |
| 364 | |
| 365 void BrowserMainParts::ToolkitInitialized() { | |
| 366 } | |
| 367 | |
| 368 bool ExitedMainMessageLoop() { | |
| 369 return g_exited_main_message_loop; | |
| 370 } | |
| 371 | |
| 372 } // namespace content | 368 } // 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 |