| Index: chrome/browser/chrome_browser_main.cc
|
| diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
|
| index 614da15828bfdddcb6807e3a50e066100fd957a1..2e71807cbb0f6c7570c7ea2fc80245af3014b7fe 100644
|
| --- a/chrome/browser/chrome_browser_main.cc
|
| +++ b/chrome/browser/chrome_browser_main.cc
|
| @@ -76,7 +76,6 @@
|
| #include "chrome/browser/shell_integration.h"
|
| #include "chrome/browser/translate/translate_manager.h"
|
| #include "chrome/browser/ui/browser.h"
|
| -#include "chrome/browser/ui/browser_init.h"
|
| #include "chrome/browser/ui/webui/chrome_url_data_manager_backend.h"
|
| #include "chrome/browser/web_resource/gpu_blacklist_updater.h"
|
| #include "chrome/common/child_process_logging.h"
|
| @@ -311,23 +310,6 @@ void InitializeURLRequestThrottlerManager(net::NetLog* net_log) {
|
| net::URLRequestThrottlerManager::GetInstance()->set_net_log(net_log);
|
| }
|
|
|
| -// Creates key child threads. We need to do this explicitly since
|
| -// BrowserThread::PostTask silently deletes a posted task if the target message
|
| -// loop isn't created.
|
| -void CreateChildThreads(BrowserProcessImpl* process) {
|
| - process->db_thread();
|
| - process->file_thread();
|
| - process->process_launcher_thread();
|
| - process->cache_thread();
|
| - process->io_thread();
|
| -#if defined(OS_CHROMEOS)
|
| - process->web_socket_proxy_thread();
|
| -#endif
|
| - // Create watchdog thread after creating all other threads because it will
|
| - // watch the other threads and they must be running.
|
| - process->watchdog_thread();
|
| -}
|
| -
|
| // Returns the new local state object, guaranteed non-NULL.
|
| PrefService* InitializeLocalState(const CommandLine& parsed_command_line,
|
| bool is_first_run) {
|
| @@ -687,7 +669,12 @@ ChromeBrowserMainParts::ChromeBrowserMainParts(
|
| translate_manager_(NULL),
|
| profile_(NULL),
|
| run_message_loop_(true),
|
| - notify_result_(ProcessSingleton::PROCESS_NONE) {
|
| + notify_result_(ProcessSingleton::PROCESS_NONE),
|
| + is_first_run_(false),
|
| + first_run_ui_bypass_(false),
|
| + metrics_(NULL),
|
| + local_state_(NULL),
|
| + restart_last_session_(false) {
|
| // If we're running tests (ui_task is non-null).
|
| if (parameters.ui_task)
|
| browser_defaults::enable_help_app = false;
|
| @@ -1207,31 +1194,65 @@ void ChromeBrowserMainParts::PostMainMessageLoopStart() {
|
| chrome_extra_parts_[i]->PostMainMessageLoopStart();
|
| }
|
|
|
| -void ChromeBrowserMainParts::PreMainMessageLoopRun() {
|
| - result_code_ = PreMainMessageLoopRunImpl();
|
| +void ChromeBrowserMainParts::PreCreateThreads() {
|
| + result_code_ = PreCreateThreadsImpl();
|
|
|
| for (size_t i = 0; i < chrome_extra_parts_.size(); ++i)
|
| chrome_extra_parts_[i]->PreMainMessageLoopRun();
|
| }
|
|
|
| -int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| +void ChromeBrowserMainParts::PreStartThread(
|
| + content::BrowserThread::ID thread_id) {
|
| + browser_process_->PreStartThread(thread_id);
|
| +}
|
| +
|
| +void ChromeBrowserMainParts::PostStartThread(
|
| + content::BrowserThread::ID thread_id) {
|
| + browser_process_->PostStartThread(thread_id);
|
| + switch (thread_id) {
|
| + case BrowserThread::FILE:
|
| + // Now the command line has been mutated based on about:flags,
|
| + // and the file thread has been started, we can set up metrics
|
| + // and initialize field trials.
|
| + metrics_ = SetupMetricsAndFieldTrials(local_state_);
|
| +
|
| +#if defined(USE_LINUX_BREAKPAD)
|
| + // Needs to be called after we have chrome::DIR_USER_DATA and
|
| + // g_browser_process. This happens in PreCreateThreads.
|
| + g_browser_process->file_thread()->message_loop()->PostTask(
|
| + FROM_HERE, new GetLinuxDistroTask());
|
| +
|
| + if (IsCrashReportingEnabled(local_state_))
|
| + InitCrashReporter();
|
| +#endif
|
| + break;
|
| +
|
| + default:
|
| + break;
|
| + }
|
| +}
|
| +
|
| +void ChromeBrowserMainParts::PreMainMessageLoopRun() {
|
| + result_code_ = PreMainMessageLoopRunImpl();
|
| +}
|
| +
|
| +int ChromeBrowserMainParts::PreCreateThreadsImpl() {
|
| run_message_loop_ = false;
|
| - FilePath user_data_dir;
|
| #if defined(OS_WIN)
|
| - PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
|
| + PathService::Get(chrome::DIR_USER_DATA, &user_data_dir_);
|
| #else
|
| // Getting the user data dir can fail if the directory isn't
|
| // creatable, for example; on Windows in code below we bring up a
|
| // dialog prompting the user to pick a different directory.
|
| // However, ProcessSingleton needs a real user_data_dir on Mac/Linux,
|
| // so it's better to fail here than fail mysteriously elsewhere.
|
| - CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
|
| + CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir_))
|
| << "Must be able to get user data directory!";
|
| #endif
|
|
|
| - process_singleton_.reset(new ProcessSingleton(user_data_dir));
|
| + process_singleton_.reset(new ProcessSingleton(user_data_dir_));
|
|
|
| - bool is_first_run = FirstRun::IsChromeFirstRun() ||
|
| + is_first_run_ = FirstRun::IsChromeFirstRun() ||
|
| parsed_command_line().HasSwitch(switches::kFirstRun);
|
|
|
| if (parsed_command_line().HasSwitch(switches::kImport) ||
|
| @@ -1240,7 +1261,7 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| // instantiated (as it makes a net::URLRequest and we don't have an IO
|
| // thread, see bug #1292702).
|
| browser_process_.reset(new FirstRunBrowserProcess(parsed_command_line()));
|
| - is_first_run = false;
|
| + is_first_run_ = false;
|
| } else {
|
| browser_process_.reset(new BrowserProcessImpl(parsed_command_line()));
|
| }
|
| @@ -1258,18 +1279,8 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| // tabs.
|
| g_browser_process->tab_closeable_state_watcher();
|
|
|
| - PrefService* local_state = InitializeLocalState(parsed_command_line(),
|
| - is_first_run);
|
| -
|
| -#if defined(USE_LINUX_BREAKPAD)
|
| - // Needs to be called after we have chrome::DIR_USER_DATA and
|
| - // g_browser_process.
|
| - g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
|
| - new GetLinuxDistroTask());
|
| -
|
| - if (IsCrashReportingEnabled(local_state))
|
| - InitCrashReporter();
|
| -#endif
|
| + local_state_ = InitializeLocalState(parsed_command_line(),
|
| + is_first_run_);
|
|
|
| // If we're running tests (ui_task is non-null), then the ResourceBundle
|
| // has already been initialized.
|
| @@ -1283,7 +1294,7 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| g_browser_process->SetApplicationLocale(l10n_util::GetLocaleOverride());
|
| #else
|
| const std::string locale =
|
| - local_state->GetString(prefs::kApplicationLocale);
|
| + local_state_->GetString(prefs::kApplicationLocale);
|
| // On a POSIX OS other than ChromeOS, the parameter that is passed to the
|
| // method InitSharedInstance is ignored.
|
| const std::string loaded_locale =
|
| @@ -1343,19 +1354,19 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| // browser's profile_manager object is created, but after ResourceBundle
|
| // is initialized.
|
| master_prefs_.reset(new FirstRun::MasterPrefs);
|
| - bool first_run_ui_bypass = false; // True to skip first run UI.
|
| - if (is_first_run) {
|
| - first_run_ui_bypass =
|
| - !FirstRun::ProcessMasterPreferences(user_data_dir, master_prefs_.get());
|
| + first_run_ui_bypass_ = false; // True to skip first run UI.
|
| + if (is_first_run_) {
|
| + first_run_ui_bypass_ = !FirstRun::ProcessMasterPreferences(
|
| + user_data_dir_, master_prefs_.get());
|
| AddFirstRunNewTabs(browser_init_.get(), master_prefs_->new_tabs);
|
|
|
| // If we are running in App mode, we do not want to show the importer
|
| // (first run) UI.
|
| - if (!first_run_ui_bypass &&
|
| + if (!first_run_ui_bypass_ &&
|
| (parsed_command_line().HasSwitch(switches::kApp) ||
|
| parsed_command_line().HasSwitch(switches::kAppId) ||
|
| parsed_command_line().HasSwitch(switches::kNoFirstRun)))
|
| - first_run_ui_bypass = true;
|
| + first_run_ui_bypass_ = true;
|
| }
|
|
|
| // TODO(viettrungluu): why don't we run this earlier?
|
| @@ -1364,17 +1375,17 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
|
|
| // Enable print preview once for supported platforms.
|
| #if defined(GOOGLE_CHROME_BUILD)
|
| - local_state->RegisterBooleanPref(prefs::kPrintingPrintPreviewEnabledOnce,
|
| + local_state_->RegisterBooleanPref(prefs::kPrintingPrintPreviewEnabledOnce,
|
| false,
|
| PrefService::UNSYNCABLE_PREF);
|
| - if (!local_state->GetBoolean(prefs::kPrintingPrintPreviewEnabledOnce)) {
|
| - local_state->SetBoolean(prefs::kPrintingPrintPreviewEnabledOnce, true);
|
| - about_flags::SetExperimentEnabled(local_state, "print-preview", true);
|
| + if (!local_state_->GetBoolean(prefs::kPrintingPrintPreviewEnabledOnce)) {
|
| + local_state_->SetBoolean(prefs::kPrintingPrintPreviewEnabledOnce, true);
|
| + about_flags::SetExperimentEnabled(local_state_, "print-preview", true);
|
| }
|
| #endif
|
|
|
| // Convert active labs into switches. Modifies the current command line.
|
| - about_flags::ConvertFlagsToSwitches(local_state,
|
| + about_flags::ConvertFlagsToSwitches(local_state_,
|
| CommandLine::ForCurrentProcess());
|
|
|
| // Reset the command line in the crash report details, since we may have
|
| @@ -1391,10 +1402,6 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| histogram_synchronizer_ = new HistogramSynchronizer();
|
| tracking_synchronizer_ = new chrome_browser_metrics::TrackingSynchronizer();
|
|
|
| - // Now the command line has been mutated based on about:flags, we can
|
| - // set up metrics and initialize field trials.
|
| - MetricsService* metrics = SetupMetricsAndFieldTrials(local_state);
|
| -
|
| #if defined(USE_WEBKIT_COMPOSITOR)
|
| // We need to ensure WebKit has been initialized before we start the WebKit
|
| // compositor. This is done by the ResourceDispatcherHost on creation.
|
| @@ -1405,9 +1412,9 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| // for the uninstall metrics if this is our first run. This only actually
|
| // gets used if the user has metrics reporting enabled at uninstall time.
|
| int64 install_date =
|
| - local_state->GetInt64(prefs::kUninstallMetricsInstallDate);
|
| + local_state_->GetInt64(prefs::kUninstallMetricsInstallDate);
|
| if (install_date == 0) {
|
| - local_state->SetInt64(prefs::kUninstallMetricsInstallDate,
|
| + local_state_->SetInt64(prefs::kUninstallMetricsInstallDate,
|
| base::Time::Now().ToTimeT());
|
| }
|
|
|
| @@ -1421,7 +1428,13 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| SecKeychainAddCallback(&KeychainCallback, 0, NULL);
|
| #endif
|
|
|
| - CreateChildThreads(browser_process_.get());
|
| + return content::RESULT_CODE_NORMAL_EXIT;
|
| +}
|
| +
|
| +int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| + // Create watchdog thread after creating all other threads because it will
|
| + // watch the other threads and they must be running.
|
| + browser_process_->watchdog_thread();
|
|
|
| #if defined(OS_CHROMEOS)
|
| // Now that the file thread exists we can record our stats.
|
| @@ -1571,13 +1584,13 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| }
|
| #endif
|
|
|
| - if (is_first_run) {
|
| + if (is_first_run_) {
|
| // Warn the ProfileManager that an import process will run, possibly
|
| // locking the WebDataService directory of the next Profile created.
|
| g_browser_process->profile_manager()->SetWillImport();
|
| }
|
|
|
| - profile_ = CreateProfile(parameters(), user_data_dir, parsed_command_line());
|
| + profile_ = CreateProfile(parameters(), user_data_dir_, parsed_command_line());
|
| if (!profile_)
|
| return content::RESULT_CODE_NORMAL_EXIT;
|
|
|
| @@ -1661,8 +1674,8 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| // Note that this be done _after_ the PrefService is initialized and all
|
| // preferences are registered, since some of the code that the importer
|
| // touches reads preferences.
|
| - if (is_first_run) {
|
| - if (!first_run_ui_bypass) {
|
| + if (is_first_run_) {
|
| + if (!first_run_ui_bypass_) {
|
| FirstRun::AutoImport(profile_,
|
| master_prefs_->homepage_defined,
|
| master_prefs_->do_import_items,
|
| @@ -1678,13 +1691,13 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| // If stats reporting was turned on by the first run dialog then toggle
|
| // the pref.
|
| if (GoogleUpdateSettings::GetCollectStatsConsent())
|
| - local_state->SetBoolean(prefs::kMetricsReportingEnabled, true);
|
| + local_state_->SetBoolean(prefs::kMetricsReportingEnabled, true);
|
| #endif // OS_POSIX
|
| - } // if (!first_run_ui_bypass)
|
| + } // if (!first_run_ui_bypass_)
|
|
|
| Browser::SetNewHomePagePrefs(profile_->GetPrefs());
|
| g_browser_process->profile_manager()->OnImportFinished(profile_);
|
| - } // if (is_first_run)
|
| + } // if (is_first_run_)
|
|
|
| #if defined(OS_WIN)
|
| // Sets things up so that if we crash from this point on, a dialog will
|
| @@ -1729,7 +1742,7 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| homepage == GoogleURLTracker::kDefaultGoogleHomepage;
|
| }
|
|
|
| - RLZTracker::InitRlzDelayed(is_first_run, master_prefs_->ping_delay,
|
| + RLZTracker::InitRlzDelayed(is_first_run_, master_prefs_->ping_delay,
|
| google_search_default, google_search_homepage);
|
|
|
| // Prime the RLZ cache for the home page access point so that its avaiable
|
| @@ -1799,8 +1812,8 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| #endif
|
|
|
| HandleTestParameters(parsed_command_line());
|
| - RecordBreakpadStatusUMA(metrics);
|
| - about_flags::RecordUMAStatistics(local_state);
|
| + RecordBreakpadStatusUMA(metrics_);
|
| + about_flags::RecordUMAStatistics(local_state_);
|
| LanguageUsageMetrics::RecordAcceptLanguages(
|
| profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
|
| LanguageUsageMetrics::RecordApplicationLanguage(
|
| @@ -1811,7 +1824,7 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| #endif
|
|
|
| #if defined(OS_CHROMEOS)
|
| - metrics->StartExternalMetrics();
|
| + metrics_->StartExternalMetrics();
|
|
|
| // Initialize the audio handler on ChromeOS.
|
| chromeos::AudioHandler::Initialize();
|
| @@ -1844,7 +1857,7 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| #if defined(OS_WIN)
|
| // We check this here because if the profile is OTR (chromeos possibility)
|
| // it won't still be accessible after browser is destroyed.
|
| - record_search_engine_ = is_first_run && !profile_->IsOffTheRecord();
|
| + record_search_engine_ = is_first_run_ && !profile_->IsOffTheRecord();
|
| #endif
|
|
|
| // ChildProcess:: is a misnomer unless you consider context. Use
|
| @@ -1900,8 +1913,9 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
|
|
| // We are in regular browser boot sequence. Open initial tabs and enter the
|
| // main message loop.
|
| + int result_code;
|
| if (browser_init_->Start(parsed_command_line(), FilePath(), profile_,
|
| - &result_code_)) {
|
| + &result_code)) {
|
| #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
|
| // Initialize autoupdate timer. Timer callback costs basically nothing
|
| // when browser is not in persistent mode, so it's OK to let it ride on
|
| @@ -2068,10 +2082,23 @@ void ChromeBrowserMainParts::PostMainMessageLoopRun() {
|
| chromeos::AudioHandler::Shutdown();
|
| #endif
|
|
|
| + restart_last_session_ = browser_shutdown::ShutdownPreThreadsStop();
|
| + browser_process_->StartTearDown();
|
| +}
|
| +
|
| +void ChromeBrowserMainParts::PreStopThread(BrowserThread::ID identifier) {
|
| + browser_process_->PreStopThread(identifier);
|
| +}
|
| +
|
| +void ChromeBrowserMainParts::PostStopThread(BrowserThread::ID identifier) {
|
| + browser_process_->PostStopThread(identifier);
|
| +}
|
| +
|
| +void ChromeBrowserMainParts::PostDestroyThreads() {
|
| // browser_shutdown takes care of deleting browser_process, so we need to
|
| // release it.
|
| ignore_result(browser_process_.release());
|
| - browser_shutdown::Shutdown();
|
| + browser_shutdown::ShutdownPostThreadsStop(restart_last_session_);
|
| master_prefs_.reset();
|
| process_singleton_.reset();
|
|
|
|
|