| Index: content/browser/browser_main_loop.cc
|
| diff --git a/content/browser/browser_main.cc b/content/browser/browser_main_loop.cc
|
| similarity index 60%
|
| copy from content/browser/browser_main.cc
|
| copy to content/browser/browser_main_loop.cc
|
| index c0ef41ef31fe63f1c4e0bdaf71513f2b50626d9a..944d40c7e34f010b711dc38cc96fe6abcb2b953d 100644
|
| --- a/content/browser/browser_main.cc
|
| +++ b/content/browser/browser_main_loop.cc
|
| @@ -2,22 +2,21 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "content/browser/browser_main.h"
|
| +#include "content/browser/browser_main_loop.h"
|
|
|
| -#include "base/allocator/allocator_shim.h"
|
| #include "base/command_line.h"
|
| #include "base/debug/trace_event.h"
|
| #include "base/logging.h"
|
| +#include "base/message_loop.h"
|
| #include "base/metrics/field_trial.h"
|
| #include "base/metrics/histogram.h"
|
| -#include "base/system_monitor/system_monitor.h"
|
| #include "base/threading/thread_restrictions.h"
|
| #include "base/tracked_objects.h"
|
| #include "content/browser/browser_thread.h"
|
| -#include "content/browser/notification_service_impl.h"
|
| #include "content/common/hi_res_timer_manager.h"
|
| #include "content/common/main_function_params.h"
|
| #include "content/common/sandbox_policy.h"
|
| +#include "content/public/browser/browser_main_parts.h"
|
| #include "content/public/browser/content_browser_client.h"
|
| #include "content/public/common/content_switches.h"
|
| #include "content/public/common/result_codes.h"
|
| @@ -33,10 +32,8 @@
|
| #include <ole2.h>
|
| #include <shellapi.h>
|
|
|
| -#include "base/win/scoped_com_initializer.h"
|
| -#include "net/base/winsock_init.h"
|
| -#include "sandbox/src/sandbox.h"
|
| #include "ui/base/l10n/l10n_util_win.h"
|
| +#include "net/base/winsock_init.h"
|
| #endif
|
|
|
| #if defined(OS_LINUX)
|
| @@ -47,39 +44,19 @@
|
| #include <dbus/dbus-glib.h>
|
| #endif
|
|
|
| +#if defined(TOOLKIT_USES_GTK)
|
| +#include "ui/gfx/gtk_util.h"
|
| +#endif
|
| +
|
| #if defined(OS_POSIX) && !defined(OS_MACOSX)
|
| #include <sys/stat.h>
|
| -
|
| #include "content/browser/renderer_host/render_sandbox_host_linux.h"
|
| #include "content/browser/zygote_host_linux.h"
|
| #endif
|
|
|
| -#if defined(TOOLKIT_USES_GTK)
|
| -#include "ui/gfx/gtk_util.h"
|
| -#endif
|
| -
|
| namespace {
|
|
|
| -#if defined(OS_WIN)
|
| -// Windows-specific initialization code for the sandbox broker services.
|
| -void InitializeBrokerServices(const MainFunctionParams& parameters,
|
| - const CommandLine& parsed_command_line) {
|
| - sandbox::BrokerServices* broker_services =
|
| - parameters.sandbox_info_.BrokerServices();
|
| - if (broker_services) {
|
| - sandbox::InitBrokerServices(broker_services);
|
| - if (!parsed_command_line.HasSwitch(switches::kNoSandbox)) {
|
| - bool use_winsta = !parsed_command_line.HasSwitch(
|
| - switches::kDisableAltWinstation);
|
| - // Precreate the desktop and window station used by the renderers.
|
| - sandbox::TargetPolicy* policy = broker_services->CreatePolicy();
|
| - sandbox::ResultCode result = policy->CreateAlternateDesktop(use_winsta);
|
| - CHECK(sandbox::SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION != result);
|
| - policy->Release();
|
| - }
|
| - }
|
| -}
|
| -#elif defined(OS_POSIX) && !defined(OS_MACOSX)
|
| +#if defined(OS_POSIX) && !defined(OS_MACOSX)
|
| void SetupSandbox(const CommandLine& parsed_command_line) {
|
| // TODO(evanm): move this into SandboxWrapper; I'm just trying to move this
|
| // code en masse out of chrome_main for now.
|
| @@ -167,7 +144,10 @@ static void SetUpGLibLogHandler() {
|
|
|
| namespace content {
|
|
|
| -BrowserMainParts::BrowserMainParts(const MainFunctionParams& parameters)
|
| +
|
| +// BrowserMainLoop construction / destructione =============================
|
| +
|
| +BrowserMainLoop::BrowserMainLoop(const MainFunctionParams& parameters)
|
| : parameters_(parameters),
|
| parsed_command_line_(parameters.command_line_),
|
| result_code_(content::RESULT_CODE_NORMAL_EXIT) {
|
| @@ -176,14 +156,29 @@ BrowserMainParts::BrowserMainParts(const MainFunctionParams& parameters)
|
| #endif
|
| }
|
|
|
| -BrowserMainParts::~BrowserMainParts() {
|
| +BrowserMainLoop::~BrowserMainLoop() {
|
| + // Destroy added parts in reverse order.
|
| + for (int i = static_cast<int>(parts_list_.size())-1; i >= 0; --i)
|
| + delete parts_list_[i];
|
| + parts_list_.clear();
|
| +
|
| #if defined(OS_WIN)
|
| OleUninitialize();
|
| #endif
|
| }
|
|
|
| -void BrowserMainParts::EarlyInitialization() {
|
| - PreEarlyInitialization();
|
| +void BrowserMainLoop::Init() {
|
| + GetContentClient()->browser()->CreateBrowserMainParts(
|
| + parameters_, &parts_list_);
|
| +}
|
| +
|
| +// BrowserMainLoop stages ==================================================
|
| +
|
| +void BrowserMainLoop::EarlyInitialization() {
|
| + for (size_t i = 0; i < parts_list_.size(); ++i)
|
| + parts_list_[i]->PreEarlyInitialization();
|
| +
|
| + // Start watching for jank during shutdown. It gets disarmed when
|
|
|
| #if defined(OS_WIN)
|
| net::EnsureWinsockInit();
|
| @@ -192,49 +187,53 @@ void BrowserMainParts::EarlyInitialization() {
|
| // Use NSS for SSL by default.
|
| // The default client socket factory uses NSS for SSL by default on
|
| // Windows and Mac.
|
| + bool init_nspr = false;
|
| #if defined(OS_WIN) || defined(OS_MACOSX)
|
| - if (parsed_command_line().HasSwitch(switches::kUseSystemSSL)) {
|
| + if (parsed_command_line_.HasSwitch(switches::kUseSystemSSL)) {
|
| net::ClientSocketFactory::UseSystemSSL();
|
| } else {
|
| + init_nspr = true;
|
| + }
|
| #elif defined(USE_NSS)
|
| - if (true) {
|
| -#else
|
| - if (false) {
|
| + init_nspr = true;
|
| #endif
|
| + if (init_nspr) {
|
| // We want to be sure to init NSPR on the main thread.
|
| crypto::EnsureNSPRInit();
|
| }
|
|
|
| #if defined(OS_POSIX) && !defined(OS_MACOSX)
|
| - SetupSandbox(parsed_command_line());
|
| + SetupSandbox(parsed_command_line_);
|
| #endif
|
|
|
| - if (parsed_command_line().HasSwitch(switches::kDisableSSLFalseStart))
|
| + if (parsed_command_line_.HasSwitch(switches::kDisableSSLFalseStart))
|
| net::SSLConfigService::DisableFalseStart();
|
| - if (parsed_command_line().HasSwitch(switches::kEnableSSLCachedInfo))
|
| + if (parsed_command_line_.HasSwitch(switches::kEnableSSLCachedInfo))
|
| net::SSLConfigService::EnableCachedInfo();
|
| - if (parsed_command_line().HasSwitch(switches::kEnableOriginBoundCerts))
|
| + if (parsed_command_line_.HasSwitch(switches::kEnableOriginBoundCerts))
|
| net::SSLConfigService::EnableOriginBoundCerts();
|
| - if (parsed_command_line().HasSwitch(
|
| + if (parsed_command_line_.HasSwitch(
|
| switches::kEnableDNSCertProvenanceChecking)) {
|
| net::SSLConfigService::EnableDNSCertProvenanceChecking();
|
| }
|
|
|
| // TODO(abarth): Should this move to InitializeNetworkOptions? This doesn't
|
| // seem dependent on SSL initialization().
|
| - if (parsed_command_line().HasSwitch(switches::kEnableTcpFastOpen))
|
| + if (parsed_command_line_.HasSwitch(switches::kEnableTcpFastOpen))
|
| net::set_tcp_fastopen_enabled(true);
|
|
|
| - PostEarlyInitialization();
|
| + for (size_t i = 0; i < parts_list_.size(); ++i)
|
| + parts_list_[i]->PostEarlyInitialization();
|
| }
|
|
|
| -void BrowserMainParts::MainMessageLoopStart() {
|
| - PreMainMessageLoopStart();
|
| +void BrowserMainLoop::MainMessageLoopStart() {
|
| + for (size_t i = 0; i < parts_list_.size(); ++i)
|
| + parts_list_[i]->PreMainMessageLoopStart();
|
|
|
| #if defined(OS_WIN)
|
| // If we're running tests (ui_task is non-null), then the ResourceBundle
|
| // has already been initialized.
|
| - if (!parameters().ui_task) {
|
| + if (!parameters_.ui_task) {
|
| // Override the configured locale with the user's preferred UI language.
|
| l10n_util::OverrideLocaleWithUILanguageList();
|
| }
|
| @@ -249,30 +248,47 @@ void BrowserMainParts::MainMessageLoopStart() {
|
|
|
| network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
|
|
|
| - PostMainMessageLoopStart();
|
| + for (size_t i = 0; i < parts_list_.size(); ++i)
|
| + parts_list_[i]->PostMainMessageLoopStart();
|
| }
|
|
|
| -static bool g_exited_main_message_loop = false;
|
| -
|
| -void BrowserMainParts::RunMainMessageLoopParts() {
|
| - PreMainMessageLoopRun();
|
| +void BrowserMainLoop::RunMainMessageLoopParts(
|
| + bool* completed_main_message_loop) {
|
| + for (size_t i = 0; i < parts_list_.size(); ++i)
|
| + parts_list_[i]->PreMainMessageLoopRun();
|
|
|
| TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
|
| // If the UI thread blocks, the whole UI is unresponsive.
|
| // Do not allow disk IO from the UI thread.
|
| base::ThreadRestrictions::SetIOAllowed(false);
|
| - MainMessageLoopRun();
|
| +
|
| + // Iterate through each of the parts. If any of them ran the main
|
| + // message loop then they should return |true|. Otherwise
|
| + // BrowserMainLoop::MainMessageLoopRun loop will be run.
|
| + bool ran_main_loop = false;
|
| + for (size_t i = 0; i < parts_list_.size(); ++i) {
|
| + int result_code = result_code_;
|
| + if (parts_list_[i]->MainMessageLoopRun(&result_code)) {
|
| + ran_main_loop = true;
|
| + result_code_ = result_code;
|
| + }
|
| + }
|
| + if (!ran_main_loop)
|
| + MainMessageLoopRun();
|
| +
|
| TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
|
|
|
| - g_exited_main_message_loop = true;
|
| + if (completed_main_message_loop)
|
| + *completed_main_message_loop = true;
|
|
|
| - PostMainMessageLoopRun();
|
| + for (size_t i = 0; i < parts_list_.size(); ++i)
|
| + parts_list_[i]->PostMainMessageLoopRun();
|
| }
|
|
|
| -void BrowserMainParts::InitializeMainThread() {
|
| +void BrowserMainLoop::InitializeMainThread() {
|
| const char* kThreadName = "CrBrowserMain";
|
| base::PlatformThread::SetName(kThreadName);
|
| - main_message_loop().set_thread_name(kThreadName);
|
| + main_message_loop_->set_thread_name(kThreadName);
|
|
|
| #if defined(TRACK_ALL_TASK_OBJECTS)
|
| tracked_objects::ThreadData::InitializeThreadContext(kThreadName);
|
| @@ -283,11 +299,12 @@ void BrowserMainParts::InitializeMainThread() {
|
| MessageLoop::current()));
|
| }
|
|
|
| -void BrowserMainParts::InitializeToolkit() {
|
| +void BrowserMainLoop::InitializeToolkit() {
|
| // TODO(evan): this function is rather subtle, due to the variety
|
| // of intersecting ifdefs we have. To keep it easy to follow, there
|
| // are no #else branches on any #ifs.
|
| -
|
| + // TODO(stevenjb): Move platform specific code into platform specific Parts
|
| + // (Need to add InitializeToolkit stage to BrowserParts).
|
| #if defined(OS_LINUX)
|
| // We want to call g_thread_init(), but in some codepaths (tests) it
|
| // is possible it has already been called. In older versions of
|
| @@ -304,14 +321,17 @@ void BrowserMainParts::InitializeToolkit() {
|
| // definitely harmless, so retained as a reminder of this
|
| // requirement for gconf.
|
| g_type_init();
|
| +
|
| #if defined(OS_CHROMEOS)
|
| // ChromeOS still uses dbus-glib, so initialize its threading here.
|
| // TODO(satorux, stevenjb): remove this once it is no longer needed.
|
| dbus_g_thread_init();
|
| #endif
|
| +
|
| #if !defined(USE_AURA)
|
| - gfx::GtkInitFromCommandLine(parameters().command_line_);
|
| + gfx::GtkInitFromCommandLine(parameters_.command_line_);
|
| #endif
|
| +
|
| SetUpGLibLogHandler();
|
| #endif
|
|
|
| @@ -330,27 +350,13 @@ void BrowserMainParts::InitializeToolkit() {
|
| LOG_GETLASTERROR(FATAL);
|
| #endif
|
|
|
| - ToolkitInitialized();
|
| + for (size_t i = 0; i < parts_list_.size(); ++i)
|
| + parts_list_[i]->ToolkitInitialized();
|
| }
|
|
|
| -void BrowserMainParts::PreEarlyInitialization() {
|
| -}
|
| -
|
| -void BrowserMainParts::PostEarlyInitialization() {
|
| -}
|
| -
|
| -void BrowserMainParts::PreMainMessageLoopStart() {
|
| -}
|
| -
|
| -void BrowserMainParts::PostMainMessageLoopStart() {
|
| -}
|
| -
|
| -void BrowserMainParts::PreMainMessageLoopRun() {
|
| -}
|
| -
|
| -void BrowserMainParts::MainMessageLoopRun() {
|
| - if (parameters().ui_task)
|
| - MessageLoopForUI::current()->PostTask(FROM_HERE, parameters().ui_task);
|
| +void BrowserMainLoop::MainMessageLoopRun() {
|
| + if (parameters_.ui_task)
|
| + MessageLoopForUI::current()->PostTask(FROM_HERE, parameters_.ui_task);
|
|
|
| #if defined(OS_MACOSX)
|
| MessageLoopForUI::current()->Run();
|
| @@ -359,83 +365,4 @@ void BrowserMainParts::MainMessageLoopRun() {
|
| #endif
|
| }
|
|
|
| -void BrowserMainParts::PostMainMessageLoopRun() {
|
| -}
|
| -
|
| -void BrowserMainParts::ToolkitInitialized() {
|
| -}
|
| -
|
| -bool ExitedMainMessageLoop() {
|
| - return g_exited_main_message_loop;
|
| -}
|
| -
|
| } // namespace content
|
| -
|
| -// Main routine for running as the Browser process.
|
| -int BrowserMain(const MainFunctionParams& parameters) {
|
| - TRACE_EVENT_BEGIN_ETW("BrowserMain", 0, "");
|
| -
|
| - NotificationServiceImpl main_notification_service;
|
| -
|
| - scoped_ptr<content::BrowserMainParts> parts(
|
| - content::GetContentClient()->browser()->CreateBrowserMainParts(
|
| - parameters));
|
| - if (!parts.get())
|
| - parts.reset(new content::BrowserMainParts(parameters));
|
| -
|
| - parts->EarlyInitialization();
|
| -
|
| - // Must happen before we try to use a message loop or display any UI.
|
| - parts->InitializeToolkit();
|
| -
|
| - parts->MainMessageLoopStart();
|
| -
|
| - // WARNING: If we get a WM_ENDSESSION, objects created on the stack here
|
| - // are NOT deleted. If you need something to run during WM_ENDSESSION add it
|
| - // to browser_shutdown::Shutdown or BrowserProcess::EndSession.
|
| -
|
| - // !!!!!!!!!! READ ME !!!!!!!!!!
|
| - // I (viettrungluu) am in the process of refactoring |BrowserMain()|. If you
|
| - // need to add something above this comment, read the documentation in
|
| - // browser_main.h. If you need to add something below, please do the
|
| - // following:
|
| - // - Figure out where you should add your code. Do NOT just pick a random
|
| - // location "which works".
|
| - // - Document the dependencies apart from compile-time-checkable ones. What
|
| - // must happen before your new code is executed? Does your new code need to
|
| - // run before something else? Are there performance reasons for executing
|
| - // your code at that point?
|
| - // - If you need to create a (persistent) object, heap allocate it and keep a
|
| - // |scoped_ptr| to it rather than allocating it on the stack. Otherwise
|
| - // I'll have to convert your code when I refactor.
|
| - // - Unless your new code is just a couple of lines, factor it out into a
|
| - // function with a well-defined purpose. Do NOT just add it inline in
|
| - // |BrowserMain()|.
|
| - // Thanks!
|
| -
|
| - // TODO(viettrungluu): put the remainder into BrowserMainParts
|
| -
|
| -#if defined(OS_WIN)
|
| -#if !defined(NO_TCMALLOC)
|
| - // When linking shared libraries, NO_TCMALLOC is defined, and dynamic
|
| - // allocator selection is not supported.
|
| -
|
| - // Make this call before going multithreaded, or spawning any subprocesses.
|
| - base::allocator::SetupSubprocessAllocator();
|
| -#endif
|
| - // The broker service initialization needs to run early because it will
|
| - // initialize the sandbox broker, which requires the process to swap its
|
| - // window station. During this time all the UI will be broken. This has to
|
| - // run before threads and windows are created.
|
| - InitializeBrokerServices(parameters, parameters.command_line_);
|
| -
|
| - base::win::ScopedCOMInitializer com_initializer;
|
| -#endif // OS_WIN
|
| -
|
| - base::StatisticsRecorder statistics;
|
| -
|
| - parts->RunMainMessageLoopParts();
|
| -
|
| - TRACE_EVENT_END_ETW("BrowserMain", 0, 0);
|
| - return parts->result_code();
|
| -}
|
|
|