diff options
37 files changed, 977 insertions, 741 deletions
diff --git a/chrome/app/breakpad_win.cc b/chrome/app/breakpad_win.cc index 06a0393..ae96306 100644 --- a/chrome/app/breakpad_win.cc +++ b/chrome/app/breakpad_win.cc @@ -526,7 +526,8 @@ bool ShowRestartDialogIfCrashed(bool* exit_now) { restart_data, len); restart_data[len] = 0; // The CHROME_RESTART var contains the dialog strings separated by '|'. - // See PrepareRestartOnCrashEnviroment() function for details. + // See ChromeBrowserMainPartsWin::PrepareRestartOnCrashEnviroment() + // for details. std::vector<std::wstring> dlg_strings; base::SplitString(restart_data, L'|', &dlg_strings); delete[] restart_data; diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 10a0a1f..2fb3af6 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc @@ -33,8 +33,6 @@ #include "chrome/browser/background/background_mode_manager.h" #include "chrome/browser/browser_process_impl.h" #include "chrome/browser/browser_shutdown.h" -#include "chrome/browser/chrome_browser_main_gtk.h" -#include "chrome/browser/chrome_browser_main_win.h" #include "chrome/browser/defaults.h" #include "chrome/browser/extensions/default_apps_trial.h" #include "chrome/browser/extensions/extension_protocols.h" @@ -121,10 +119,6 @@ #include "chrome/app/breakpad_linux.h" #endif -#if defined(TOOLKIT_USES_GTK) -#include "chrome/browser/ui/gtk/gtk_util.h" -#endif - #if defined(OS_LINUX) && !defined(OS_CHROMEOS) #include "chrome/browser/first_run/upgrade_util_linux.h" #endif @@ -161,6 +155,7 @@ #include "base/win/windows_version.h" #include "chrome/browser/browser_trial.h" #include "chrome/browser/browser_util_win.h" +#include "chrome/browser/chrome_browser_main_win.h" #include "chrome/browser/first_run/try_chrome_dialog_view.h" #include "chrome/browser/first_run/upgrade_util_win.h" #include "chrome/browser/fragmentation_checker_win.h" @@ -195,6 +190,7 @@ #endif #if defined(TOOLKIT_USES_GTK) +#include "chrome/browser/ui/gtk/gtk_util.h" #include "ui/gfx/gtk_util.h" #endif @@ -202,6 +198,10 @@ #include "ui/base/touch/touch_factory.h" #endif +#if defined(USE_X11) +#include "chrome/browser/chrome_browser_main_x11.h" +#endif + #if defined(USE_AURA) #include "chrome/browser/ui/views/aura/chrome_shell_delegate.h" #include "ui/aura/desktop.h" @@ -681,7 +681,9 @@ const char kMissingLocaleDataMessage[] = ChromeBrowserMainParts::ChromeBrowserMainParts( const MainFunctionParams& parameters) - : BrowserMainParts(parameters), + : parameters_(parameters), + parsed_command_line_(parameters.command_line_), + result_code_(content::RESULT_CODE_NORMAL_EXIT), shutdown_watcher_(new ShutdownWatcherHelper()), record_search_engine_(false), translate_manager_(NULL), @@ -698,12 +700,12 @@ ChromeBrowserMainParts::~ChromeBrowserMainParts() { // This will be called after the command-line has been mutated by about:flags MetricsService* ChromeBrowserMainParts::SetupMetricsAndFieldTrials( - const CommandLine& parsed_command_line, PrefService* local_state) { // Must initialize metrics after labs have been converted into switches, // but before field trials are set up (so that client ID is available for // one-time randomized field trials). - MetricsService* metrics = InitializeMetrics(parsed_command_line, local_state); + MetricsService* metrics = InitializeMetrics( + parsed_command_line_, local_state); // Initialize FieldTrialList to support FieldTrials that use one-time // randomization. The client ID will be empty if the user has not opted @@ -1176,10 +1178,10 @@ DLLEXPORT void __cdecl RelaunchChromeBrowserWithNewCommandLineIfNeeded() { #endif void ChromeBrowserMainParts::PreMainMessageLoopRun() { - set_result_code(PreMainMessageLoopRunInternal()); + result_code_ = PreMainMessageLoopRunImpl(); } -int ChromeBrowserMainParts::PreMainMessageLoopRunInternal() { +int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() { run_message_loop_ = false; FilePath user_data_dir; #if defined(OS_WIN) @@ -1382,8 +1384,7 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunInternal() { // Now the command line has been mutated based on about:flags, we can // set up metrics and initialize field trials. - MetricsService* metrics = - SetupMetricsAndFieldTrials(parsed_command_line(), local_state); + MetricsService* metrics = SetupMetricsAndFieldTrials(local_state); #if defined(USE_WEBKIT_COMPOSITOR) // We need to ensure WebKit has been initialized before we start the WebKit @@ -1472,12 +1473,14 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunInternal() { if (parsed_command_line().HasSwitch(switches::kUninstall)) { return DoUninstallTasks(already_running); } -#endif if (parsed_command_line().HasSwitch(switches::kHideIcons) || parsed_command_line().HasSwitch(switches::kShowIcons)) { - return HandleIconsCommands(parsed_command_line()); + return ChromeBrowserMainPartsWin::HandleIconsCommands( + parsed_command_line_); } +#endif + if (parsed_command_line().HasSwitch(switches::kMakeDefaultBrowser)) { return ShellIntegration::SetAsDefaultBrowser() ? static_cast<int>(content::RESULT_CODE_NORMAL_EXIT) : @@ -1630,7 +1633,6 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunInternal() { // Do the tasks if chrome has been upgraded while it was last running. if (!already_running && upgrade_util::DoUpgradeTasks(parsed_command_line())) return content::RESULT_CODE_NORMAL_EXIT; -#endif // Check if there is any machine level Chrome installed on the current // machine. If yes and the current Chrome process is user level, we do not @@ -1641,9 +1643,10 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunInternal() { // processes etc). // Do not allow this to occur for Chrome Frame user-to-system handoffs. if (!parsed_command_line().HasSwitch(switches::kChromeFrame) && - CheckMachineLevelInstall()) { + ChromeBrowserMainPartsWin::CheckMachineLevelInstall()) { return chrome::RESULT_CODE_MACHINE_LEVEL_INSTALL_EXISTS; } +#endif // Create the TranslateManager singleton. translate_manager_ = TranslateManager::GetInstance(); @@ -1691,26 +1694,24 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunInternal() { g_browser_process->profile_manager()->OnImportFinished(profile_); } // if (is_first_run) +#if defined(OS_WIN) // Sets things up so that if we crash from this point on, a dialog will // popup asking the user to restart chrome. It is done this late to avoid // testing against a bunch of special cases that are taken care early on. - PrepareRestartOnCrashEnviroment(parsed_command_line()); + ChromeBrowserMainPartsWin::PrepareRestartOnCrashEnviroment( + parsed_command_line()); - // Start watching for hangs during startup. We disarm this hang detector when - // ThreadWatcher takes over or when browser is shutdown. - StartupTimeBomb::Arm(base::TimeDelta::FromSeconds(300)); - -#if defined(OS_WIN) // Registers Chrome with the Windows Restart Manager, which will restore the // Chrome session when the computer is restarted after a system update. // This could be run as late as WM_QUERYENDSESSION for system update reboots, // but should run on startup if extended to handle crashes/hangs/patches. // Also, better to run once here than once for each HWND's WM_QUERYENDSESSION. - if (base::win::GetVersion() >= base::win::VERSION_VISTA) - RegisterApplicationRestart(parsed_command_line()); -#endif // OS_WIN + if (base::win::GetVersion() >= base::win::VERSION_VISTA) { + ChromeBrowserMainPartsWin::RegisterApplicationRestart( + parsed_command_line()); + } -#if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD) +#if defined(GOOGLE_CHROME_BUILD) // Init the RLZ library. This just binds the dll and schedules a task on the // file thread to be run sometime later. If this is the first run we record // the installation event. @@ -1743,7 +1744,12 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunInternal() { // for the startup page if needed (i.e., when the startup page is set to // the home page). RLZTracker::GetAccessPointRlz(rlz_lib::CHROME_HOME_PAGE, NULL); -#endif // GOOGLE_CHROME_BUILD && OS_WIN +#endif // GOOGLE_CHROME_BUILD +#endif // OS_WIN + + // Start watching for hangs during startup. We disarm this hang detector when + // ThreadWatcher takes over or when browser is shutdown. + StartupTimeBomb::Arm(base::TimeDelta::FromSeconds(300)); // Configure modules that need access to resources. net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider); @@ -1948,9 +1954,12 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunInternal() { return result_code; } -void ChromeBrowserMainParts::MainMessageLoopRun() { +bool ChromeBrowserMainParts::MainMessageLoopRun(int* result_code) { + // Set the result code set in PreMainMessageLoopRun. + *result_code = result_code_; + if (!run_message_loop_) - return; + return true; // Don't run the default message loop. // This should be invoked as close to the start of the browser's // UI thread message loop as possible to get a stable measurement @@ -1971,6 +1980,8 @@ void ChromeBrowserMainParts::MainMessageLoopRun() { chromeos::BootTimesLoader::Get()->AddLogoutTimeMarker("UIMessageLoopEnded", true); #endif + + return true; } void ChromeBrowserMainParts::PostMainMessageLoopRun() { diff --git a/chrome/browser/chrome_browser_main.h b/chrome/browser/chrome_browser_main.h index 95f2fea..817e8de 100644 --- a/chrome/browser/chrome_browser_main.h +++ b/chrome/browser/chrome_browser_main.h @@ -8,11 +8,12 @@ #include "base/basictypes.h" #include "base/gtest_prod_util.h" +#include "base/memory/scoped_ptr.h" #include "base/metrics/field_trial.h" #include "base/tracked_objects.h" #include "chrome/browser/first_run/first_run.h" #include "chrome/browser/process_singleton.h" -#include "content/browser/browser_main.h" +#include "content/public/browser/browser_main_parts.h" class BrowserProcessImpl; class FieldTrialSynchronizer; @@ -22,6 +23,7 @@ class PrefService; class Profile; class ShutdownWatcherHelper; class TranslateManager; +struct MainFunctionParams; namespace chrome_browser { // For use by ShowMissingLocaleMessageBox. @@ -36,18 +38,30 @@ class ChromeBrowserMainParts : public content::BrowserMainParts { // Constructs metrics service and does related initialization, including // creation of field trials. Call only after labs have been converted to // switches. - MetricsService* SetupMetricsAndFieldTrials( - const CommandLine& parsed_command_line, - PrefService* local_state); + MetricsService* SetupMetricsAndFieldTrials(PrefService* local_state); + + const MainFunctionParams& parameters() const { + return parameters_; + } + const CommandLine& parsed_command_line() const { + return parsed_command_line_; + } protected: explicit ChromeBrowserMainParts(const MainFunctionParams& parameters); - virtual void PreMainMessageLoopRun() OVERRIDE; - int PreMainMessageLoopRunInternal(); - virtual void MainMessageLoopRun() OVERRIDE; - virtual void PostMainMessageLoopRun() OVERRIDE; + // content::BrowserParts overrides + virtual void PreEarlyInitialization() OVERRIDE {} + virtual void PostEarlyInitialization() OVERRIDE {} + virtual void PreMainMessageLoopStart() OVERRIDE {} virtual void ToolkitInitialized() OVERRIDE; + virtual void PostMainMessageLoopStart() OVERRIDE {} + virtual void PreMainMessageLoopRun() OVERRIDE; + virtual bool MainMessageLoopRun(int* result_code) OVERRIDE; + virtual void PostMainMessageLoopRun(); + + // Displays a warning message that we can't find any locale data files. + virtual void ShowMissingLocaleMessageBox() = 0; private: // Methods for |EarlyInitialization()| --------------------------------------- @@ -89,8 +103,16 @@ class ChromeBrowserMainParts : public content::BrowserMainParts { void SetupFieldTrials(bool metrics_recording_enabled, bool proxy_policy_is_set); + // Methods for Main Message Loop ------------------------------------------- + + int PreMainMessageLoopRunImpl(); + // Members initialized on construction --------------------------------------- + const MainFunctionParams& parameters_; + const CommandLine& parsed_command_line_; + int result_code_; + // Create ShutdownWatcherHelper object for watching jank during shutdown. // Please keep |shutdown_watcher| as the first object constructed, and hence // it is destroyed last. @@ -138,9 +160,6 @@ void RecordBreakpadStatusUMA(MetricsService* metrics); // present on the current platform. void WarnAboutMinimumSystemRequirements(); -// Displays a warning message that we can't find any locale data files. -void ShowMissingLocaleMessageBox(); - // Records the time from our process' startup to the present time in // the UMA histogram |metric_name|. void RecordBrowserStartupTime(); diff --git a/chrome/browser/chrome_browser_main_aura.cc b/chrome/browser/chrome_browser_main_aura.cc deleted file mode 100644 index e795b38..0000000 --- a/chrome/browser/chrome_browser_main_aura.cc +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chrome_browser_main_aura.h" - -#include "base/logging.h" - -ChromeBrowserMainPartsAura::ChromeBrowserMainPartsAura( - const MainFunctionParams& parameters) - : ChromeBrowserMainParts(parameters) { - NOTIMPLEMENTED(); -} - -void ChromeBrowserMainPartsAura::PreEarlyInitialization() { - NOTIMPLEMENTED(); -} - -void ChromeBrowserMainPartsAura::PostMainMessageLoopStart() { - NOTIMPLEMENTED(); -} - -void ShowMissingLocaleMessageBox() { - NOTIMPLEMENTED(); -} diff --git a/chrome/browser/chrome_browser_main_aura.h b/chrome/browser/chrome_browser_main_aura.h deleted file mode 100644 index 3b11d4e..0000000 --- a/chrome/browser/chrome_browser_main_aura.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_CHROME_BROWSER_MAIN_AURA_H_ -#define CHROME_BROWSER_CHROME_BROWSER_MAIN_AURA_H_ - -#include "chrome/browser/chrome_browser_main.h" - -class ChromeBrowserMainPartsAura : public ChromeBrowserMainParts { - public: - explicit ChromeBrowserMainPartsAura(const MainFunctionParams& parameters); - - virtual void PreEarlyInitialization() OVERRIDE; - virtual void PostMainMessageLoopStart() OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainPartsAura); -}; - -#endif // CHROME_BROWSER_CHROME_BROWSER_MAIN_AURA_H_ diff --git a/chrome/browser/chrome_browser_main_gtk.h b/chrome/browser/chrome_browser_main_gtk.h deleted file mode 100644 index e55e4fe..0000000 --- a/chrome/browser/chrome_browser_main_gtk.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Contains functions used by BrowserMain() that are gtk-specific. - -#ifndef CHROME_BROWSER_CHROME_BROWSER_MAIN_GTK_H_ -#define CHROME_BROWSER_CHROME_BROWSER_MAIN_GTK_H_ -#pragma once - -#include "base/compiler_specific.h" -#include "chrome/browser/chrome_browser_main_posix.h" -#include "chrome/browser/chrome_browser_main_x11.h" - -class ChromeBrowserMainPartsGtk : public ChromeBrowserMainPartsPosix { - public: - explicit ChromeBrowserMainPartsGtk(const MainFunctionParams& parameters); - - virtual void PreEarlyInitialization() OVERRIDE; - - private: - void DetectRunningAsRoot(); -}; - -#endif // CHROME_BROWSER_CHROME_BROWSER_MAIN_GTK_H_ diff --git a/chrome/browser/chrome_browser_main_linux.cc b/chrome/browser/chrome_browser_main_linux.cc new file mode 100644 index 0000000..8e595ee --- /dev/null +++ b/chrome/browser/chrome_browser_main_linux.cc @@ -0,0 +1,29 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chrome_browser_main_linux.h" + +#if defined(USE_AURA) +#include "chrome/browser/chrome_browser_parts_aura.h" +#endif +#if defined(TOOLKIT_USES_GTK) +#include "chrome/browser/chrome_browser_parts_gtk.h" +#endif + +ChromeBrowserMainPartsLinux::ChromeBrowserMainPartsLinux( + const MainFunctionParams& parameters) + : ChromeBrowserMainPartsPosix(parameters) { +} + +void ChromeBrowserMainPartsLinux::ShowMissingLocaleMessageBox() { +#if defined(USE_AURA) + ChromeBrowserPartsAura::ShowMessageBox( + chrome_browser::kMissingLocaleDataMessage); +#elif defined(TOOLKIT_USES_GTK) + ChromeBrowserPartsGtk::ShowMessageBox( + chrome_browser::kMissingLocaleDataMessage); +#else +#error "Need MessageBox implementation for linux without Aura or Gtk" +#endif +} diff --git a/chrome/browser/chrome_browser_main_linux.h b/chrome/browser/chrome_browser_main_linux.h new file mode 100644 index 0000000..80f3e55 --- /dev/null +++ b/chrome/browser/chrome_browser_main_linux.h @@ -0,0 +1,22 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Contains functions used by BrowserMain() that are linux-specific. + +#ifndef CHROME_BROWSER_CHROME_BROWSER_MAIN_LINUX_H_ +#define CHROME_BROWSER_CHROME_BROWSER_MAIN_LINUX_H_ +#pragma once + +#include "base/compiler_specific.h" +#include "chrome/browser/chrome_browser_main_posix.h" + +class ChromeBrowserMainPartsLinux : public ChromeBrowserMainPartsPosix { + public: + explicit ChromeBrowserMainPartsLinux(const MainFunctionParams& parameters); + + // ChromeBrowserMainParts overrides. + virtual void ShowMissingLocaleMessageBox() OVERRIDE; +}; + +#endif // CHROME_BROWSER_CHROME_BROWSER_MAIN_LINUX_H_ diff --git a/chrome/browser/chrome_browser_main_mac.h b/chrome/browser/chrome_browser_main_mac.h index cf71045..2ba7e7b 100644 --- a/chrome/browser/chrome_browser_main_mac.h +++ b/chrome/browser/chrome_browser_main_mac.h @@ -12,9 +12,13 @@ class ChromeBrowserMainPartsMac : public ChromeBrowserMainPartsPosix { public: explicit ChromeBrowserMainPartsMac(const MainFunctionParams& parameters); + // BrowserParts overrides. virtual void PreEarlyInitialization() OVERRIDE; virtual void PreMainMessageLoopStart() OVERRIDE; + // ChromeBrowserMainParts overrides. + virtual void ShowMissingLocaleMessageBox() OVERRIDE; + // Perform platform-specific work that needs to be done after the main event // loop has ended. The embedder must be sure to call this. static void DidEndMainMessageLoop(); diff --git a/chrome/browser/chrome_browser_main_mac.mm b/chrome/browser/chrome_browser_main_mac.mm index fe7913d..99428ee 100644 --- a/chrome/browser/chrome_browser_main_mac.mm +++ b/chrome/browser/chrome_browser_main_mac.mm @@ -37,27 +37,12 @@ void WarnAboutMinimumSystemRequirements() { // Nothing to check for on Mac right now. } -void ShowMissingLocaleMessageBox() { - // Not called on Mac because we load the locale files differently. -} - // From browser_main_win.h, stubs until we figure out the right thing... int DoUninstallTasks(bool chrome_still_running) { return content::RESULT_CODE_NORMAL_EXIT; } -int HandleIconsCommands(const CommandLine& parsed_command_line) { - return 0; -} - -bool CheckMachineLevelInstall() { - return false; -} - -void PrepareRestartOnCrashEnviroment(const CommandLine& parsed_command_line) { -} - // ChromeBrowserMainPartsMac --------------------------------------------------- ChromeBrowserMainPartsMac::ChromeBrowserMainPartsMac( @@ -128,6 +113,11 @@ void ChromeBrowserMainPartsMac::PreMainMessageLoopStart() { setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"]; } +void ChromeBrowserMainPartsMac::ShowMissingLocaleMessageBox() { + // Not called on Mac because we load the locale files differently. + NOTREACHED(); +} + void ChromeBrowserMainPartsMac::DidEndMainMessageLoop() { AppController* appController = [NSApp delegate]; [appController didEndMainMessageLoop]; diff --git a/chrome/browser/chrome_browser_main_unittest.cc b/chrome/browser/chrome_browser_main_unittest.cc index e3c99b7..9bcd07f 100644 --- a/chrome/browser/chrome_browser_main_unittest.cc +++ b/chrome/browser/chrome_browser_main_unittest.cc @@ -6,6 +6,7 @@ #include <vector> #include "base/command_line.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" #include "chrome/browser/chrome_browser_main.h" #include "chrome/browser/chrome_content_browser_client.h" #include "chrome/common/chrome_switches.h" @@ -34,30 +35,37 @@ TEST_F(BrowserMainTest, WarmConnectionFieldTrial_WarmestSocket) { scoped_ptr<MainFunctionParams> params( new MainFunctionParams(command_line_, *sandbox_init_wrapper_, NULL)); - scoped_ptr<content::BrowserMainParts> bw( - content::GetContentClient()->browser()->CreateBrowserMainParts( - *params)); - - ChromeBrowserMainParts* cbw = static_cast<ChromeBrowserMainParts*>(bw.get()); - cbw->WarmConnectionFieldTrial(); - - EXPECT_EQ(0, net::GetSocketReusePolicy()); + ScopedVector<content::BrowserMainParts> bwv; + content::GetContentClient()->browser()->CreateBrowserMainParts( + *params, &(bwv.get())); + ChromeBrowserMainParts* cbw = NULL; + if (bwv.size() >= 1) + cbw = static_cast<ChromeBrowserMainParts*>(bwv[0]); + EXPECT_TRUE(cbw); + if (cbw) { + cbw->WarmConnectionFieldTrial(); + EXPECT_EQ(0, net::GetSocketReusePolicy()); + } } TEST_F(BrowserMainTest, WarmConnectionFieldTrial_Random) { scoped_ptr<MainFunctionParams> params( new MainFunctionParams(command_line_, *sandbox_init_wrapper_, NULL)); - scoped_ptr<content::BrowserMainParts> bw( - content::GetContentClient()->browser()->CreateBrowserMainParts( - *params)); - ChromeBrowserMainParts* cbw = static_cast<ChromeBrowserMainParts*>(bw.get()); - - const int kNumRuns = 1000; - for (int i = 0; i < kNumRuns; i++) { - cbw->WarmConnectionFieldTrial(); - int val = net::GetSocketReusePolicy(); - EXPECT_LE(val, 2); - EXPECT_GE(val, 0); + ScopedVector<content::BrowserMainParts> bwv; + content::GetContentClient()->browser()->CreateBrowserMainParts( + *params, &(bwv.get())); + ChromeBrowserMainParts* cbw = NULL; + if (bwv.size() >= 1) + cbw = static_cast<ChromeBrowserMainParts*>(bwv[0]); + EXPECT_TRUE(cbw); + if (cbw) { + const int kNumRuns = 1000; + for (int i = 0; i < kNumRuns; i++) { + cbw->WarmConnectionFieldTrial(); + int val = net::GetSocketReusePolicy(); + EXPECT_LE(val, 2); + EXPECT_GE(val, 0); + } } } @@ -68,20 +76,25 @@ TEST_F(BrowserMainTest, WarmConnectionFieldTrial_Invalid) { new MainFunctionParams(command_line_, *sandbox_init_wrapper_, NULL)); // This test ends up launching a new process, and that doesn't initialize the // ContentClient interfaces. - scoped_ptr<content::BrowserMainParts> bw; + ScopedVector<content::BrowserMainParts> bwv; if (content::GetContentClient()) { - bw.reset(content::GetContentClient()->browser()->CreateBrowserMainParts( - *params)); + content::GetContentClient()->browser()->CreateBrowserMainParts( + *params, &(bwv.get())); } else { chrome::ChromeContentBrowserClient ccbc; - bw.reset(ccbc.CreateBrowserMainParts(*params)); + ccbc.CreateBrowserMainParts(*params, &(bwv.get())); } - ChromeBrowserMainParts* cbw = static_cast<ChromeBrowserMainParts*>(bw.get()); + ChromeBrowserMainParts* cbw = NULL; + if (bwv.size() >= 1) + cbw = static_cast<ChromeBrowserMainParts*>(bwv[0]); + EXPECT_TRUE(cbw); + if (cbw) { #if defined(NDEBUG) && defined(DCHECK_ALWAYS_ON) - EXPECT_DEATH(cbw->WarmConnectionFieldTrial(), - "Not a valid socket reuse policy group"); + EXPECT_DEATH(cbw->WarmConnectionFieldTrial(), + "Not a valid socket reuse policy group"); #else - EXPECT_DEBUG_DEATH(cbw->WarmConnectionFieldTrial(), - "Not a valid socket reuse policy group"); + EXPECT_DEBUG_DEATH(cbw->WarmConnectionFieldTrial(), + "Not a valid socket reuse policy group"); #endif + } } diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc index f723969..6064a00 100644 --- a/chrome/browser/chrome_browser_main_win.cc +++ b/chrome/browser/chrome_browser_main_win.cc @@ -74,14 +74,6 @@ void WarnAboutMinimumSystemRequirements() { } } -#if !defined(USE_AURA) -void ShowMissingLocaleMessageBox() { - ui::MessageBox(NULL, ASCIIToUTF16(chrome_browser::kMissingLocaleDataMessage), - ASCIIToUTF16(chrome_browser::kMissingLocaleDataTitle), - MB_OK | MB_ICONERROR | MB_TOPMOST); -} -#endif - void RecordBrowserStartupTime() { // Calculate the time that has elapsed from our own process creation. FILETIME creation_time = {}; @@ -141,11 +133,23 @@ int DoUninstallTasks(bool chrome_still_running) { return ret; } -// Prepares the localized strings that are going to be displayed to -// the user if the browser process dies. These strings are stored in the -// environment block so they are accessible in the early stages of the -// chrome executable's lifetime. -void PrepareRestartOnCrashEnviroment(const CommandLine& parsed_command_line) { +// ChromeBrowserMainPartsWin --------------------------------------------------- + +ChromeBrowserMainPartsWin::ChromeBrowserMainPartsWin( + const MainFunctionParams& parameters) + : ChromeBrowserMainParts(parameters) { +} + +void ChromeBrowserMainPartsWin::PreMainMessageLoopStart() { + if (!parameters().ui_task) { + // Make sure that we know how to handle exceptions from the message loop. + InitializeWindowProcExceptions(); + } +} + +// static +void ChromeBrowserMainPartsWin::PrepareRestartOnCrashEnviroment( + const CommandLine& parsed_command_line) { // Clear this var so child processes don't show the dialog by default. scoped_ptr<base::Environment> env(base::Environment::Create()); env->UnSetVar(env_vars::kShowRestart); @@ -177,7 +181,9 @@ void PrepareRestartOnCrashEnviroment(const CommandLine& parsed_command_line) { env->SetVar(env_vars::kRestartInfo, UTF16ToUTF8(dlg_strings)); } -void RegisterApplicationRestart(const CommandLine& parsed_command_line) { +// static +void ChromeBrowserMainPartsWin::RegisterApplicationRestart( + const CommandLine& parsed_command_line) { DCHECK(base::win::GetVersion() >= base::win::VERSION_VISTA); base::ScopedNativeLibrary library(FilePath(L"kernel32.dll")); // Get the function pointer for RegisterApplicationRestart. @@ -207,11 +213,15 @@ void RegisterApplicationRestart(const CommandLine& parsed_command_line) { DCHECK(SUCCEEDED(hr)) << "RegisterApplicationRestart failed."; } -// This method handles the --hide-icons and --show-icons command line options -// for chrome that get triggered by Windows from registry entries -// HideIconsCommand & ShowIconsCommand. Chrome doesn't support hide icons -// functionality so we just ask the users if they want to uninstall Chrome. -int HandleIconsCommands(const CommandLine& parsed_command_line) { +void ChromeBrowserMainPartsWin::ShowMissingLocaleMessageBox() { + ui::MessageBox(NULL, ASCIIToUTF16(chrome_browser::kMissingLocaleDataMessage), + ASCIIToUTF16(chrome_browser::kMissingLocaleDataTitle), + MB_OK | MB_ICONERROR | MB_TOPMOST); +} + +// static +int ChromeBrowserMainPartsWin::HandleIconsCommands( + const CommandLine& parsed_command_line) { if (parsed_command_line.HasSwitch(switches::kHideIcons)) { string16 cp_applet; base::win::Version version = base::win::GetVersion(); @@ -237,11 +247,8 @@ int HandleIconsCommands(const CommandLine& parsed_command_line) { return chrome::RESULT_CODE_UNSUPPORTED_PARAM; } -// Check if there is any machine level Chrome installed on the current -// machine. If yes and the current Chrome process is user level, we do not -// allow the user level Chrome to run. So we notify the user and uninstall -// user level Chrome. -bool CheckMachineLevelInstall() { +// static +bool ChromeBrowserMainPartsWin::CheckMachineLevelInstall() { // TODO(tommi): Check if using the default distribution is always the right // thing to do. BrowserDistribution* dist = BrowserDistribution::GetDistribution(); @@ -270,17 +277,3 @@ bool CheckMachineLevelInstall() { } return false; } - -// ChromeBrowserMainPartsWin --------------------------------------------------- - -ChromeBrowserMainPartsWin::ChromeBrowserMainPartsWin( - const MainFunctionParams& parameters) - : ChromeBrowserMainParts(parameters) { -} - -void ChromeBrowserMainPartsWin::PreMainMessageLoopStart() { - if (!parameters().ui_task) { - // Make sure that we know how to handle exceptions from the message loop. - InitializeWindowProcExceptions(); - } -} diff --git a/chrome/browser/chrome_browser_main_win.h b/chrome/browser/chrome_browser_main_win.h index c866211..f54f557 100644 --- a/chrome/browser/chrome_browser_main_win.h +++ b/chrome/browser/chrome_browser_main_win.h @@ -17,33 +17,39 @@ class CommandLine; // user to close the other chrome instance. int DoUninstallTasks(bool chrome_still_running); -// Prepares the localized strings that are going to be displayed to -// the user if the browser process dies. These strings are stored in the -// environment block so they are accessible in the early stages of the -// chrome executable's lifetime. -void PrepareRestartOnCrashEnviroment(const CommandLine& parsed_command_line); - -// Registers Chrome with the Windows Restart Manager, which will restore the -// Chrome session when the computer is restarted after a system update. -void RegisterApplicationRestart(const CommandLine& parsed_command_line); - -// This method handles the --hide-icons and --show-icons command line options -// for chrome that get triggered by Windows from registry entries -// HideIconsCommand & ShowIconsCommand. Chrome doesn't support hide icons -// functionality so we just ask the users if they want to uninstall Chrome. -int HandleIconsCommands(const CommandLine& parsed_command_line); - -// Check if there is any machine level Chrome installed on the current -// machine. If yes and the current Chrome process is user level, we do not -// allow the user level Chrome to run. So we notify the user and uninstall -// user level Chrome. -bool CheckMachineLevelInstall(); - class ChromeBrowserMainPartsWin : public ChromeBrowserMainParts { public: explicit ChromeBrowserMainPartsWin(const MainFunctionParams& parameters); + // BrowserParts overrides. virtual void PreMainMessageLoopStart() OVERRIDE; + + // ChromeBrowserMainParts overrides. + virtual void ShowMissingLocaleMessageBox() OVERRIDE; + + // Prepares the localized strings that are going to be displayed to + // the user if the browser process dies. These strings are stored in the + // environment block so they are accessible in the early stages of the + // chrome executable's lifetime. + static void PrepareRestartOnCrashEnviroment( + const CommandLine& parsed_command_line); + + // Registers Chrome with the Windows Restart Manager, which will restore the + // Chrome session when the computer is restarted after a system update. + static void RegisterApplicationRestart( + const CommandLine& parsed_command_line); + + // This method handles the --hide-icons and --show-icons command line options + // for chrome that get triggered by Windows from registry entries + // HideIconsCommand & ShowIconsCommand. Chrome doesn't support hide icons + // functionality so we just ask the users if they want to uninstall Chrome. + static int HandleIconsCommands(const CommandLine& parsed_command_line); + + // Check if there is any machine level Chrome installed on the current + // machine. If yes and the current Chrome process is user level, we do not + // allow the user level Chrome to run. So we notify the user and uninstall + // user level Chrome. + static bool CheckMachineLevelInstall(); }; #endif // CHROME_BROWSER_CHROME_BROWSER_MAIN_WIN_H_ diff --git a/chrome/browser/chrome_browser_main_x11.cc b/chrome/browser/chrome_browser_main_x11.cc index adc8ae1..e7986f1 100644 --- a/chrome/browser/chrome_browser_main_x11.cc +++ b/chrome/browser/chrome_browser_main_x11.cc @@ -88,17 +88,6 @@ int DoUninstallTasks(bool chrome_still_running) { return content::RESULT_CODE_NORMAL_EXIT; } -int HandleIconsCommands(const CommandLine &parsed_command_line) { - return 0; -} - -bool CheckMachineLevelInstall() { - return false; -} - -void PrepareRestartOnCrashEnviroment(const CommandLine &parsed_command_line) { -} - void SetBrowserX11ErrorHandlers() { // Set up error handlers to make sure profile gets written if X server // goes away. diff --git a/chrome/browser/chrome_browser_parts_aura.cc b/chrome/browser/chrome_browser_parts_aura.cc new file mode 100644 index 0000000..5ebe45f --- /dev/null +++ b/chrome/browser/chrome_browser_parts_aura.cc @@ -0,0 +1,28 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chrome_browser_parts_aura.h" + +#include "base/logging.h" + +ChromeBrowserPartsAura::ChromeBrowserPartsAura() + : content::BrowserMainParts() { +} + +void ChromeBrowserPartsAura::PreEarlyInitialization() { + NOTIMPLEMENTED(); +} + +bool ChromeBrowserPartsAura::MainMessageLoopRun(int* result_code) { + return false; +} + +void ChromeBrowserPartsAura::PostMainMessageLoopStart() { + NOTIMPLEMENTED(); +} + +void ChromeBrowserPartsAura::ShowMessageBox(const char* message) { + LOG(ERROR) << "ShowMessageBox (not implemented): " << message; + NOTIMPLEMENTED(); +} diff --git a/chrome/browser/chrome_browser_parts_aura.h b/chrome/browser/chrome_browser_parts_aura.h new file mode 100644 index 0000000..d2fdc70 --- /dev/null +++ b/chrome/browser/chrome_browser_parts_aura.h @@ -0,0 +1,31 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROME_BROWSER_PARTS_AURA_H_ +#define CHROME_BROWSER_CHROME_BROWSER_PARTS_AURA_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "content/public/browser/browser_main_parts.h" + +class ChromeBrowserPartsAura : public content::BrowserMainParts { + public: + ChromeBrowserPartsAura(); + + virtual void PreEarlyInitialization() OVERRIDE; + virtual void PostEarlyInitialization() OVERRIDE {} + virtual void PreMainMessageLoopStart() OVERRIDE {} + virtual void ToolkitInitialized() OVERRIDE {} + virtual void PostMainMessageLoopStart() OVERRIDE; + virtual void PreMainMessageLoopRun() OVERRIDE {} + virtual bool MainMessageLoopRun(int* result_code) OVERRIDE; + virtual void PostMainMessageLoopRun() {} + + static void ShowMessageBox(const char* message); + + private: + DISALLOW_COPY_AND_ASSIGN(ChromeBrowserPartsAura); +}; + +#endif // CHROME_BROWSER_CHROME_BROWSER_PARTS_AURA_H_ diff --git a/chrome/browser/chrome_browser_main_gtk.cc b/chrome/browser/chrome_browser_parts_gtk.cc index abf3f7a..b51363f 100644 --- a/chrome/browser/chrome_browser_main_gtk.cc +++ b/chrome/browser/chrome_browser_parts_gtk.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chrome_browser_main_gtk.h" +#include "chrome/browser/chrome_browser_parts_gtk.h" #include <gtk/gtk.h> @@ -14,21 +14,22 @@ #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/gtk_util.h" -ChromeBrowserMainPartsGtk::ChromeBrowserMainPartsGtk( - const MainFunctionParams& parameters) - : ChromeBrowserMainPartsPosix(parameters) { +ChromeBrowserPartsGtk::ChromeBrowserPartsGtk() + : content::BrowserMainParts() { } -void ChromeBrowserMainPartsGtk::PreEarlyInitialization() { +void ChromeBrowserPartsGtk::PreEarlyInitialization() { DetectRunningAsRoot(); +} - ChromeBrowserMainPartsPosix::PreEarlyInitialization(); +bool ChromeBrowserPartsGtk::MainMessageLoopRun(int* result_code) { + return false; } -void ChromeBrowserMainPartsGtk::DetectRunningAsRoot() { +void ChromeBrowserPartsGtk::DetectRunningAsRoot() { if (geteuid() == 0) { const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - if (parsed_command_line().HasSwitch(switches::kUserDataDir)) + if (command_line.HasSwitch(switches::kUserDataDir)) return; gfx::GtkInitFromCommandLine(command_line); @@ -66,18 +67,17 @@ void ChromeBrowserMainPartsGtk::DetectRunningAsRoot() { } } -void ShowMissingLocaleMessageBox() { +// static +void ChromeBrowserPartsGtk::ShowMessageBox(const char* message) { GtkWidget* dialog = gtk_message_dialog_new( NULL, static_cast<GtkDialogFlags>(0), GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", - chrome_browser::kMissingLocaleDataMessage); - - gtk_window_set_title(GTK_WINDOW(dialog), - chrome_browser::kMissingLocaleDataTitle); + message); + gtk_window_set_title(GTK_WINDOW(dialog), message); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } diff --git a/chrome/browser/chrome_browser_parts_gtk.h b/chrome/browser/chrome_browser_parts_gtk.h new file mode 100644 index 0000000..8a19321 --- /dev/null +++ b/chrome/browser/chrome_browser_parts_gtk.h @@ -0,0 +1,33 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Contains functions used by BrowserMain() that are gtk-specific. + +#ifndef CHROME_BROWSER_CHROME_BROWSER_PARTS_GTK_H_ +#define CHROME_BROWSER_CHROME_BROWSER_PARTS_GTK_H_ +#pragma once + +#include "base/compiler_specific.h" +#include "content/public/browser/browser_main_parts.h" + +class ChromeBrowserPartsGtk : public content::BrowserMainParts { + public: + ChromeBrowserPartsGtk(); + + virtual void PreEarlyInitialization() OVERRIDE; + virtual void PostEarlyInitialization() OVERRIDE {} + virtual void PreMainMessageLoopStart() OVERRIDE {} + virtual void ToolkitInitialized() OVERRIDE {} + virtual void PostMainMessageLoopStart() OVERRIDE {} + virtual void PreMainMessageLoopRun() OVERRIDE {} + virtual bool MainMessageLoopRun(int* result_code) OVERRIDE; + virtual void PostMainMessageLoopRun() {} + + static void ShowMessageBox(const char* message); + + private: + void DetectRunningAsRoot(); +}; + +#endif // CHROME_BROWSER_CHROME_BROWSER_PARTS_GTK_H_ diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 9789afd..d1651a8 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -68,6 +68,7 @@ #include "content/browser/tab_contents/tab_contents_view.h" #include "content/browser/worker_host/worker_process_host.h" #include "content/common/desktop_notification_messages.h" +#include "content/public/browser/browser_main_parts.h" #include "grit/generated_resources.h" #include "grit/ui_resources.h" #include "net/base/cookie_monster.h" @@ -75,16 +76,24 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/chrome_browser_main_chromeos.h" -#elif defined(USE_AURA) -#include "chrome/browser/chrome_browser_main_aura.h" -#elif defined(OS_WIN) +#if defined(OS_WIN) #include "chrome/browser/chrome_browser_main_win.h" #elif defined(OS_MACOSX) #include "chrome/browser/chrome_browser_main_mac.h" -#elif defined(TOOLKIT_USES_GTK) -#include "chrome/browser/chrome_browser_main_gtk.h" +#elif defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/chrome_browser_main_chromeos.h" +#elif defined(OS_LINUX) +#include "chrome/browser/chrome_browser_main_linux.h" +#elif defined(OS_POSIX) +#include "chrome/browser/chrome_browser_main_posix.h" +#endif + +#if defined(USE_AURA) +#include "chrome/browser/chrome_browser_parts_aura.h" +#endif + +#if defined(TOOLKIT_USES_GTK) +#include "chrome/browser/chrome_browser_parts_gtk.h" #endif #if defined(OS_LINUX) @@ -104,7 +113,6 @@ #include "chrome/browser/ui/crypto_module_password_dialog.h" #endif - #if defined(USE_AURA) || defined(TOUCH_UI) #include "chrome/browser/renderer_host/render_widget_host_view_views.h" #elif defined(OS_WIN) @@ -191,20 +199,31 @@ RenderProcessHostPrivilege GetProcessPrivilege( namespace chrome { -content::BrowserMainParts* ChromeContentBrowserClient::CreateBrowserMainParts( - const MainFunctionParams& parameters) { -#if defined(OS_CHROMEOS) - return new ChromeBrowserMainPartsChromeos(parameters); -#elif defined(USE_AURA) - return new ChromeBrowserMainPartsAura(parameters); -#elif defined(OS_WIN) - return new ChromeBrowserMainPartsWin(parameters); +void ChromeContentBrowserClient::CreateBrowserMainParts( + const MainFunctionParams& parameters, + std::vector<content::BrowserMainParts*>* parts_list) { + // Construct the Main browser parts based on the OS type. +#if defined(OS_WIN) + parts_list->push_back(new ChromeBrowserMainPartsWin(parameters)); #elif defined(OS_MACOSX) - return new ChromeBrowserMainPartsMac(parameters); -#elif defined(TOOLKIT_USES_GTK) - return new ChromeBrowserMainPartsGtk(parameters); + parts_list->push_back(new ChromeBrowserMainPartsMac(parameters)); +#elif defined(OS_CHROMEOS) + parts_list->push_back(new ChromeBrowserMainPartsChromeos(parameters)); +#elif defined(OS_LINUX) + parts_list->push_back(new ChromeBrowserMainPartsLinux(parameters)); +#elif defined(OS_POSIX) + parts_list->push_back(new ChromeBrowserMainPartsPosix(parameters)); #else - return NULL; + NOTREACHED(); + parts_list->push_back(new ChromeBrowserMainParts(parameters)); +#endif + + // Construct additional browser parts. +#if defined(USE_AURA) + parts_list->push_back(new ChromeBrowserPartsAura()); +#endif +#if defined(TOOLKIT_USES_GTK) + parts_list->push_back(new ChromeBrowserPartsGtk()); #endif } diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index d8fb323..bb8d55a 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h @@ -15,8 +15,9 @@ namespace chrome { class ChromeContentBrowserClient : public content::ContentBrowserClient { public: - virtual content::BrowserMainParts* CreateBrowserMainParts( - const MainFunctionParams& parameters) OVERRIDE; + virtual void CreateBrowserMainParts( + const MainFunctionParams& parameters, + std::vector<content::BrowserMainParts*>* parts_list) OVERRIDE; virtual RenderWidgetHostView* CreateViewForWidget( RenderWidgetHost* widget) OVERRIDE; virtual TabContentsView* CreateTabContentsView( diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index 6ac1340..88a3535 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc @@ -71,7 +71,7 @@ static base::LazyInstance<MessageLoopObserver> g_message_loop_observer( ChromeBrowserMainPartsChromeos::ChromeBrowserMainPartsChromeos( const MainFunctionParams& parameters) - : ChromeBrowserMainPartsBase(parameters) { + : ChromeBrowserMainPartsLinux(parameters) { } ChromeBrowserMainPartsChromeos::~ChromeBrowserMainPartsChromeos() { @@ -99,7 +99,7 @@ ChromeBrowserMainPartsChromeos::~ChromeBrowserMainPartsChromeos() { } void ChromeBrowserMainPartsChromeos::PreEarlyInitialization() { - ChromeBrowserMainPartsBase::PreEarlyInitialization(); + ChromeBrowserMainPartsLinux::PreEarlyInitialization(); if (parsed_command_line().HasSwitch(switches::kGuestSession)) { // Disable sync and extensions if we're in "browse without sign-in" mode. CommandLine* singleton_command_line = CommandLine::ForCurrentProcess(); @@ -110,7 +110,7 @@ void ChromeBrowserMainPartsChromeos::PreEarlyInitialization() { } void ChromeBrowserMainPartsChromeos::PreMainMessageLoopStart() { - ChromeBrowserMainPartsBase::PreMainMessageLoopStart(); + ChromeBrowserMainPartsLinux::PreMainMessageLoopStart(); // Initialize CrosLibrary only for the browser, unless running tests // (which do their own CrosLibrary setup). if (!parameters().ui_task) { @@ -125,7 +125,7 @@ void ChromeBrowserMainPartsChromeos::PreMainMessageLoopStart() { void ChromeBrowserMainPartsChromeos::PreMainMessageLoopRun() { // FILE thread is created in ChromeBrowserMainParts::PreMainMessageLoopRun(). - ChromeBrowserMainPartsBase::PreMainMessageLoopRun(); + ChromeBrowserMainPartsLinux::PreMainMessageLoopRun(); // Get the statistics provider instance here to start loading statistcs // on the background FILE thread. chromeos::system::StatisticsProvider::GetInstance(); diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.h b/chrome/browser/chromeos/chrome_browser_main_chromeos.h index 2786642..790477f 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.h +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.h @@ -6,24 +6,16 @@ #define CHROME_BROWSER_CHROMEOS_CHROME_BROWSER_MAIN_CHROMEOS_H_ #include "base/memory/scoped_ptr.h" -#if defined(TOOLKIT_USES_GTK) -#include "chrome/browser/chrome_browser_main_gtk.h" -typedef ChromeBrowserMainPartsGtk ChromeBrowserMainPartsBase; -#else -#include "chrome/browser/chrome_browser_main_posix.h" -#include "chrome/browser/chrome_browser_main_x11.h" -typedef ChromeBrowserMainPartsPosix ChromeBrowserMainPartsBase; -#endif +#include "chrome/browser/chrome_browser_main_linux.h" namespace chromeos { class BrightnessObserver; class SessionManagerObserver; } // namespace chromeos -class ChromeBrowserMainPartsChromeos : public ChromeBrowserMainPartsBase { +class ChromeBrowserMainPartsChromeos : public ChromeBrowserMainPartsLinux { public: explicit ChromeBrowserMainPartsChromeos(const MainFunctionParams& parameters); - virtual ~ChromeBrowserMainPartsChromeos(); virtual void PreEarlyInitialization() OVERRIDE; @@ -34,6 +26,7 @@ class ChromeBrowserMainPartsChromeos : public ChromeBrowserMainPartsBase { private: scoped_ptr<chromeos::BrightnessObserver> brightness_observer_; scoped_ptr<chromeos::SessionManagerObserver> session_manager_observer_; + DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainPartsChromeos); }; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index be5d194..e61b44a 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -340,10 +340,8 @@ 'browser/chrome_browser_application_mac.mm', 'browser/chrome_browser_main.cc', 'browser/chrome_browser_main.h', - 'browser/chrome_browser_main_aura.cc', - 'browser/chrome_browser_main_aura.h', - 'browser/chrome_browser_main_gtk.cc', - 'browser/chrome_browser_main_gtk.h', + 'browser/chrome_browser_main_linux.cc', + 'browser/chrome_browser_main_linux.h', 'browser/chrome_browser_main_mac.mm', 'browser/chrome_browser_main_mac.h', 'browser/chrome_browser_main_posix.cc', @@ -352,6 +350,10 @@ 'browser/chrome_browser_main_win.h', 'browser/chrome_browser_main_x11.cc', 'browser/chrome_browser_main_x11.h', + 'browser/chrome_browser_parts_aura.cc', + 'browser/chrome_browser_parts_aura.h', + 'browser/chrome_browser_parts_gtk.cc', + 'browser/chrome_browser_parts_gtk.h', 'browser/chrome_content_browser_client.cc', 'browser/chrome_content_browser_client.h', 'browser/chrome_plugin_message_filter.cc', diff --git a/content/browser/browser_context.h b/content/browser/browser_context.h index 2b88d47..2477af5 100644 --- a/content/browser/browser_context.h +++ b/content/browser/browser_context.h @@ -42,7 +42,7 @@ class ResourceContext; // It lives on the UI thread. class BrowserContext { public: - virtual ~BrowserContext() {}; + virtual ~BrowserContext() {} // Returns the path of the directory where this context's data is stored. virtual FilePath GetPath() = 0; diff --git a/content/browser/browser_main.cc b/content/browser/browser_main.cc index c0ef41e..9627f36 100644 --- a/content/browser/browser_main.cc +++ b/content/browser/browser_main.cc @@ -8,54 +8,17 @@ #include "base/command_line.h" #include "base/debug/trace_event.h" #include "base/logging.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_main_loop.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/content_browser_client.h" #include "content/public/common/content_switches.h" -#include "content/public/common/result_codes.h" -#include "crypto/nss_util.h" -#include "net/base/network_change_notifier.h" -#include "net/base/ssl_config_service.h" -#include "net/socket/client_socket_factory.h" -#include "net/socket/tcp_client_socket.h" #if defined(OS_WIN) -#include <windows.h> -#include <commctrl.h> -#include <ole2.h> -#include <shellapi.h> - #include "base/win/scoped_com_initializer.h" -#include "net/base/winsock_init.h" +#include "content/common/sandbox_policy.h" #include "sandbox/src/sandbox.h" -#include "ui/base/l10n/l10n_util_win.h" -#endif - -#if defined(OS_LINUX) -#include <glib-object.h> -#endif - -#if defined(OS_CHROMEOS) -#include <dbus/dbus-glib.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 { @@ -79,292 +42,14 @@ void InitializeBrokerServices(const MainFunctionParams& parameters, } } } -#elif 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. - const char* sandbox_binary = NULL; - struct stat st; - - // In Chromium branded builds, developers can set an environment variable to - // use the development sandbox. See - // http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment - if (stat("/proc/self/exe", &st) == 0 && st.st_uid == getuid()) - sandbox_binary = getenv("CHROME_DEVEL_SANDBOX"); - -#if defined(LINUX_SANDBOX_PATH) - if (!sandbox_binary) - sandbox_binary = LINUX_SANDBOX_PATH; -#endif - - std::string sandbox_cmd; - if (sandbox_binary && !parsed_command_line.HasSwitch(switches::kNoSandbox)) - sandbox_cmd = sandbox_binary; - - // Tickle the sandbox host and zygote host so they fork now. - RenderSandboxHostLinux* shost = RenderSandboxHostLinux::GetInstance(); - shost->Init(sandbox_cmd); - ZygoteHost* zhost = ZygoteHost::GetInstance(); - zhost->Init(sandbox_cmd); -} #endif -#if defined(OS_LINUX) -static void GLibLogHandler(const gchar* log_domain, - GLogLevelFlags log_level, - const gchar* message, - gpointer userdata) { - if (!log_domain) - log_domain = "<unknown>"; - if (!message) - message = "<no message>"; - - if (strstr(message, "Loading IM context type") || - strstr(message, "wrong ELF class: ELFCLASS64")) { - // http://crbug.com/9643 - // Until we have a real 64-bit build or all of these 32-bit package issues - // are sorted out, don't fatal on ELF 32/64-bit mismatch warnings and don't - // spam the user with more than one of them. - static bool alerted = false; - if (!alerted) { - LOG(ERROR) << "Bug 9643: " << log_domain << ": " << message; - alerted = true; - } - } else if (strstr(message, "Theme file for default has no") || - strstr(message, "Theme directory") || - strstr(message, "theme pixmap")) { - LOG(ERROR) << "GTK theme error: " << message; - } else if (strstr(message, "gtk_drag_dest_leave: assertion")) { - LOG(ERROR) << "Drag destination deleted: http://crbug.com/18557"; - } else if (strstr(message, "Out of memory") && - strstr(log_domain, "<unknown>")) { - LOG(ERROR) << "DBus call timeout or out of memory: " - << "http://crosbug.com/15496"; - } else if (strstr(message, "XDG_RUNTIME_DIR variable not set")) { - LOG(ERROR) << message << " (http://bugs.chromium.org/97293)"; - } else { - LOG(DFATAL) << log_domain << ": " << message; - } -} - -static void SetUpGLibLogHandler() { - // Register GLib-handled assertions to go through our logging system. - const char* kLogDomains[] = { NULL, "Gtk", "Gdk", "GLib", "GLib-GObject" }; - for (size_t i = 0; i < arraysize(kLogDomains); i++) { - g_log_set_handler(kLogDomains[i], - static_cast<GLogLevelFlags>(G_LOG_FLAG_RECURSION | - G_LOG_FLAG_FATAL | - G_LOG_LEVEL_ERROR | - G_LOG_LEVEL_CRITICAL | - G_LOG_LEVEL_WARNING), - GLibLogHandler, - NULL); - } -} -#endif +bool g_exited_main_message_loop = false; } // namespace namespace content { -BrowserMainParts::BrowserMainParts(const MainFunctionParams& parameters) - : parameters_(parameters), - parsed_command_line_(parameters.command_line_), - result_code_(content::RESULT_CODE_NORMAL_EXIT) { -#if defined(OS_WIN) - OleInitialize(NULL); -#endif -} - -BrowserMainParts::~BrowserMainParts() { -#if defined(OS_WIN) - OleUninitialize(); -#endif -} - -void BrowserMainParts::EarlyInitialization() { - PreEarlyInitialization(); - -#if defined(OS_WIN) - net::EnsureWinsockInit(); -#endif - - // Use NSS for SSL by default. - // The default client socket factory uses NSS for SSL by default on - // Windows and Mac. -#if defined(OS_WIN) || defined(OS_MACOSX) - if (parsed_command_line().HasSwitch(switches::kUseSystemSSL)) { - net::ClientSocketFactory::UseSystemSSL(); - } else { -#elif defined(USE_NSS) - if (true) { -#else - if (false) { -#endif - // 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()); -#endif - - if (parsed_command_line().HasSwitch(switches::kDisableSSLFalseStart)) - net::SSLConfigService::DisableFalseStart(); - if (parsed_command_line().HasSwitch(switches::kEnableSSLCachedInfo)) - net::SSLConfigService::EnableCachedInfo(); - if (parsed_command_line().HasSwitch(switches::kEnableOriginBoundCerts)) - net::SSLConfigService::EnableOriginBoundCerts(); - 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)) - net::set_tcp_fastopen_enabled(true); - - PostEarlyInitialization(); -} - -void BrowserMainParts::MainMessageLoopStart() { - 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) { - // Override the configured locale with the user's preferred UI language. - l10n_util::OverrideLocaleWithUILanguageList(); - } -#endif - - main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI)); - - InitializeMainThread(); - - system_monitor_.reset(new base::SystemMonitor); - hi_res_timer_manager_.reset(new HighResolutionTimerManager); - - network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); - - PostMainMessageLoopStart(); -} - -static bool g_exited_main_message_loop = false; - -void BrowserMainParts::RunMainMessageLoopParts() { - 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(); - TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); - - g_exited_main_message_loop = true; - - PostMainMessageLoopRun(); -} - -void BrowserMainParts::InitializeMainThread() { - const char* kThreadName = "CrBrowserMain"; - base::PlatformThread::SetName(kThreadName); - main_message_loop().set_thread_name(kThreadName); - -#if defined(TRACK_ALL_TASK_OBJECTS) - tracked_objects::ThreadData::InitializeThreadContext(kThreadName); -#endif // TRACK_ALL_TASK_OBJECTS - - // Register the main thread by instantiating it, but don't call any methods. - main_thread_.reset(new BrowserThread(BrowserThread::UI, - MessageLoop::current())); -} - -void BrowserMainParts::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. - -#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 - // GTK, it is an error to call g_thread_init twice; unfortunately, - // the API to tell whether it has been called already was also only - // added in a newer version of GTK! Thankfully, this non-intuitive - // check is actually equivalent and sufficient to work around the - // error. - if (!g_thread_supported()) - g_thread_init(NULL); - // Glib type system initialization. Needed at least for gconf, - // used in net/proxy/proxy_config_service_linux.cc. Most likely - // this is superfluous as gtk_init() ought to do this. It's - // 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_); -#endif - SetUpGLibLogHandler(); -#endif - -#if defined(TOOLKIT_GTK) - // It is important for this to happen before the first run dialog, as it - // styles the dialog as well. - gfx::InitRCStyles(); -#endif - -#if defined(OS_WIN) - // Init common control sex. - INITCOMMONCONTROLSEX config; - config.dwSize = sizeof(config); - config.dwICC = ICC_WIN95_CLASSES; - if (!InitCommonControlsEx(&config)) - LOG_GETLASTERROR(FATAL); -#endif - - 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); - -#if defined(OS_MACOSX) - MessageLoopForUI::current()->Run(); -#else - MessageLoopForUI::current()->RunWithDispatcher(NULL); -#endif -} - -void BrowserMainParts::PostMainMessageLoopRun() { -} - -void BrowserMainParts::ToolkitInitialized() { -} - bool ExitedMainMessageLoop() { return g_exited_main_message_loop; } @@ -377,18 +62,17 @@ int BrowserMain(const MainFunctionParams& parameters) { NotificationServiceImpl main_notification_service; - scoped_ptr<content::BrowserMainParts> parts( - content::GetContentClient()->browser()->CreateBrowserMainParts( - parameters)); - if (!parts.get()) - parts.reset(new content::BrowserMainParts(parameters)); + scoped_ptr<content::BrowserMainLoop> main_loop( + new content::BrowserMainLoop(parameters)); + + main_loop->Init(); - parts->EarlyInitialization(); + main_loop->EarlyInitialization(); // Must happen before we try to use a message loop or display any UI. - parts->InitializeToolkit(); + main_loop->InitializeToolkit(); - parts->MainMessageLoopStart(); + main_loop->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 @@ -434,8 +118,9 @@ int BrowserMain(const MainFunctionParams& parameters) { base::StatisticsRecorder statistics; - parts->RunMainMessageLoopParts(); + main_loop->RunMainMessageLoopParts(&g_exited_main_message_loop); TRACE_EVENT_END_ETW("BrowserMain", 0, 0); - return parts->result_code(); + + return main_loop->GetResultCode(); } diff --git a/content/browser/browser_main.h b/content/browser/browser_main.h index ec1121f..86370bb 100644 --- a/content/browser/browser_main.h +++ b/content/browser/browser_main.h @@ -7,124 +7,12 @@ #pragma once #include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" #include "content/common/content_export.h" -class BrowserThread; -class CommandLine; -class HighResolutionTimerManager; -class MessageLoop; struct MainFunctionParams; -namespace base { -class SystemMonitor; -} - -namespace net { -class NetworkChangeNotifier; -} - namespace content { -// BrowserMainParts: -// This class contains different "stages" to be executed in |BrowserMain()|, -// mostly initialization. This is made into a class rather than just functions -// so each stage can create and maintain state. Each part is represented by a -// single method (e.g., "EarlyInitialization()"), which does the following: -// - calls a method (e.g., "PreEarlyInitialization()") which individual -// platforms can override to provide platform-specific code which is to be -// executed before the common code; -// - calls various methods for things common to all platforms (for that given -// stage); and -// - calls a method (e.g., "PostEarlyInitialization()") for platform-specific -// code to be called after the common code. -// As indicated above, platforms should override the default "Pre...()" and -// "Post...()" methods when necessary; they need not call the superclass's -// implementation (which is empty). -// -// Parts: -// - EarlyInitialization: things which should be done as soon as possible on -// program start (such as setting up signal handlers) and things to be done -// at some generic time before the start of the main message loop. -// - MainMessageLoopStart: things beginning with the start of the main message -// loop and ending with initialization of the main thread; platform-specific -// things which should be done immediately before the start of the main -// message loop should go in |PreMainMessageLoopStart()|. -// - (more to come) -// -// How to add stuff (to existing parts): -// - Figure out when your new code should be executed. What must happen -// before/after your code is executed? Are there performance reasons for -// running your code at a particular time? Document these things! -// - Split out any platform-specific bits. Please avoid #ifdefs it at all -// possible. You have two choices for platform-specific code: (1) Execute it -// from one of the platform-specific |Pre/Post...()| methods; do this if the -// code is unique to a platform type. Or (2) execute it from one of the -// "parts" (e.g., |EarlyInitialization()|) and provide platform-specific -// implementations of your code (in a virtual method); do this if you need to -// provide different implementations across most/all platforms. -// - Unless your new code is just one or two lines, put it into a separate -// method with a well-defined purpose. (Likewise, if you're adding to an -// existing chunk which makes it longer than one or two lines, please move -// the code out into a separate method.) -class CONTENT_EXPORT BrowserMainParts { - public: - explicit BrowserMainParts(const MainFunctionParams& parameters); - virtual ~BrowserMainParts(); - - // Parts to be called by |BrowserMain()|. - void EarlyInitialization(); - void InitializeToolkit(); - void MainMessageLoopStart(); - void RunMainMessageLoopParts(); - - int result_code() const { return result_code_; } - - protected: - // Methods to be overridden to provide platform-specific code; these - // correspond to the "parts" above. - virtual void PreEarlyInitialization(); - virtual void PostEarlyInitialization(); - virtual void PreMainMessageLoopStart(); - virtual void PostMainMessageLoopStart(); - virtual void PreMainMessageLoopRun(); - virtual void MainMessageLoopRun(); - virtual void PostMainMessageLoopRun(); - - // Allows an embedder to do any extra toolkit initialization. - virtual void ToolkitInitialized(); - - // Accessors for data members (below) ---------------------------------------- - const MainFunctionParams& parameters() const { - return parameters_; - } - const CommandLine& parsed_command_line() const { - return parsed_command_line_; - } - MessageLoop& main_message_loop() const { - return *main_message_loop_; - } - void set_result_code(int result_code) { result_code_ = result_code; } - - private: - void InitializeMainThread(); - - // Members initialized on construction --------------------------------------- - - const MainFunctionParams& parameters_; - const CommandLine& parsed_command_line_; - int result_code_; - - // Members initialized in |MainMessageLoopStart()| --------------------------- - scoped_ptr<MessageLoop> main_message_loop_; - scoped_ptr<base::SystemMonitor> system_monitor_; - scoped_ptr<HighResolutionTimerManager> hi_res_timer_manager_; - scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; - scoped_ptr<BrowserThread> main_thread_; - - DISALLOW_COPY_AND_ASSIGN(BrowserMainParts); -}; - bool ExitedMainMessageLoop(); } // namespace content diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc new file mode 100644 index 0000000..944d40c --- /dev/null +++ b/content/browser/browser_main_loop.cc @@ -0,0 +1,368 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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_loop.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/threading/thread_restrictions.h" +#include "base/tracked_objects.h" +#include "content/browser/browser_thread.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" +#include "crypto/nss_util.h" +#include "net/base/network_change_notifier.h" +#include "net/base/ssl_config_service.h" +#include "net/socket/client_socket_factory.h" +#include "net/socket/tcp_client_socket.h" + +#if defined(OS_WIN) +#include <windows.h> +#include <commctrl.h> +#include <ole2.h> +#include <shellapi.h> + +#include "ui/base/l10n/l10n_util_win.h" +#include "net/base/winsock_init.h" +#endif + +#if defined(OS_LINUX) +#include <glib-object.h> +#endif + +#if defined(OS_CHROMEOS) +#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 + +namespace { + +#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. + const char* sandbox_binary = NULL; + struct stat st; + + // In Chromium branded builds, developers can set an environment variable to + // use the development sandbox. See + // http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment + if (stat("/proc/self/exe", &st) == 0 && st.st_uid == getuid()) + sandbox_binary = getenv("CHROME_DEVEL_SANDBOX"); + +#if defined(LINUX_SANDBOX_PATH) + if (!sandbox_binary) + sandbox_binary = LINUX_SANDBOX_PATH; +#endif + + std::string sandbox_cmd; + if (sandbox_binary && !parsed_command_line.HasSwitch(switches::kNoSandbox)) + sandbox_cmd = sandbox_binary; + + // Tickle the sandbox host and zygote host so they fork now. + RenderSandboxHostLinux* shost = RenderSandboxHostLinux::GetInstance(); + shost->Init(sandbox_cmd); + ZygoteHost* zhost = ZygoteHost::GetInstance(); + zhost->Init(sandbox_cmd); +} +#endif + +#if defined(OS_LINUX) +static void GLibLogHandler(const gchar* log_domain, + GLogLevelFlags log_level, + const gchar* message, + gpointer userdata) { + if (!log_domain) + log_domain = "<unknown>"; + if (!message) + message = "<no message>"; + + if (strstr(message, "Loading IM context type") || + strstr(message, "wrong ELF class: ELFCLASS64")) { + // http://crbug.com/9643 + // Until we have a real 64-bit build or all of these 32-bit package issues + // are sorted out, don't fatal on ELF 32/64-bit mismatch warnings and don't + // spam the user with more than one of them. + static bool alerted = false; + if (!alerted) { + LOG(ERROR) << "Bug 9643: " << log_domain << ": " << message; + alerted = true; + } + } else if (strstr(message, "Theme file for default has no") || + strstr(message, "Theme directory") || + strstr(message, "theme pixmap")) { + LOG(ERROR) << "GTK theme error: " << message; + } else if (strstr(message, "gtk_drag_dest_leave: assertion")) { + LOG(ERROR) << "Drag destination deleted: http://crbug.com/18557"; + } else if (strstr(message, "Out of memory") && + strstr(log_domain, "<unknown>")) { + LOG(ERROR) << "DBus call timeout or out of memory: " + << "http://crosbug.com/15496"; + } else if (strstr(message, "XDG_RUNTIME_DIR variable not set")) { + LOG(ERROR) << message << " (http://bugs.chromium.org/97293)"; + } else { + LOG(DFATAL) << log_domain << ": " << message; + } +} + +static void SetUpGLibLogHandler() { + // Register GLib-handled assertions to go through our logging system. + const char* kLogDomains[] = { NULL, "Gtk", "Gdk", "GLib", "GLib-GObject" }; + for (size_t i = 0; i < arraysize(kLogDomains); i++) { + g_log_set_handler(kLogDomains[i], + static_cast<GLogLevelFlags>(G_LOG_FLAG_RECURSION | + G_LOG_FLAG_FATAL | + G_LOG_LEVEL_ERROR | + G_LOG_LEVEL_CRITICAL | + G_LOG_LEVEL_WARNING), + GLibLogHandler, + NULL); + } +} +#endif + +} // namespace + +namespace content { + + +// BrowserMainLoop construction / destructione ============================= + +BrowserMainLoop::BrowserMainLoop(const MainFunctionParams& parameters) + : parameters_(parameters), + parsed_command_line_(parameters.command_line_), + result_code_(content::RESULT_CODE_NORMAL_EXIT) { +#if defined(OS_WIN) + OleInitialize(NULL); +#endif +} + +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 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(); +#endif + + // 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)) { + net::ClientSocketFactory::UseSystemSSL(); + } else { + init_nspr = true; + } +#elif defined(USE_NSS) + 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_); +#endif + + if (parsed_command_line_.HasSwitch(switches::kDisableSSLFalseStart)) + net::SSLConfigService::DisableFalseStart(); + if (parsed_command_line_.HasSwitch(switches::kEnableSSLCachedInfo)) + net::SSLConfigService::EnableCachedInfo(); + if (parsed_command_line_.HasSwitch(switches::kEnableOriginBoundCerts)) + net::SSLConfigService::EnableOriginBoundCerts(); + 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)) + net::set_tcp_fastopen_enabled(true); + + for (size_t i = 0; i < parts_list_.size(); ++i) + parts_list_[i]->PostEarlyInitialization(); +} + +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) { + // Override the configured locale with the user's preferred UI language. + l10n_util::OverrideLocaleWithUILanguageList(); + } +#endif + + main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI)); + + InitializeMainThread(); + + system_monitor_.reset(new base::SystemMonitor); + hi_res_timer_manager_.reset(new HighResolutionTimerManager); + + network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); + + for (size_t i = 0; i < parts_list_.size(); ++i) + parts_list_[i]->PostMainMessageLoopStart(); +} + +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); + + // 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, ""); + + if (completed_main_message_loop) + *completed_main_message_loop = true; + + for (size_t i = 0; i < parts_list_.size(); ++i) + parts_list_[i]->PostMainMessageLoopRun(); +} + +void BrowserMainLoop::InitializeMainThread() { + const char* kThreadName = "CrBrowserMain"; + base::PlatformThread::SetName(kThreadName); + main_message_loop_->set_thread_name(kThreadName); + +#if defined(TRACK_ALL_TASK_OBJECTS) + tracked_objects::ThreadData::InitializeThreadContext(kThreadName); +#endif // TRACK_ALL_TASK_OBJECTS + + // Register the main thread by instantiating it, but don't call any methods. + main_thread_.reset(new BrowserThread(BrowserThread::UI, + MessageLoop::current())); +} + +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 + // GTK, it is an error to call g_thread_init twice; unfortunately, + // the API to tell whether it has been called already was also only + // added in a newer version of GTK! Thankfully, this non-intuitive + // check is actually equivalent and sufficient to work around the + // error. + if (!g_thread_supported()) + g_thread_init(NULL); + // Glib type system initialization. Needed at least for gconf, + // used in net/proxy/proxy_config_service_linux.cc. Most likely + // this is superfluous as gtk_init() ought to do this. It's + // 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_); +#endif + + SetUpGLibLogHandler(); +#endif + +#if defined(TOOLKIT_GTK) + // It is important for this to happen before the first run dialog, as it + // styles the dialog as well. + gfx::InitRCStyles(); +#endif + +#if defined(OS_WIN) + // Init common control sex. + INITCOMMONCONTROLSEX config; + config.dwSize = sizeof(config); + config.dwICC = ICC_WIN95_CLASSES; + if (!InitCommonControlsEx(&config)) + LOG_GETLASTERROR(FATAL); +#endif + + for (size_t i = 0; i < parts_list_.size(); ++i) + parts_list_[i]->ToolkitInitialized(); +} + +void BrowserMainLoop::MainMessageLoopRun() { + if (parameters_.ui_task) + MessageLoopForUI::current()->PostTask(FROM_HERE, parameters_.ui_task); + +#if defined(OS_MACOSX) + MessageLoopForUI::current()->Run(); +#else + MessageLoopForUI::current()->RunWithDispatcher(NULL); +#endif +} + +} // namespace content diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h new file mode 100644 index 0000000..e9f67a6 --- /dev/null +++ b/content/browser/browser_main_loop.h @@ -0,0 +1,75 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_BROWSER_MAIN_LOOP_H_ +#define CONTENT_BROWSER_BROWSER_MAIN_LOOP_H_ +#pragma once + +#include <vector> + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" + +class BrowserThread; +class CommandLine; +class HighResolutionTimerManager; +class MessageLoop; + +struct MainFunctionParams; + +namespace base { +class SystemMonitor; +} + +namespace net { +class NetworkChangeNotifier; +} + +namespace content { + +class BrowserMainParts; + +// Implements the main browser loop stages called from |BrowserMain()|. +// See comments in browser_main_parts.h for additional info. +class BrowserMainLoop { + public: + explicit BrowserMainLoop(const MainFunctionParams& parameters); + virtual ~BrowserMainLoop(); + + void Init(); + + void EarlyInitialization(); + void InitializeToolkit(); + void MainMessageLoopStart(); + void RunMainMessageLoopParts(bool* completed_main_message_loop); + void MainMessageLoopRun(); + + int GetResultCode() const { return result_code_; } + + private: + void InitializeMainThread(); + + // Members initialized on construction --------------------------------------- + const MainFunctionParams& parameters_; + const CommandLine& parsed_command_line_; + int result_code_; + + // Vector of BrowserMainParts set by CreateBrowserMainParts ------------------ + // The BrowserParts fucntions for each part are called in the order added. + // They are released (destroyed) in the reverse order. + std::vector<BrowserMainParts*> parts_list_; + + // Members initialized in |MainMessageLoopStart()| --------------------------- + scoped_ptr<MessageLoop> main_message_loop_; + scoped_ptr<base::SystemMonitor> system_monitor_; + scoped_ptr<HighResolutionTimerManager> hi_res_timer_manager_; + scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; + scoped_ptr<BrowserThread> main_thread_; + + DISALLOW_COPY_AND_ASSIGN(BrowserMainLoop); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_BROWSER_MAIN_LOOP_H_ diff --git a/content/browser/mock_content_browser_client.cc b/content/browser/mock_content_browser_client.cc index 9f6316d..bc88faf 100644 --- a/content/browser/mock_content_browser_client.cc +++ b/content/browser/mock_content_browser_client.cc @@ -23,9 +23,9 @@ MockContentBrowserClient::MockContentBrowserClient() { MockContentBrowserClient::~MockContentBrowserClient() { } -BrowserMainParts* MockContentBrowserClient::CreateBrowserMainParts( - const MainFunctionParams& parameters) { - return NULL; +void MockContentBrowserClient::CreateBrowserMainParts( + const MainFunctionParams& parameters, + std::vector<BrowserMainParts*>* parts_list) { } RenderWidgetHostView* MockContentBrowserClient::CreateViewForWidget( diff --git a/content/browser/mock_content_browser_client.h b/content/browser/mock_content_browser_client.h index 8ff575a..0742691 100644 --- a/content/browser/mock_content_browser_client.h +++ b/content/browser/mock_content_browser_client.h @@ -21,8 +21,9 @@ class MockContentBrowserClient : public ContentBrowserClient { MockContentBrowserClient(); virtual ~MockContentBrowserClient(); - virtual BrowserMainParts* CreateBrowserMainParts( - const MainFunctionParams& parameters) OVERRIDE; + virtual void CreateBrowserMainParts( + const MainFunctionParams& parameters, + std::vector<BrowserMainParts*>* parts_list) OVERRIDE; virtual RenderWidgetHostView* CreateViewForWidget( RenderWidgetHost* widget) OVERRIDE; virtual TabContentsView* CreateTabContentsView( diff --git a/content/content_browser.gypi b/content/content_browser.gypi index eb2dd04..9d3f8e4 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -53,6 +53,8 @@ 'browser/browser_context.h', 'browser/browser_main.cc', 'browser/browser_main.h', + 'browser/browser_main_loop.cc', + 'browser/browser_main_loop.h', 'browser/browser_message_filter.cc', 'browser/browser_message_filter.h', 'browser/browser_process_sub_thread.cc', @@ -573,6 +575,7 @@ 'browser/zygote_host_linux.cc', 'browser/zygote_host_linux.h', 'browser/zygote_main_linux.cc', + 'public/browser/browser_main_parts.h', 'public/browser/content_browser_client.h', 'public/browser/download_manager_delegate.h', 'public/browser/native_web_keyboard_event.h', diff --git a/content/public/browser/browser_main_parts.h b/content/public/browser/browser_main_parts.h new file mode 100644 index 0000000..0bbaa83 --- /dev/null +++ b/content/public/browser/browser_main_parts.h @@ -0,0 +1,87 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_PUBLIC_BROWSER_BROWSER_MAIN_PARTS_H_ +#define CONTENT_PUBLIC_BROWSER_BROWSER_MAIN_PARTS_H_ +#pragma once + +#include "base/basictypes.h" +#include "content/common/content_export.h" + +namespace content { + +// This class contains different "stages" to be executed by |BrowserMain()|, +// Each stage is represented by a single BrowserMainParts method, called from +// the corresponding method in |BrowserMainLoop| (e.g., EarlyInitialization()) +// which does the following: +// - calls a method (e.g., "PreEarlyInitialization()") for each member of +// |parts_|. Parts will implement platform or tookit specific code for that +// stage. +// - calls various methods for things common to all platforms (for that stage). +// - calls a method (e.g., "PostEarlyInitialization()") for platform-specific +// code to be called after the common code. +// +// Stages: +// - EarlyInitialization: things which should be done as soon as possible on +// program start (such as setting up signal handlers) and things to be done +// at some generic time before the start of the main message loop. +// - MainMessageLoopStart: things beginning with the start of the main message +// loop and ending with initialization of the main thread; platform-specific +// things which should be done immediately before the start of the main +// message loop should go in |PreMainMessageLoopStart()|. +// - RunMainMessageLoopParts: things to be done before and after invoking the +// main message loop run method (e.g. MessageLoopForUI::current()->Run()). +// +// How to add stuff (to existing parts): +// - Figure out when your new code should be executed. What must happen +// before/after your code is executed? Are there performance reasons for +// running your code at a particular time? Document these things! +// - Split out any platform-specific bits. Please avoid #ifdefs it at all +// possible. You have two choices for platform-specific code: (1) Execute it +// from one of the platform-specific |Pre/Post...()| methods; do this if the +// code is unique to a platform type. Or (2) execute it from one of the +// "parts" (e.g., |EarlyInitialization()|) and provide platform-specific +// implementations of your code (in a virtual method); do this if you need to +// provide different implementations across most/all platforms. +// - Unless your new code is just one or two lines, put it into a separate +// method with a well-defined purpose. (Likewise, if you're adding to an +// existing chunk which makes it longer than one or two lines, please move +// the code out into a separate method.) +// +// There can be any number of "Parts". These should be constructed in +// ContentBrowserClient::CreateBrowserMainParts. Each stage will be called +// for each part in the order it was added. Destruction is in the inverse order. +class CONTENT_EXPORT BrowserMainParts { + public: + BrowserMainParts() {} + virtual ~BrowserMainParts() {} + + virtual void PreEarlyInitialization() = 0; + + virtual void PostEarlyInitialization() = 0; + + virtual void PreMainMessageLoopStart() = 0; + + // Allows an embedder to do any extra toolkit initialization. + virtual void ToolkitInitialized() = 0; + + virtual void PostMainMessageLoopStart() = 0; + + virtual void PreMainMessageLoopRun() = 0; + + // Returns true if the message loop was run, false otherwise. + // May set |result_code|, which will be returned by |BrowserMain()|. + // If no BrowserMainParts implementations return true, the default + // implementation will be run. + virtual bool MainMessageLoopRun(int* result_code) = 0; + + virtual void PostMainMessageLoopRun() = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(BrowserMainParts); +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_BROWSER_MAIN_PARTS_H_ diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 95f956b..e56f587 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h @@ -67,7 +67,6 @@ class Clipboard; namespace content { class BrowserContext; -class BrowserMainParts; class ResourceContext; class WebUIFactory; @@ -83,11 +82,12 @@ class ContentBrowserClient { public: virtual ~ContentBrowserClient() {} - // Allows the embedder to return a customed BrowserMainParts implementation - // for the browser staratup code. Can return NULL, in which case the default - // is used. - virtual BrowserMainParts* CreateBrowserMainParts( - const MainFunctionParams& parameters) = 0; + // Allows the embedder to set any number of custom BrowserMainParts + // implementations for the browser startup code. See comments in + // browser_main_parts.h. + virtual void CreateBrowserMainParts( + const MainFunctionParams& parameters, + std::vector<BrowserMainParts*>* parts_list) = 0; // Platform-specific creator. Use this to construct new RenderWidgetHostViews // rather than using RenderWidgetHostViewWin & friends. diff --git a/content/shell/shell_browser_main.cc b/content/shell/shell_browser_main.cc index ae3b0c1..7058cff 100644 --- a/content/shell/shell_browser_main.cc +++ b/content/shell/shell_browser_main.cc @@ -21,7 +21,7 @@ namespace content { ShellBrowserMainParts::ShellBrowserMainParts( const MainFunctionParams& parameters) - : BrowserMainParts(parameters) { + : BrowserMainParts() { ShellContentBrowserClient* shell_browser_client = static_cast<ShellContentBrowserClient*>( content::GetContentClient()->browser()); @@ -74,6 +74,11 @@ void ShellBrowserMainParts::PreMainMessageLoopRun() { NULL, MSG_ROUTING_NONE, NULL); + +} + +bool ShellBrowserMainParts::MainMessageLoopRun(int* result_code) { + return false; } ResourceDispatcherHost* ShellBrowserMainParts::GetResourceDispatcherHost() { diff --git a/content/shell/shell_browser_main.h b/content/shell/shell_browser_main.h index 5d46e1f..7e43d88 100644 --- a/content/shell/shell_browser_main.h +++ b/content/shell/shell_browser_main.h @@ -6,10 +6,12 @@ #define CONTENT_SHELL_SHELL_BROWSER_MAIN_H_ #pragma once +#include "base/basictypes.h" #include "base/memory/scoped_ptr.h" -#include "content/browser/browser_main.h" +#include "content/public/browser/browser_main_parts.h" class ResourceDispatcherHost; +struct MainFunctionParams; namespace base { class Thread; @@ -28,7 +30,14 @@ class ShellBrowserMainParts : public BrowserMainParts { explicit ShellBrowserMainParts(const MainFunctionParams& parameters); virtual ~ShellBrowserMainParts(); - virtual void PreMainMessageLoopRun(); + virtual void PreEarlyInitialization() OVERRIDE {} + virtual void PostEarlyInitialization() OVERRIDE {} + virtual void PreMainMessageLoopStart() OVERRIDE {} + virtual void ToolkitInitialized() OVERRIDE {} + virtual void PostMainMessageLoopStart() OVERRIDE {} + virtual void PreMainMessageLoopRun() OVERRIDE; + virtual bool MainMessageLoopRun(int* result_code) OVERRIDE; + virtual void PostMainMessageLoopRun() {} ResourceDispatcherHost* GetResourceDispatcherHost(); ui::Clipboard* GetClipboard(); diff --git a/content/shell/shell_content_browser_client.cc b/content/shell/shell_content_browser_client.cc index a97abf5..0176c2b 100644 --- a/content/shell/shell_content_browser_client.cc +++ b/content/shell/shell_content_browser_client.cc @@ -28,9 +28,10 @@ ShellContentBrowserClient::ShellContentBrowserClient() ShellContentBrowserClient::~ShellContentBrowserClient() { } -BrowserMainParts* ShellContentBrowserClient::CreateBrowserMainParts( - const MainFunctionParams& parameters) { - return new ShellBrowserMainParts(parameters); +void ShellContentBrowserClient::CreateBrowserMainParts( + const MainFunctionParams& parameters, + std::vector<BrowserMainParts*>* parts_list) { + parts_list->push_back(new ShellBrowserMainParts(parameters)); } RenderWidgetHostView* ShellContentBrowserClient::CreateViewForWidget( diff --git a/content/shell/shell_content_browser_client.h b/content/shell/shell_content_browser_client.h index ffbf826..c444952 100644 --- a/content/shell/shell_content_browser_client.h +++ b/content/shell/shell_content_browser_client.h @@ -24,7 +24,7 @@ class ShellContentBrowserClient : public ContentBrowserClient #if defined(OS_WIN) , public TabContentsViewWinDelegate #endif - { +{ public: ShellContentBrowserClient(); virtual ~ShellContentBrowserClient(); @@ -33,8 +33,9 @@ class ShellContentBrowserClient : public ContentBrowserClient shell_browser_main_parts_ = parts; } - virtual BrowserMainParts* CreateBrowserMainParts( - const MainFunctionParams& parameters) OVERRIDE; + virtual void CreateBrowserMainParts( + const MainFunctionParams& parameters, + std::vector<BrowserMainParts*>* parts_list) OVERRIDE; virtual RenderWidgetHostView* CreateViewForWidget( RenderWidgetHost* widget) OVERRIDE; virtual TabContentsView* CreateTabContentsView( |